godot_binary_serialization/encoder/
dictionary.rs

1use byteorder::{LittleEndian, WriteBytesExt};
2
3use crate::types::{structures::GodotDictionary, SerializeFlag, GodotTypeIndex};
4
5use super::Encoder;
6
7impl Encoder {
8    /// Encodes a Godot dictionary into bytes. A godot dictionary consists of key value pairs.
9    /// 
10    /// # Example
11    /// 
12    /// Due to the nature of Godot's type system, key's and value's can be different types. Due to
13    /// the nature of Rust, this adds quite a bit of overhead to creating a Dictionary
14    /// ```json
15    /// { "key": "value", "key2": 42, Vector3(45, 2, 9): 9529 }
16    /// ```
17    pub fn encode_dictionary(dictionary: &GodotDictionary) -> anyhow::Result<Vec<u8>> {
18        let mut bytes: Vec<u8> = Vec::new();
19
20        let iterator = dictionary.map.iter();
21        let length = iterator.len();
22
23        bytes.write_i16::<LittleEndian>(GodotTypeIndex::Dictionary as i16)?;
24        bytes.write_i16::<LittleEndian>(SerializeFlag::None as i16)?;
25        bytes.write_i32::<LittleEndian>(length as i32)?;
26
27        for (key, value) in iterator {
28            let mut key_bytes = Encoder::encode_variant(&**key)?;
29            bytes.append(&mut key_bytes);
30            let mut value_bytes = Encoder::encode_variant(&**value)?;
31            bytes.append(&mut value_bytes);
32        }
33
34        Ok(bytes)
35    }
36}
37
38#[cfg(test)]
39mod test {
40    use crate::{
41        encoder::Encoder,
42        types::{
43            primitive::{GodotInteger, GodotString},
44            structures::{GodotDictionary, GodotVector3},
45        },
46    };
47
48    #[test]
49    fn encode_dictionary() {
50        let expected_bytes = [
51            18, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 112, 111, 115, 105, 116, 105, 111,
52            110, 7, 0, 0, 0, 184, 30, 5, 63, 0, 0, 251, 67, 0, 0, 136, 66, 4, 0, 0, 0, 2, 0, 0, 0,
53            105, 100, 0, 0, 2, 0, 0, 0, 181, 2, 0, 0,
54        ]
55        .to_vec();
56
57        let mut dict = GodotDictionary::new();
58        dict.insert(GodotString::new("position"), GodotVector3::new(0.52, 502.0, 68.0));
59        dict.insert(GodotString::new("id"), GodotInteger::new_from_i32(693));
60
61        let bytes = Encoder::encode_dictionary(&dict).unwrap();
62        assert_eq!(
63            expected_bytes, bytes,
64            "Expected {:?} but got {:?}",
65            expected_bytes, bytes
66        );
67    }
68}