Skip to content

Commit b562fac

Browse files
author
Astrale
committed
add Variant::{hash ; booleanize ; stringify}
+ test
1 parent fb15aef commit b562fac

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;
@@ -334,6 +335,66 @@ fn variant_type_correct() {
334335
);
335336
}
336337

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

339400
fn roundtrip<T>(value: T)

0 commit comments

Comments
 (0)