From 3e63a35807a59f8a3cf062a4df93a59fa0d7ac61 Mon Sep 17 00:00:00 2001 From: Jan Haller Date: Sun, 17 Jul 2022 00:34:52 +0200 Subject: [PATCH 1/2] Tests for StringName (conversions, Eq, Ord) --- gdnative-core/src/core_types/string.rs | 45 ++++++++++++++++++++++++++ test/src/lib.rs | 2 ++ 2 files changed, 47 insertions(+) diff --git a/gdnative-core/src/core_types/string.rs b/gdnative-core/src/core_types/string.rs index 8ffbc27ab..8254c3cbe 100644 --- a/gdnative-core/src/core_types/string.rs +++ b/gdnative-core/src/core_types/string.rs @@ -2,6 +2,7 @@ use crate::core_types::Variant; use crate::object::NewRef; use crate::private::get_api; use crate::sys; +use std::cmp::Ordering; use std::ffi::CStr; use std::fmt; @@ -728,3 +729,47 @@ godot_test!(test_string { assert_eq!(fmt2, GodotString::from("foo bar")); assert_eq!(fmt_string2, GodotString::from("{0} {1}")); }); + +godot_test!(test_string_name_eq { + use crate::core_types::{GodotString, StringName}; + + let a: StringName = StringName::from_str("some string"); + let b: StringName = StringName::from_godot_string(&GodotString::from("some string")); + let c: StringName = StringName::from_str(String::from("some other string")); + let d: StringName = StringName::from_str("yet another one"); + + // test Eq + assert_eq!(a, b); + assert_ne!(a, c); + assert_ne!(a, d); + assert_ne!(b, c); + assert_ne!(b, d); + assert_ne!(c, d); + + let back = b.to_godot_string(); + assert_eq!(back, GodotString::from("some string")); +}); + +godot_test!(test_string_name_ord { + use crate::core_types::{GodotString, StringName}; + + let a: StringName = StringName::from_str("some string"); + let b: StringName = StringName::from_godot_string(&GodotString::from("some string")); + let c: StringName = StringName::from_str(String::from("some other string")); + + // test Ord + let a_b = Ord::cmp(&a, &b); + let b_a = Ord::cmp(&b, &a); + assert_eq!(a_b, Ordering::Equal); + assert_eq!(b_a, Ordering::Equal); + + let a_c = Ord::cmp(&a, &c); + let c_a = Ord::cmp(&c, &a); + let b_c = Ord::cmp(&b, &c); + let c_b = Ord::cmp(&c, &b); + assert_ne!(a_c, Ordering::Equal); + assert_eq!(a_c, b_c); + assert_eq!(c_a, c_b); + assert_eq!(a_c, c_a.reverse()); + assert_eq!(b_c, c_b.reverse()); +}); diff --git a/test/src/lib.rs b/test/src/lib.rs index 597f38b30..0f1a19db5 100644 --- a/test/src/lib.rs +++ b/test/src/lib.rs @@ -24,6 +24,8 @@ pub extern "C" fn run_tests( ) -> gdnative::sys::godot_variant { let mut status = true; status &= gdnative::core_types::test_string(); + status &= gdnative::core_types::test_string_name_eq(); + status &= gdnative::core_types::test_string_name_ord(); status &= gdnative::core_types::test_dictionary(); // status &= gdnative::test_dictionary_clone_clear(); From 37c1360f7a3f725a87fc183f375d00c143baad30 Mon Sep 17 00:00:00 2001 From: Jan Haller Date: Sun, 17 Jul 2022 17:22:49 +0200 Subject: [PATCH 2/2] Workaround Eq/Ord bug for older Godot versions (fixed upstream meanwhile) --- gdnative-core/src/core_types/string.rs | 32 ++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/gdnative-core/src/core_types/string.rs b/gdnative-core/src/core_types/string.rs index 8254c3cbe..9cd2873b2 100644 --- a/gdnative-core/src/core_types/string.rs +++ b/gdnative-core/src/core_types/string.rs @@ -592,8 +592,36 @@ impl StringName { impl_basic_traits_as_sys! { for StringName as godot_string_name { Drop => godot_string_name_destroy; - Eq => godot_string_name_operator_equal; - Ord => godot_string_name_operator_less; + + // Note: Godot's equal/less implementations contained a bug until Godot 3.5, see https://github.com/godot-rust/godot-rust/pull/912 + // Thus explicit impl as a workaround for now + // Eq => godot_string_name_operator_equal; + // Ord => godot_string_name_operator_less; + } +} + +impl PartialEq for StringName { + #[inline] + fn eq(&self, other: &Self) -> bool { + // Slow but correct -- see comment above + self.to_godot_string() == other.to_godot_string() + } +} + +impl Eq for StringName {} + +impl PartialOrd for StringName { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + Some(Ord::cmp(self, other)) + } +} + +impl Ord for StringName { + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + // Slow but correct -- see comment above + Ord::cmp(&self.to_godot_string(), &other.to_godot_string()) } }