Skip to content

Commit aa1b50f

Browse files
committed
Include suggestions from chitoyuu
1 parent e114ba8 commit aa1b50f

File tree

2 files changed

+105
-88
lines changed

2 files changed

+105
-88
lines changed

godot-core/src/builtin/dictionary.rs

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ impl Dictionary {
5151
self.as_inner().duplicate(true)
5252
}
5353

54-
/// Returns a shallow copy of the dictionary. All dictionary keys and values are copied, but
55-
/// any reference types (such as `Array`, `Dictionary` and `Object`) will still refer to the
54+
/// Returns a shallow copy of the dictionary. All dictionary keys and values are copied, but
55+
/// any reference types (such as `Array`, `Dictionary` and `Object`) will still refer to the
5656
/// same value.
5757
///
5858
/// To create a deep copy, use [`duplicate_deep()`] instead. To create a new reference to the
@@ -65,7 +65,7 @@ impl Dictionary {
6565

6666
/// Removes a key from the map, and returns the value associated with
6767
/// the key if the key was in the dictionary.
68-
pub fn remove<K: ToVariant>(&mut self, key: K) -> Option<Variant> {
68+
pub fn remove(&mut self, key: impl ToVariant) -> Option<Variant> {
6969
let key = key.to_variant();
7070
let old_value = self.get(key.clone());
7171
self.as_inner().erase(key);
@@ -76,8 +76,8 @@ impl Dictionary {
7676
///
7777
/// Unlike in godot, this will return `None` if the key does not exist
7878
/// and `Some(nil)` the key is `null`.
79-
pub fn find_key_by_value(&self, value: Variant) -> Option<Variant> {
80-
let key = self.as_inner().find_key(value);
79+
pub fn find_key_by_value(&self, value: impl ToVariant) -> Option<Variant> {
80+
let key = self.as_inner().find_key(value.to_variant());
8181

8282
if !key.is_nil() || self.contains_key(key.clone()) {
8383
Some(key)
@@ -91,7 +91,7 @@ impl Dictionary {
9191
///
9292
/// Unlike `get` in godot, this will return `None` if there is
9393
/// no value with the given key.
94-
pub fn get<K: ToVariant>(&self, key: K) -> Option<Variant> {
94+
pub fn get(&self, key: impl ToVariant) -> Option<Variant> {
9595
let key = key.to_variant();
9696
if !self.contains_key(key.clone()) {
9797
return None;
@@ -100,19 +100,19 @@ impl Dictionary {
100100
Some(self.get_or_nil(key))
101101
}
102102

103-
/// Returns the value at the key in the dictionary, or nil otherwise. This
104-
/// method does not let you differentiate `NIL` values stored as values from
103+
/// Returns the value at the key in the dictionary, or nil otherwise. This
104+
/// method does not let you differentiate `NIL` values stored as values from
105105
/// absent keys. If you need that, use `get()`.
106106
///
107107
/// This is equivalent to `get` in godot.
108-
pub fn get_or_nil<K: ToVariant>(&self, key: K) -> Variant {
108+
pub fn get_or_nil(&self, key: impl ToVariant) -> Variant {
109109
self.as_inner().get(key.to_variant(), Variant::nil())
110110
}
111111

112112
/// Returns `true` if the dictionary contains the given key.
113113
///
114114
/// This is equivalent to `has` in godot.
115-
pub fn contains_key<K: ToVariant>(&self, key: K) -> bool {
115+
pub fn contains_key(&self, key: impl ToVariant) -> bool {
116116
let key = key.to_variant();
117117
self.as_inner().has(key)
118118
}
@@ -164,7 +164,7 @@ impl Dictionary {
164164
/// Get the pointer corresponding to the given key in the dictionary,
165165
/// this pointer is null if there is no value at the given key.
166166
#[allow(dead_code)] // TODO: remove function if it turns out i'll never actually get any use out of it
167-
fn get_ptr<K: ToVariant>(&self, key: K) -> *const Variant {
167+
fn get_ptr(&self, key: impl ToVariant) -> *const Variant {
168168
let key = key.to_variant();
169169
unsafe {
170170
(interface_fn!(dictionary_operator_index_const))(self.sys_const(), key.var_sys_const())
@@ -175,7 +175,7 @@ impl Dictionary {
175175
/// Get the pointer corresponding to the given key in the dictionary,
176176
/// if there exists no value at the given key then a new one is created
177177
/// and initialized to a nil variant.
178-
fn get_ptr_mut<K: ToVariant>(&mut self, key: K) -> *mut Variant {
178+
fn get_ptr_mut(&mut self, key: impl ToVariant) -> *mut Variant {
179179
let key = key.to_variant();
180180
unsafe {
181181
let ptr =
@@ -190,41 +190,21 @@ impl Dictionary {
190190

191191
/// Insert a value at the given key, returning the value
192192
/// that previously was at that key if there was one.
193-
pub fn insert<K: ToVariant>(&mut self, key: K, value: Variant) -> Option<Variant> {
193+
pub fn insert(&mut self, key: impl ToVariant, value: impl ToVariant) -> Option<Variant> {
194194
let key = key.to_variant();
195195
let old_value = self.get(key.clone());
196196
self.set(key, value);
197197
old_value
198198
}
199199

200200
/// Set a key to a given value
201-
pub fn set<K: ToVariant>(&mut self, key: K, value: Variant) {
201+
pub fn set(&mut self, key: impl ToVariant, value: impl ToVariant) {
202202
let key = key.to_variant();
203203
unsafe {
204-
*self.get_ptr_mut(key) = value;
204+
*self.get_ptr_mut(key) = value.to_variant();
205205
}
206206
}
207207

208-
/// Convert this dictionary to a strongly typed rust `HashMap`. If the conversion
209-
/// fails for any key or value, an error is returned.
210-
pub fn try_to_hashmap<K: FromVariant + Eq + std::hash::Hash, V: FromVariant>(
211-
&self,
212-
) -> Result<HashMap<K, V>, VariantConversionError> {
213-
let mut map = HashMap::new();
214-
for key in self.keys().into_iter() {
215-
map.insert(key.try_to()?, self.get(key).unwrap().try_to()?);
216-
}
217-
Ok(map)
218-
}
219-
220-
/// Convert the keys of this dictionary to a strongly typed rust `HashSet`. If the
221-
/// conversion fails for any key, an error is returned.
222-
pub fn try_to_hashset<K: FromVariant + Eq + std::hash::Hash>(
223-
&self,
224-
) -> Result<HashSet<K>, VariantConversionError> {
225-
Ok(self.keys().try_to_vec::<K>()?.into_iter().collect())
226-
}
227-
228208
#[doc(hidden)]
229209
pub fn as_inner(&self) -> inner::InnerDictionary {
230210
inner::InnerDictionary::from_outer(self)
@@ -236,7 +216,7 @@ impl Dictionary {
236216
impl<K: ToVariant, V: ToVariant> From<&HashMap<K, V>> for Dictionary {
237217
fn from(map: &HashMap<K, V>) -> Self {
238218
let mut dict = Dictionary::new();
239-
for (k, v) in map.into_iter() {
219+
for (k, v) in map.iter() {
240220
dict.insert(k.to_variant(), v.to_variant());
241221
}
242222
dict
@@ -245,16 +225,53 @@ impl<K: ToVariant, V: ToVariant> From<&HashMap<K, V>> for Dictionary {
245225

246226
/// Creates a `Dictionary` from the given `HashSet`. Each key is converted
247227
/// to a `Variant`, and the values are all `true`.
228+
///
229+
///
248230
impl<K: ToVariant> From<&HashSet<K>> for Dictionary {
249231
fn from(set: &HashSet<K>) -> Self {
250232
let mut dict = Dictionary::new();
251-
for k in set.into_iter() {
233+
for k in set.iter() {
252234
dict.insert(k.to_variant(), true.to_variant());
253235
}
254236
dict
255237
}
256238
}
257239

240+
/// Convert this dictionary to a strongly typed rust `HashMap`. If the conversion
241+
/// fails for any key or value, an error is returned.
242+
///
243+
/// Will be replaced by a proper iteration implementation.
244+
impl<K: FromVariant + Eq + std::hash::Hash, V: FromVariant> TryFrom<&Dictionary> for HashMap<K, V> {
245+
type Error = VariantConversionError;
246+
247+
fn try_from(dictionary: &Dictionary) -> Result<Self, Self::Error> {
248+
// TODO: try to panic or something if modified while iterating
249+
// Though probably better to fix when implementing iteration proper
250+
dictionary
251+
.keys()
252+
.iter()
253+
.zip(dictionary.values().iter())
254+
.map(|(key, value)| Ok((K::try_from_variant(&key)?, V::try_from_variant(&value)?)))
255+
.collect()
256+
}
257+
}
258+
259+
/// Convert the keys of this dictionary to a strongly typed rust `HashSet`. If the
260+
/// conversion fails for any key, an error is returned.
261+
impl<K: FromVariant + Eq + std::hash::Hash> TryFrom<&Dictionary> for HashSet<K> {
262+
type Error = VariantConversionError;
263+
264+
fn try_from(dictionary: &Dictionary) -> Result<Self, Self::Error> {
265+
// TODO: try to panic or something if modified while iterating
266+
// Though probably better to fix when implementing iteration proper
267+
dictionary
268+
.keys()
269+
.iter()
270+
.map(|key| K::try_from_variant(&key))
271+
.collect()
272+
}
273+
}
274+
258275
/// Inserts all key-values from the iterator into the dictionary,
259276
/// replacing values with existing keys with new values returned
260277
/// from the iterator.
@@ -335,7 +352,7 @@ macro_rules! dict {
335352
{
336353
let mut d = ::godot::builtin::Dictionary::new();
337354
$(
338-
d.set($key, ::godot::builtin::Variant::from($value));
355+
d.set($key, $value);
339356
)*
340357
d
341358
}

0 commit comments

Comments
 (0)