From 3786a0a132a656abbff187b586cb5383401b6960 Mon Sep 17 00:00:00 2001 From: Lili Zoey Date: Sat, 28 Jan 2023 16:34:59 +0100 Subject: [PATCH] Include suggestions from code review --- godot-core/src/builtin/arrays.rs | 2 +- godot-core/src/builtin/dictionary.rs | 239 ++++++++++++++++----------- godot-core/src/builtin/string.rs | 6 +- itest/rust/src/dictionary_test.rs | 127 +++++++------- 4 files changed, 212 insertions(+), 162 deletions(-) diff --git a/godot-core/src/builtin/arrays.rs b/godot-core/src/builtin/arrays.rs index 919f2ca73..44fca959f 100644 --- a/godot-core/src/builtin/arrays.rs +++ b/godot-core/src/builtin/arrays.rs @@ -565,7 +565,7 @@ impl_builtin_traits! { for Array { Default => array_construct_default; Drop => array_destroy; - Eq => array_operator_equal; + PartialEq => array_operator_equal; } } diff --git a/godot-core/src/builtin/dictionary.rs b/godot-core/src/builtin/dictionary.rs index 74fc65d36..7e446cc41 100644 --- a/godot-core/src/builtin/dictionary.rs +++ b/godot-core/src/builtin/dictionary.rs @@ -1,23 +1,24 @@ use godot_ffi as sys; use crate::builtin::{inner, FromVariant, ToVariant, Variant, VariantConversionError}; +use crate::obj::Share; use std::collections::{HashMap, HashSet}; use std::fmt; -use sys::{ffi_methods, interface_fn, GodotFfi}; use sys::types::*; +use sys::{ffi_methods, interface_fn, GodotFfi}; use super::Array; /// Godot's `Dictionary` type. /// /// The keys and values of the array are all `Variant`, so they can all be of different types. -/// -/// Keys are assumed to be cheap to clone, this will usually be the case especially for +/// +/// Keys are assumed to be cheap to clone, this will usually be the case especially for /// value types and reference counted types. /// -/// # Safety +/// # Thread safety /// -/// TODO: I suspect it is similar to the rules for array. +/// The same principles apply as for [`Array`]. Consult its documentation for details. #[repr(C)] pub struct Dictionary { opaque: OpaqueDictionary, @@ -28,7 +29,7 @@ impl Dictionary { Self { opaque } } - /// Constructs an empty `Dictionary` + /// Constructs an empty `Dictionary`. pub fn new() -> Self { Self::default() } @@ -38,17 +39,25 @@ impl Dictionary { self.as_inner().clear() } - /// Returns a deep copy of the dictionary. All nested array/dictionary keys and - /// values are duplicated as well. - /// + /// Returns a deep copy of the dictionary. All nested arrays and dictionaries are duplicated and + /// will not be shared with the original dictionary. Note that any `Object`-derived elements will + /// still be shallow copied. + /// + /// To create a shallow copy, use [`duplicate_shallow()`] instead. To create a new reference to + /// the same array data, use [`share()`]. + /// /// Equivalent to `dictionary.duplicate(true)` in godot. pub fn duplicate_deep(&self) -> Self { self.as_inner().duplicate(true) } - /// Returns a shallow copy of the dictionary. Nested array/dictionary keys and - /// values are not duplicated. - /// + /// Returns a shallow copy of the dictionary. All dictionary keys and values are copied, but + /// any reference types (such as `Array`, `Dictionary` and `Object`) will still refer to the + /// same value. + /// + /// To create a deep copy, use [`duplicate_deep()`] instead. To create a new reference to the + /// same dictionary data, use [`share()`]. + /// /// Equivalent to `dictionary.duplicate(false)` in godot. pub fn duplicate_shallow(&self) -> Self { self.as_inner().duplicate(false) @@ -56,19 +65,19 @@ impl Dictionary { /// Removes a key from the map, and returns the value associated with /// the key if the key was in the dictionary. - pub fn remove(&mut self, key: K) -> Option { + pub fn remove(&mut self, key: impl ToVariant) -> Option { let key = key.to_variant(); let old_value = self.get(key.clone()); self.as_inner().erase(key); old_value } - /// Returns the first key whose associated value is `value`, if one exists - /// + /// Returns the first key whose associated value is `value`, if one exists. + /// /// Unlike in godot, this will return `None` if the key does not exist - /// and `Some(nil)` the key is `null` - pub fn find_key(&self, value: Variant) -> Option { - let key = self.as_inner().find_key(value); + /// and `Some(nil)` the key is `null`. + pub fn find_key_by_value(&self, value: impl ToVariant) -> Option { + let key = self.as_inner().find_key(value.to_variant()); if !key.is_nil() || self.contains_key(key.clone()) { Some(key) @@ -78,11 +87,11 @@ impl Dictionary { } /// Returns the value at the key in the dictionary, if there is - /// one - /// + /// one. + /// /// Unlike `get` in godot, this will return `None` if there is - /// no value with the given key. - pub fn get(&self, key: K) -> Option { + /// no value with the given key. + pub fn get(&self, key: impl ToVariant) -> Option { let key = key.to_variant(); if !self.contains_key(key.clone()) { return None; @@ -91,24 +100,26 @@ impl Dictionary { Some(self.get_or_nil(key)) } - /// Returns the value at the key in the dictionary, or nil otherwise - /// + /// Returns the value at the key in the dictionary, or nil otherwise. This + /// method does not let you differentiate `NIL` values stored as values from + /// absent keys. If you need that, use `get()`. + /// /// This is equivalent to `get` in godot. - pub fn get_or_nil(&self, key: K) -> Variant { + pub fn get_or_nil(&self, key: impl ToVariant) -> Variant { self.as_inner().get(key.to_variant(), Variant::nil()) } - /// Returns `true` if the dictionary contains the given key - /// - /// This is equivalent to `has` in godot - pub fn contains_key(&self, key: K) -> bool { + /// Returns `true` if the dictionary contains the given key. + /// + /// This is equivalent to `has` in godot. + pub fn contains_key(&self, key: impl ToVariant) -> bool { let key = key.to_variant(); self.as_inner().has(key) } - /// Returns `true` if the dictionary contains all the given keys - /// - /// This is equivalent to `has_all` in godot + /// Returns `true` if the dictionary contains all the given keys. + /// + /// This is equivalent to `has_all` in godot. pub fn contains_all_keys(&self, keys: Array) -> bool { self.as_inner().has_all(keys) } @@ -118,33 +129,33 @@ impl Dictionary { self.as_inner().hash().try_into().unwrap() } - /// Creates a new `Array` containing all the keys currently in the dictionary + /// Creates a new `Array` containing all the keys currently in the dictionary. pub fn keys(&self) -> Array { self.as_inner().keys() } - /// Creates a new `Array` containing all the values currently in the dictionary + /// Creates a new `Array` containing all the values currently in the dictionary. pub fn values(&self) -> Array { self.as_inner().values() } - /// Returns true if the dictionary is empty + /// Returns true if the dictionary is empty. pub fn is_empty(&self) -> bool { self.as_inner().is_empty() } /// Copies all keys and values from other into self. - /// + /// /// If overwrite is true, it will overwrite pre-existing keys. Otherwise /// it will not. - /// + /// /// This is equivalent to `merge` in godot. pub fn extend_dictionary(&mut self, other: Self, overwrite: bool) { self.as_inner().merge(other, overwrite) } - /// Returns the number of entries in the dictionary - /// + /// Returns the number of entries in the dictionary. + /// /// This is equivalent to `size` in godot. pub fn len(&self) -> usize { self.as_inner().size().try_into().unwrap() @@ -152,21 +163,24 @@ impl Dictionary { /// Get the pointer corresponding to the given key in the dictionary, /// this pointer is null if there is no value at the given key. - pub fn get_ptr(&self, key: K) -> *const Variant { + #[allow(dead_code)] // TODO: remove function if it turns out i'll never actually get any use out of it + fn get_ptr(&self, key: impl ToVariant) -> *const Variant { let key = key.to_variant(); unsafe { - (interface_fn!(dictionary_operator_index_const))(self.sys_const(), key.var_sys_const()) as *const Variant + (interface_fn!(dictionary_operator_index_const))(self.sys_const(), key.var_sys_const()) + as *const Variant } } /// Get the pointer corresponding to the given key in the dictionary, /// if there exists no value at the given key then a new one is created /// and initialized to a nil variant. - pub fn get_ptr_mut(&mut self, key: K) -> *mut Variant { + fn get_ptr_mut(&mut self, key: impl ToVariant) -> *mut Variant { let key = key.to_variant(); unsafe { let ptr = - (interface_fn!(dictionary_operator_index))(self.sys_mut(), key.var_sys_const()) as *mut Variant; + (interface_fn!(dictionary_operator_index))(self.sys_mut(), key.var_sys_const()) + as *mut Variant; // dictionary_operator_index initializes the value so it wont be null assert!(!ptr.is_null()); // i think it might be safe to turn this into a &mut Variant? @@ -176,39 +190,19 @@ impl Dictionary { /// Insert a value at the given key, returning the value /// that previously was at that key if there was one. - pub fn insert(&mut self, key: K, value: Variant) -> Option { + pub fn insert(&mut self, key: impl ToVariant, value: impl ToVariant) -> Option { let key = key.to_variant(); - let old_value = self.remove(key.clone()); + let old_value = self.get(key.clone()); self.set(key, value); old_value } /// Set a key to a given value - pub fn set(&mut self, key: K, value: Variant) { + pub fn set(&mut self, key: impl ToVariant, value: impl ToVariant) { let key = key.to_variant(); unsafe { - *self.get_ptr_mut(key) = value; - } - } - - /// Convert this dictionary to a strongly typed rust `HashMap`. If the conversion - /// fails for any key or value, an error is returned. - pub fn try_to_hashmap( - &self, - ) -> Result, VariantConversionError> { - let mut map = HashMap::new(); - for key in self.keys().into_iter() { - map.insert(key.try_to()?, self.get(key).unwrap().try_to()?); + *self.get_ptr_mut(key) = value.to_variant(); } - Ok(map) - } - - /// Convert the keys of this dictionary to a strongly typed rust `HashSet`. If the - /// conversion fails for any key, an error is returned. - pub fn try_to_hashset( - &self, - ) -> Result, VariantConversionError> { - Ok(self.keys().try_to_vec::()?.into_iter().collect()) } #[doc(hidden)] @@ -217,27 +211,51 @@ impl Dictionary { } } -/// Creates a `Dictionary` from the given `HashMap`. Each key and value are +/// Creates a `Dictionary` from the given `T`. Each key and value are /// converted to a `Variant`. -impl From> for Dictionary { - fn from(map: HashMap) -> Self { - let mut dict = Dictionary::new(); - for (k, v) in map.into_iter() { - dict.insert(k.to_variant(), v.to_variant()); - } - dict +impl<'a, 'b, K, V, T> From for Dictionary +where + T: IntoIterator, + K: ToVariant + 'a, + V: ToVariant + 'b, +{ + fn from(iterable: T) -> Self { + iterable.into_iter().map(|(key,value)| (key.to_variant(), value.to_variant())).collect() } } -/// Creates a `Dictionary` from the given `HashSet`. Each key is converted -/// to a `Variant`, and the values are all `true`. -impl From> for Dictionary { - fn from(set: HashSet) -> Self { - let mut dict = Dictionary::new(); - for k in set.into_iter() { - dict.insert(k.to_variant(), true.to_variant()); - } - dict +/// Convert this dictionary to a strongly typed rust `HashMap`. If the conversion +/// fails for any key or value, an error is returned. +/// +/// Will be replaced by a proper iteration implementation. +impl TryFrom<&Dictionary> for HashMap { + type Error = VariantConversionError; + + fn try_from(dictionary: &Dictionary) -> Result { + // TODO: try to panic or something if modified while iterating + // Though probably better to fix when implementing iteration proper + dictionary + .keys() + .iter_shared() + .zip(dictionary.values().iter_shared()) + .map(|(key, value)| Ok((K::try_from_variant(&key)?, V::try_from_variant(&value)?))) + .collect() + } +} + +/// Convert the keys of this dictionary to a strongly typed rust `HashSet`. If the +/// conversion fails for any key, an error is returned. +impl TryFrom<&Dictionary> for HashSet { + type Error = VariantConversionError; + + fn try_from(dictionary: &Dictionary) -> Result { + // TODO: try to panic or something if modified while iterating + // Though probably better to fix when implementing iteration proper + dictionary + .keys() + .iter_shared() + .map(|key| K::try_from_variant(&key)) + .collect() } } @@ -247,7 +265,7 @@ impl From> for Dictionary { impl Extend<(K, V)> for Dictionary { fn extend>(&mut self, iter: T) { for (k, v) in iter.into_iter() { - self.insert(k.to_variant(), v.to_variant()); + self.set(k.to_variant(), v.to_variant()) } } } @@ -256,7 +274,7 @@ impl FromIterator<(K, V)> for Dictionary { fn from_iter>(iter: T) -> Self { let mut dict = Dictionary::new(); for (k, v) in iter.into_iter() { - dict.insert(k.to_variant(), v.to_variant()); + dict.set(k.to_variant(), v.to_variant()) } dict } @@ -265,9 +283,8 @@ impl FromIterator<(K, V)> for Dictionary { impl_builtin_traits! { for Dictionary { Default => dictionary_construct_default; - Clone => dictionary_construct_copy; Drop => dictionary_destroy; - Eq => dictionary_operator_equal; + PartialEq => dictionary_operator_equal; } } @@ -281,33 +298,53 @@ impl fmt::Debug for Dictionary { } } +/// Creates a new reference to the data in this dictionary. Changes to the original dictionary will be +/// reflected in the copy and vice versa. +/// +/// To create a (mostly) independent copy instead, see [`Dictionary::duplicate_shallow()`] and +/// [`Dictionary::duplicate_deep()`]. +impl Share for Dictionary { + fn share(&self) -> Self { + unsafe { + Self::from_sys_init(|self_ptr| { + let ctor = sys::builtin_fn!(dictionary_construct_copy); + let args = [self.sys_const()]; + ctor(self_ptr, args.as_ptr()); + }) + } + } +} + /// Creates a new dictionary with the given keys and values, the syntax mirrors /// godot's dictionary creation syntax. -/// -/// Currently only literal keys are supported. But any expression whose result -/// can be converted with `Variant::from()` may be used. -/// +/// +/// Any value can be used as a key, but to use an expression you need to surround it +/// in `()` or `{}` +/// /// Example /// ```rust, no_run /// # #[macro_use] extern crate godot_core; /// # fn main() { +/// let key = "my_key"; /// let d = dict! { /// "key1": 10, /// "another": Variant::nil(), -/// "true": true, -/// "final": "final", +/// key: true, +/// (1 + 2): "final", /// } /// # } -/// ``` +/// ``` #[macro_export] macro_rules! dict { - () => { - ::godot::builtin::Dictionary::new() - }; - ($($key:literal: $value:expr),+ $(,)?) => { + ($($key:tt: $value:expr),* $(,)?) => { { - let mut d = ::godot::builtin::Dictionary::new(); - $(d.set($key, ::godot::builtin::Variant::from($value));)* + let mut d = $crate::builtin::Dictionary::new(); + $( + // otherwise `(1 + 2): true` would complain even though you can't write + // 1 + 2: true + #[allow(unused_parens)] + d.set($key, $value); + )* d } }; diff --git a/godot-core/src/builtin/string.rs b/godot-core/src/builtin/string.rs index b9921385d..8995815d8 100644 --- a/godot-core/src/builtin/string.rs +++ b/godot-core/src/builtin/string.rs @@ -151,19 +151,19 @@ impl fmt::Debug for GodotString { impl ToVariant for &str { fn to_variant(&self) -> Variant { - crate::builtin::GodotString::from(*self).to_variant() + GodotString::from(*self).to_variant() } } impl ToVariant for String { fn to_variant(&self) -> Variant { - crate::builtin::GodotString::from(self).to_variant() + GodotString::from(self).to_variant() } } impl FromVariant for String { fn try_from_variant(variant: &Variant) -> Result { - Ok(crate::builtin::GodotString::try_from_variant(variant)?.to_string()) + Ok(GodotString::try_from_variant(variant)?.to_string()) } } diff --git a/itest/rust/src/dictionary_test.rs b/itest/rust/src/dictionary_test.rs index ea431b778..5360b7b44 100644 --- a/itest/rust/src/dictionary_test.rs +++ b/itest/rust/src/dictionary_test.rs @@ -9,7 +9,7 @@ use std::collections::{HashMap, HashSet}; use crate::itest; use godot::{ builtin::{Dictionary, FromVariant, ToVariant}, - prelude::Variant, + prelude::{Variant, Share}, private::class_macros::dict, }; @@ -55,12 +55,12 @@ fn dictionary_from_iterator() { assert_eq!(dictionary.len(), 2); assert_eq!( - dictionary.get("foo".to_variant()), + dictionary.get("foo"), Some(1.to_variant()), "key = \"foo\"" ); assert_eq!( - dictionary.get("bar".to_variant()), + dictionary.get("bar"), Some(2.to_variant()), "key = \"bar\"" ); @@ -69,12 +69,12 @@ fn dictionary_from_iterator() { assert_eq!(dictionary.len(), 2); assert_eq!( - dictionary.get(1.to_variant()), + dictionary.get(1), Some("foo".to_variant()), "key = 1" ); assert_eq!( - dictionary.get(2.to_variant()), + dictionary.get(2), Some("bar".to_variant()), "key = 2" ); @@ -82,30 +82,30 @@ fn dictionary_from_iterator() { #[itest] fn dictionary_from() { - let dictionary = Dictionary::from(HashMap::from([("foo", 1), ("bar", 2)])); + let dictionary = Dictionary::from(&HashMap::from([("foo", 1), ("bar", 2)])); assert_eq!(dictionary.len(), 2); assert_eq!( - dictionary.get("foo".to_variant()), + dictionary.get("foo"), Some(1.to_variant()), "key = \"foo\"" ); assert_eq!( - dictionary.get("bar".to_variant()), + dictionary.get("bar"), Some(2.to_variant()), "key = \"bar\"" ); - let dictionary = Dictionary::from(HashMap::from([(1, "foo"), (2, "bar")])); + let dictionary = Dictionary::from(&HashMap::from([(1, "foo"), (2, "bar")])); assert_eq!(dictionary.len(), 2); assert_eq!( - dictionary.get(1.to_variant()), + dictionary.get(1), Some("foo".to_variant()), "key = \"foo\"" ); assert_eq!( - dictionary.get(2.to_variant()), + dictionary.get(2), Some("bar".to_variant()), "key = \"bar\"" ); @@ -121,20 +121,33 @@ fn dictionary_macro() { assert_eq!(dictionary.len(), 3); assert_eq!( - dictionary.get("foo".to_variant()), + dictionary.get("foo"), Some(0.to_variant()), "key = \"foo\"" ); assert_eq!( - dictionary.get("bar".to_variant()), + dictionary.get("bar"), Some(true.to_variant()), "key = \"bar\"" ); assert_eq!( - dictionary.get("baz".to_variant()), + dictionary.get("baz"), Some("foobar".to_variant()), "key = \"baz\"" ); + + let empty = dict!(); + assert!(empty.is_empty()); + + let foo = "foo"; + let dict_complex = dict! { + foo: 10, + "bar": true, + (1 + 2): Variant::nil(), + }; + assert_eq!(dict_complex.get("foo"), Some(10.to_variant())); + assert_eq!(dict_complex.get("bar"), Some(true.to_variant())); + assert_eq!(dict_complex.get(3), Some(Variant::nil())); } #[itest] @@ -146,7 +159,7 @@ fn dictionary_try_to_hashmap() { }; assert_eq!( - dictionary.try_to_hashmap::(), + HashMap::::try_from(&dictionary), Ok(HashMap::from([ ("foo".into(), 0), ("bar".into(), 1), @@ -164,7 +177,7 @@ fn dictionary_try_to_hashset() { }; assert_eq!( - dictionary.try_to_hashset::(), + HashSet::::try_from(&dictionary), Ok(HashSet::from(["foo".into(), "bar".into(), "baz".into()])) ); } @@ -177,15 +190,15 @@ fn dictionary_clone() { }; let dictionary = dict! { "foo": 0, - "bar": subdictionary.clone() + "bar": subdictionary.share() }; #[allow(clippy::redundant_clone)] - let clone = dictionary.clone(); - Dictionary::try_from_variant(&clone.get("bar".to_variant()).unwrap()) + let clone = dictionary.share(); + Dictionary::try_from_variant(&clone.get("bar").unwrap()) .unwrap() - .insert("final".to_variant(), 4.to_variant()); + .insert("final", 4); assert_eq!( - subdictionary.get("final".to_variant()), + subdictionary.get("final"), Some(4.to_variant()) ); } @@ -208,14 +221,14 @@ fn dictionary_duplicate_deep() { }; let dictionary = dict! { "foo": 0, - "bar": subdictionary.clone() + "bar": subdictionary.share() }; let clone = dictionary.duplicate_deep(); - Dictionary::try_from_variant(&clone.get("bar".to_variant()).unwrap()) + Dictionary::try_from_variant(&clone.get("bar").unwrap()) .unwrap() - .insert("baz".to_variant(), 4.to_variant()); + .insert("baz", 4); assert_eq!( - subdictionary.get("baz".to_variant()), + subdictionary.get("baz"), Some(true.to_variant()), "key = \"baz\"" ); @@ -229,14 +242,14 @@ fn dictionary_duplicate_shallow() { }; let dictionary = dict! { "foo": 0, - "bar": subdictionary.clone() + "bar": subdictionary.share() }; let mut clone = dictionary.duplicate_shallow(); - Dictionary::try_from_variant(&clone.get("bar".to_variant()).unwrap()) + Dictionary::try_from_variant(&clone.get("bar").unwrap()) .unwrap() - .insert("baz".to_variant(), 4.to_variant()); + .insert("baz", 4); assert_eq!( - subdictionary.get("baz".to_variant()), + subdictionary.get("baz"), Some(4.to_variant()), "key = \"baz\"" ); @@ -254,44 +267,44 @@ fn dictionary_get() { "nil": Variant::nil(), }; - dictionary.insert("baz".to_variant(), "foobar".to_variant()); + dictionary.insert("baz", "foobar"); assert_eq!( - dictionary.get("foo".to_variant()), + dictionary.get("foo"), Some(0.to_variant()), "key = \"foo\"" ); assert_eq!( - dictionary.get("bar".to_variant()), + dictionary.get("bar"), Some(true.to_variant()), "key = \"bar\"" ); assert_eq!( - dictionary.get("baz".to_variant()), + dictionary.get("baz"), Some("foobar".to_variant()) ); assert_eq!( - dictionary.get("nil".to_variant()), + dictionary.get("nil"), Some(Variant::nil()), "key = \"nil\"" ); assert_eq!( - dictionary.get("missing".to_variant()), + dictionary.get("missing"), None, "key = \"missing\"" ); assert_eq!( - dictionary.get_or_nil("nil".to_variant()), + dictionary.get_or_nil("nil"), Variant::nil(), "key = \"nil\"" ); assert_eq!( - dictionary.get_or_nil("missing".to_variant()), + dictionary.get_or_nil("missing"), Variant::nil(), "key = \"missing\"" ); assert_eq!( - dictionary.get("foobar".to_variant()), + dictionary.get("foobar"), None, "key = \"foobar\"" ); @@ -305,17 +318,17 @@ fn dictionary_insert() { }; assert_eq!( - dictionary.insert("bar".to_variant(), 2.to_variant()), + dictionary.insert("bar", 2), Some(1.to_variant()) ); assert_eq!( - dictionary.try_to_hashmap::().unwrap(), - HashMap::from([("foo".into(), 0), ("bar".into(), 2)]) + HashMap::::try_from(&dictionary), + Ok(HashMap::from([("foo".into(), 0), ("bar".into(), 2)])) ); - assert_eq!(dictionary.insert("baz".to_variant(), 3.to_variant()), None); + assert_eq!(dictionary.insert("baz", 3), None); assert_eq!( - dictionary.try_to_hashmap::().unwrap(), - HashMap::from([("foo".into(), 0), ("bar".into(), 2), ("baz".into(), 3)]) + HashMap::::try_from(&dictionary), + Ok(HashMap::from([("foo".into(), 0), ("bar".into(), 2), ("baz".into(), 3)])) ); } @@ -324,21 +337,21 @@ fn dictionary_insert_multiple() { let mut dictionary = dict! {}; assert!(dictionary.is_empty()); - dictionary.insert(1.to_variant(), true.to_variant()); - assert_eq!(dictionary.get(1.to_variant()), Some(true.to_variant())); + dictionary.insert(1, true); + assert_eq!(dictionary.get(1), Some(true.to_variant())); let mut other = dict! {}; assert!(other.is_empty()); - other.insert(1.to_variant(), 2.to_variant()); - assert_eq!(other.get(1.to_variant()), Some(2.to_variant())); + other.insert(1, 2); + assert_eq!(other.get(1), Some(2.to_variant())); } #[itest] fn dictionary_insert_long() { let mut dictionary = dict! {}; let old = dictionary.insert( "abcdefghijklmnopqrstuvwxyz", - "zabcdefghijklmnopqrstuvwxy".to_variant(), + "zabcdefghijklmnopqrstuvwxy", ); assert_eq!(old, None); assert_eq!( @@ -353,14 +366,14 @@ fn dictionary_extend() { "foo": 0, "bar": true, }; - assert_eq!(dictionary.get("foo".to_variant()), Some(0.to_variant())); + assert_eq!(dictionary.get("foo"), Some(0.to_variant())); let other = dict! { "bar": "new", "baz": Variant::nil(), }; dictionary.extend_dictionary(other, false); - assert_eq!(dictionary.get("bar".to_variant()), Some(true.to_variant())); - assert_eq!(dictionary.get("baz".to_variant()), Some(Variant::nil())); + assert_eq!(dictionary.get("bar"), Some(true.to_variant())); + assert_eq!(dictionary.get("baz"), Some(Variant::nil())); let mut dictionary = dict! { "bar": true, @@ -369,7 +382,7 @@ fn dictionary_extend() { "bar": "new", }; dictionary.extend_dictionary(other, true); - assert_eq!(dictionary.get("bar".to_variant()), Some("new".to_variant())); + assert_eq!(dictionary.get("bar"), Some("new".to_variant())); } #[itest] @@ -377,8 +390,8 @@ fn dictionary_remove() { let mut dictionary = dict! { "foo": 0, }; - assert_eq!(dictionary.remove("foo".to_variant()), Some(0.to_variant())); - assert!(!dictionary.contains_key("foo".to_variant())); + assert_eq!(dictionary.remove("foo"), Some(0.to_variant())); + assert!(!dictionary.contains_key("foo")); assert!(dictionary.is_empty()); } @@ -403,11 +416,11 @@ fn dictionary_find_key() { }; assert_eq!( - dictionary.find_key(0.to_variant()), + dictionary.find_key_by_value(0), Some("foo".to_variant()) ); assert_eq!( - dictionary.find_key(true.to_variant()), + dictionary.find_key_by_value(true), Some("bar".to_variant()) ); }