godot_binary_serialization/types/
structures.rs

1use indexmap::IndexMap;
2
3use super::{variant::{AsVariant, GodotVariant}, TYPE_PADDING};
4
5/// A Vector 2 from godot
6#[derive(PartialEq, Debug, Clone, Copy)]
7pub struct GodotVector2 {
8    pub x: f32,
9    pub y: f32,
10}
11
12impl GodotVector2 {
13    const BIT_SIZE: usize = 8;
14    pub fn new(x: f32, y: f32) -> Self {
15        Self { x, y }
16    }
17}
18
19impl GodotVariant for GodotVector2 {
20    fn byte_length(&self) -> usize {
21        TYPE_PADDING as usize + Self::BIT_SIZE
22    }
23
24    fn as_any(&self) -> &dyn std::any::Any {
25        self
26    }
27    fn variant_eq(&self, other: &dyn GodotVariant) -> bool {
28        if let Some(other) = other.as_var::<GodotVector2>() {
29            self.x == other.x && self.y == other.y
30        } else {
31            false
32        }
33    }
34
35    fn bytes(&self) -> Vec<u8> {
36        format!("{}{}", self.x, self.y).as_bytes().to_vec()
37    }
38}
39
40/// A Vector 3 from godot
41#[derive(PartialEq, Debug, Clone, Copy)]
42pub struct GodotVector3 {
43    pub x: f32,
44    pub y: f32,
45    pub z: f32,
46}
47
48impl GodotVector3 {
49    const BIT_SIZE: usize = 12;
50
51    pub fn new(x: f32, y: f32, z: f32) -> Self {
52        Self { x, y, z }
53    }
54}
55
56impl GodotVariant for GodotVector3 {
57    fn byte_length(&self) -> usize {
58        TYPE_PADDING as usize + Self::BIT_SIZE
59    }
60
61    fn as_any(&self) -> &dyn std::any::Any {
62        self
63    }
64
65    fn variant_eq(&self, other: &dyn GodotVariant) -> bool {
66        if let Some(other) = other.as_var::<GodotVector3>() {
67            self.x == other.x && self.y == other.y && self.z == other.z
68        } else {
69            false
70        }
71    }
72
73    fn bytes(&self) -> Vec<u8> {
74        format!("{}{}{}", self.x, self.y, self.y)
75            .as_bytes()
76            .to_vec()
77    }
78}
79
80/// A Dictionary from godot, similar to an object in javascript, it consists of key:value pairs
81#[derive(Debug)]
82pub struct GodotDictionary {
83    pub map: IndexMap<Box<dyn GodotVariant>, Box<dyn GodotVariant>>,
84    pub byte_size: usize,
85}
86
87impl GodotDictionary {
88    /// Gets a value from a dictionary
89    pub fn get<V>(&self, key: impl GodotVariant + 'static) -> Option<&V>
90    where
91        V: GodotVariant + 'static,
92    {
93        let key = Box::new(key) as Box<dyn GodotVariant>;
94
95        let value = self.map.get(&key)?;
96
97        value.as_var::<V>()
98    }
99
100    /// Inserst a value into a dictionary
101    pub fn insert<K, V>(&mut self, key: K, value: V)
102    where
103        K: GodotVariant + 'static,
104        V: GodotVariant + 'static,
105    {
106        let key = Box::new(key) as Box<dyn GodotVariant>;
107        let value = Box::new(value) as Box<dyn GodotVariant>;
108        self.map.insert(key, value);
109    }
110
111    /// Creates a dictionary that is empty
112    pub fn new() -> Self {
113        Self {
114            map: IndexMap::new(),
115            byte_size: 0,
116        }
117    }
118
119    pub fn new_from_map(map: IndexMap<Box<dyn GodotVariant>, Box<dyn GodotVariant>>) -> Self {
120        Self { map, byte_size: 0 }
121    }
122}
123
124impl Default for GodotDictionary {
125    fn default() -> Self {
126        Self::new()
127    }
128}
129
130impl GodotVariant for GodotDictionary {
131    fn byte_length(&self) -> usize {
132        self.byte_size
133    }
134
135    fn as_any(&self) -> &dyn std::any::Any {
136        self
137    }
138
139    fn variant_eq(&self, other: &dyn GodotVariant) -> bool {
140        if let Some(other) = other.as_var::<GodotDictionary>() {
141            for (key, value) in self.map.iter() {
142                for (o_key, o_value) in other.map.iter() {
143                    if key != o_key || value == o_value {
144                        return false;
145                    }
146                }
147            }
148
149            true
150        } else {
151            false
152        }
153    }
154
155    fn bytes(&self) -> Vec<u8> {
156        format!("{:?}", self.map).as_bytes().to_vec()
157    }
158}