Skip to content

Commit 9353407

Browse files
bors[bot]Astrale
andauthored
Merge #153
153: Implement more Variant accessors r=Bromeon a=astrale-sharp Closes #140 The test for stringify are looking pretty good in my opinion This is not ready to merge : [ ] Discuss mapped method returned type (sys::GDExtensionBool, sys::GDExtensionInt, etc) [ ] Test all mapped method [ ] remove itest(focus) [ ] squash the commits Currently I wrote this kind of code, I have ```rust pub fn booleanize(&self) -> sys::GDExtensionBool { interface_fn!(variant_booleanize)(self.var_sys()) } ``` Which is bad cause we probably don't want sys::GDExtensionBool to be seen by users, instead I guess it should return a regular rust boolean but I'm unsure how to do the conversion yet, it's probably somewhere in the code Co-authored-by: Astrale <[email protected]>
2 parents 2b72fd6 + b562fac commit 9353407

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

godot-core/src/builtin/variant/mod.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,15 +156,29 @@ impl Variant {
156156
}
157157
}
158158

159+
/// return a `GodotString` representing the variant
159160
#[allow(unused_mut)]
160-
pub(crate) fn stringify(&self) -> GodotString {
161+
pub fn stringify(&self) -> GodotString {
161162
let mut result = GodotString::new();
162163
unsafe {
163164
interface_fn!(variant_stringify)(self.var_sys(), result.string_sys());
164165
}
165166
result
166167
}
167168

169+
/// return the hash value of the variant.
170+
///
171+
/// _Godot equivalent : `@GlobalScope.hash()`_
172+
pub fn hash(&self) -> i64 {
173+
unsafe { interface_fn!(variant_hash)(self.var_sys()) }
174+
}
175+
176+
/// return a false only if the variant is `Variant::NIL`
177+
/// or an empty `TypedArray` or `Dictionary`.
178+
pub fn booleanize(&self) -> bool {
179+
unsafe { interface_fn!(variant_booleanize)(self.var_sys()) != 0 }
180+
}
181+
168182
fn from_opaque(opaque: OpaqueVariant) -> Self {
169183
Self { opaque }
170184
}

itest/rust/src/variant_test.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
use crate::{expect_panic, itest};
88
use godot::builtin::{
9-
FromVariant, GodotString, NodePath, StringName, ToVariant, Variant, Vector2, Vector3,
9+
dict, varray, FromVariant, GodotString, NodePath, StringName, ToVariant, Variant, Vector2,
10+
Vector3,
1011
};
1112
use godot::engine::Node2D;
1213
use godot::obj::InstanceId;
@@ -337,6 +338,66 @@ fn variant_type_correct() {
337338
);
338339
}
339340

341+
#[itest]
342+
fn variant_stringify_correct() {
343+
assert_eq!("value".to_variant().stringify(), gstr("value"));
344+
assert_eq!(Variant::nil().stringify(), gstr("<null>"));
345+
assert_eq!(true.to_variant().stringify(), gstr("true"));
346+
assert_eq!(30.to_variant().stringify(), gstr("30"));
347+
assert_eq!(
348+
godot::builtin::varray![1, "hello", false]
349+
.to_variant()
350+
.stringify(),
351+
gstr("[1, \"hello\", false]")
352+
);
353+
assert_eq!(
354+
dict! { "KEY": 50 }.to_variant().stringify(),
355+
gstr("{ \"KEY\": 50 }")
356+
);
357+
}
358+
359+
#[itest]
360+
fn variant_booleanize_correct() {
361+
assert!(gstr("string").to_variant().booleanize());
362+
assert!(10.to_variant().booleanize());
363+
assert!(varray![""].to_variant().booleanize());
364+
assert!(dict! { "Key": 50 }.to_variant().booleanize());
365+
366+
assert!(!Dictionary::new().to_variant().booleanize());
367+
assert!(!varray![].to_variant().booleanize());
368+
assert!(!0.to_variant().booleanize());
369+
assert!(!Variant::nil().booleanize());
370+
assert!(!gstr("").to_variant().booleanize());
371+
}
372+
373+
#[itest]
374+
fn variant_hash_correct() {
375+
let hash_is_not_0 = [
376+
dict! {}.to_variant(),
377+
gstr("").to_variant(),
378+
varray![].to_variant(),
379+
];
380+
let self_equal = [
381+
gstr("string").to_variant(),
382+
varray![false, true, 4, "7"].to_variant(),
383+
0.to_variant(),
384+
dict! { 0 : dict!{ 0: 1 }}.to_variant(),
385+
];
386+
387+
for variant in hash_is_not_0 {
388+
assert_ne!(variant.hash(), 0)
389+
}
390+
for variant in self_equal {
391+
assert_eq!(variant.hash(), variant.hash())
392+
}
393+
394+
assert_eq!(Variant::nil().hash(), 0);
395+
396+
// it's not guaranteed that different object will have different hash but it is
397+
// extremely unlikely for a collision to happen.
398+
assert_ne!(dict! { 0: dict!{ 0: 0 } }, dict! { 0: dict!{ 0: 1 } });
399+
}
400+
340401
// ----------------------------------------------------------------------------------------------------------------------------------------------
341402

342403
fn roundtrip<T>(value: T)

0 commit comments

Comments
 (0)