|
1 | 1 | use crate::*;
|
2 | 2 | use std::borrow::Cow;
|
| 3 | +use std::collections::HashMap; |
3 | 4 | use std::default::Default;
|
4 | 5 | use std::fmt;
|
| 6 | +use std::hash::Hash; |
5 | 7 | use std::mem::{forget, transmute};
|
6 | 8 | use std::ptr;
|
7 | 9 |
|
@@ -1602,6 +1604,33 @@ impl<T: FromVariant> FromVariant for Vec<T> {
|
1602 | 1604 | }
|
1603 | 1605 | }
|
1604 | 1606 |
|
| 1607 | +impl<K: ToVariant + Hash + ToVariantEq, V: ToVariant> ToVariant for HashMap<K, V> { |
| 1608 | + #[inline] |
| 1609 | + fn to_variant(&self) -> Variant { |
| 1610 | + let dict = Dictionary::new(); |
| 1611 | + for (key, value) in self { |
| 1612 | + dict.insert(key, value); |
| 1613 | + } |
| 1614 | + dict.owned_to_variant() |
| 1615 | + } |
| 1616 | +} |
| 1617 | + |
| 1618 | +impl<K: FromVariant + Hash + Eq, V: FromVariant> FromVariant for HashMap<K, V> { |
| 1619 | + #[inline] |
| 1620 | + fn from_variant(variant: &Variant) -> Result<Self, FromVariantError> { |
| 1621 | + let dictionary = Dictionary::from_variant(variant)?; |
| 1622 | + let len: usize = dictionary |
| 1623 | + .len() |
| 1624 | + .try_into() |
| 1625 | + .expect("Dictionary length should fit in usize"); |
| 1626 | + let mut hash_map = HashMap::with_capacity(len); |
| 1627 | + for (key, value) in dictionary.iter() { |
| 1628 | + hash_map.insert(K::from_variant(&key)?, V::from_variant(&value)?); |
| 1629 | + } |
| 1630 | + Ok(hash_map) |
| 1631 | + } |
| 1632 | +} |
| 1633 | + |
1605 | 1634 | macro_rules! tuple_length {
|
1606 | 1635 | () => { 0usize };
|
1607 | 1636 | ($_x:ident, $($xs:ident,)*) => {
|
@@ -1774,6 +1803,38 @@ godot_test!(
|
1774 | 1803 | assert_eq!(Some(&f64::to_variant(&54.0)), vec_maybe[2].as_ref().err());
|
1775 | 1804 | }
|
1776 | 1805 |
|
| 1806 | + test_variant_hash_map { |
| 1807 | + let original_hash_map = HashMap::from([ |
| 1808 | + ("Foo".to_string(), 4u32), |
| 1809 | + ("Bar".to_string(), 2u32) |
| 1810 | + ]); |
| 1811 | + let variant = original_hash_map.to_variant(); |
| 1812 | + let check_hash_map = variant.try_to::<HashMap<String, u32>>().expect("should be hash map"); |
| 1813 | + assert_eq!(original_hash_map, check_hash_map); |
| 1814 | + // Check conversion of heterogeneous dictionary key types |
| 1815 | + let non_homogenous_key_dictonary = Dictionary::new(); |
| 1816 | + non_homogenous_key_dictonary.insert("Foo".to_string(), 4u32); |
| 1817 | + non_homogenous_key_dictonary.insert(7, 2u32); |
| 1818 | + assert_eq!( |
| 1819 | + non_homogenous_key_dictonary.owned_to_variant().try_to::<HashMap<String, u32>>(), |
| 1820 | + Err(FromVariantError::InvalidVariantType { |
| 1821 | + variant_type: VariantType::I64, |
| 1822 | + expected: VariantType::GodotString |
| 1823 | + }), |
| 1824 | + ); |
| 1825 | + // Check conversion of heterogeneous dictionary value types |
| 1826 | + let non_homogenous_value_dictonary = Dictionary::new(); |
| 1827 | + non_homogenous_value_dictonary.insert("Foo".to_string(), 4u32); |
| 1828 | + non_homogenous_value_dictonary.insert("Bar".to_string(), "Unexpected".to_string()); |
| 1829 | + assert_eq!( |
| 1830 | + non_homogenous_value_dictonary.owned_to_variant().try_to::<HashMap<String, u32>>(), |
| 1831 | + Err(FromVariantError::InvalidVariantType { |
| 1832 | + variant_type: VariantType::GodotString, |
| 1833 | + expected: VariantType::I64 |
| 1834 | + }), |
| 1835 | + ); |
| 1836 | + } |
| 1837 | + |
1777 | 1838 | test_variant_tuple {
|
1778 | 1839 | let variant = (42i64, 54i64).to_variant();
|
1779 | 1840 | let arr = variant.try_to::<VariantArray>().expect("should be array");
|
|
0 commit comments