aoe2_probe/parse/
token.rs

1use serde::{Deserialize, Serialize};
2
3use crate::utils::{DynString, PatchedMap, C256, C4};
4
5use super::code::Encode;
6
7#[derive(Clone, Debug, Serialize, Deserialize)]
8#[serde(tag = "type", content = "value")]
9pub enum Token {
10    UInt8(u8),
11    UInt16(u16),
12    UInt32(u32),
13
14    Int8(i8),
15    Int16(i16),
16    Int32(i32),
17
18    Float32(f32),
19    Float64(f64),
20
21    Char4(C4),
22    Char256(C256),
23
24    Str16(DynString<u16>),
25    Str32(DynString<u32>),
26
27    Union(PatchedMap),
28    Vector(Vec<Token>),
29}
30
31impl Token {
32    /// Retrieve an immutable value by the given path.
33    /// The return value will be a Token enum.
34    /// using token.try_[type] function to get the actual data.
35    /// # Examples
36    ///
37    /// ```
38    /// use aoe2_probe::Scenario;
39    ///
40    /// let scenario = Scenario::from_file("./resources/chapter_1.aoe2scenario").unwrap();
41    /// //Immutable borrow author string.
42    /// let author = scenario.versio.get_by_path("/file_header/creator_name").try_str32();
43    /// ```
44    pub fn get_by_path(&self, path: &str) -> &Token {
45        let keys: Vec<&str> = path.split('/').filter(|str| !str.is_empty()).collect();
46        let mut value = self;
47        for key in keys {
48            value = &value.try_map()[key];
49        }
50        value
51    }
52
53    /// Retrieve a mutable value by the given path.
54    /// The return value will be a Token enum.
55    /// using token.try_mut_[type] function to get the actual data.
56    /// # Examples
57    ///
58    /// ```
59    /// use aoe2_probe::Scenario;
60    ///
61    /// //Mutable borrow author string.
62    /// let mut scenario = Scenario::from_file("./resources/chapter_1.aoe2scenario").unwrap();
63    /// let author = scenario.versio.get_by_path_mut("/file_header/creator_name").try_mut_str32();
64    /// author.set_content("Arian");
65    /// ```
66    pub fn get_by_path_mut(&mut self, path: &str) -> &mut Token {
67        let keys: Vec<&str> = path.split('/').filter(|str| !str.is_empty()).collect();
68        let mut value = self;
69        for key in keys {
70            value = &mut value.try_mut_map()[key];
71        }
72        value
73    }
74
75    pub fn try_u8(&self) -> &u8 {
76        match self {
77            Token::UInt8(value) => value,
78            _ => panic!("Not a u8 element!"),
79        }
80    }
81
82    pub fn try_mut_u8(&mut self) -> &mut u8 {
83        match self {
84            Token::UInt8(value) => value,
85            _ => panic!("Not a u8 element!"),
86        }
87    }
88
89    pub fn try_u16(&self) -> &u16 {
90        match self {
91            Token::UInt16(value) => value,
92            _ => panic!("Not a u16 element!"),
93        }
94    }
95
96    pub fn try_mut_u16(&mut self) -> &mut u16 {
97        match self {
98            Token::UInt16(value) => value,
99            _ => panic!("Not a u16 element!"),
100        }
101    }
102
103    pub fn try_u32(&self) -> &u32 {
104        match self {
105            Token::UInt32(value) => value,
106            _ => panic!("Not a u32 element!"),
107        }
108    }
109
110    pub fn try_mut_u32(&mut self) -> &mut u32 {
111        match self {
112            Token::UInt32(value) => value,
113            _ => panic!("Not a u32 element!"),
114        }
115    }
116
117    pub fn try_i8(&self) -> &i8 {
118        match self {
119            Token::Int8(value) => value,
120            _ => panic!("Not a u8 element!"),
121        }
122    }
123
124    pub fn try_mut_i8(&mut self) -> &mut i8 {
125        match self {
126            Token::Int8(value) => value,
127            _ => panic!("Not a u8 element!"),
128        }
129    }
130
131    pub fn try_i16(&self) -> &i16 {
132        match self {
133            Token::Int16(value) => value,
134            _ => panic!("Not a u16 element!"),
135        }
136    }
137
138    pub fn try_mut_i16(&mut self) -> &mut i16 {
139        match self {
140            Token::Int16(value) => value,
141            _ => panic!("Not a u16 element!"),
142        }
143    }
144
145    pub fn try_i32(&self) -> &i32 {
146        match self {
147            Token::Int32(value) => value,
148            _ => panic!("Not a i32 element!"),
149        }
150    }
151
152    pub fn try_mut_i32(&mut self) -> &mut i32 {
153        match self {
154            Token::Int32(value) => value,
155            _ => panic!("Not a i32 element!"),
156        }
157    }
158
159    pub fn try_f32(&self) -> &f32 {
160        match self {
161            Token::Float32(value) => value,
162            _ => panic!("Not a f32 element!"),
163        }
164    }
165
166    pub fn try_mut_f32(&mut self) -> &mut f32 {
167        match self {
168            Token::Float32(value) => value,
169            _ => panic!("Not a f32 element!"),
170        }
171    }
172
173    pub fn try_f64(&self) -> &f64 {
174        match self {
175            Token::Float64(value) => value,
176            _ => panic!("Not a f64 element!"),
177        }
178    }
179
180    pub fn try_mut_f64(&mut self) -> &mut f64 {
181        match self {
182            Token::Float64(value) => value,
183            _ => panic!("Not a f64 element!"),
184        }
185    }
186
187    pub fn try_c4(&self) -> &C4 {
188        match self {
189            Token::Char4(value) => value,
190            _ => panic!("Not a c4 element!"),
191        }
192    }
193
194    pub fn try_mut_c4(&mut self) -> &mut C4 {
195        match self {
196            Token::Char4(value) => value,
197            _ => panic!("Not a c4 element!"),
198        }
199    }
200
201    pub fn try_c256(&self) -> &C256 {
202        match self {
203            Token::Char256(value) => value,
204            _ => panic!("Not a c256 element!"),
205        }
206    }
207
208    pub fn try_mut_c256(&mut self) -> &mut C256 {
209        match self {
210            Token::Char256(value) => value,
211            _ => panic!("Not a c256 element!"),
212        }
213    }
214
215    pub fn try_str16(&self) -> &DynString<u16> {
216        match self {
217            Token::Str16(value) => value,
218            _ => panic!("Not a f64 element!"),
219        }
220    }
221
222    pub fn try_mut_str16(&mut self) -> &mut DynString<u16> {
223        match self {
224            Token::Str16(value) => value,
225            _ => panic!("Not a f64 element!"),
226        }
227    }
228
229    pub fn try_str32(&self) -> &DynString<u32> {
230        match self {
231            Token::Str32(value) => value,
232            _ => panic!("Not a f64 element!"),
233        }
234    }
235
236    pub fn try_mut_str32(&mut self) -> &mut DynString<u32> {
237        match self {
238            Token::Str32(value) => value,
239            _ => panic!("Not a f64 element!"),
240        }
241    }
242
243    pub fn try_map(&self) -> &PatchedMap {
244        match self {
245            Token::Union(value) => value,
246            _ => panic!("Not a union element!"),
247        }
248    }
249
250    pub fn try_mut_map(&mut self) -> &mut PatchedMap {
251        match self {
252            Token::Union(value) => value,
253            _ => panic!("Not a union element!"),
254        }
255    }
256
257    pub fn try_vec(&self) -> &Vec<Token> {
258        match self {
259            Token::Vector(value) => value,
260            _ => panic!("Not a vec element!"),
261        }
262    }
263
264    pub fn try_mut_vec(&mut self) -> &mut Vec<Token> {
265        match self {
266            Token::Vector(value) => value,
267            _ => panic!("Not a vec element!"),
268        }
269    }
270
271    pub fn try_compatible_u64(&self) -> u64 {
272        match self {
273            Token::UInt8(num) => *num as u64,
274            Token::UInt16(num) => *num as u64,
275            Token::UInt32(num) => *num as u64,
276            Token::Int8(num) => {
277                if *num >= 0 {
278                    *num as u64
279                } else {
280                    0
281                }
282            }
283            Token::Int16(num) => {
284                if *num >= 0 {
285                    *num as u64
286                } else {
287                    0
288                }
289            }
290            Token::Int32(num) => {
291                if *num >= 0 {
292                    *num as u64
293                } else {
294                    0
295                }
296            }
297            Token::Float32(num) => {
298                if *num == 2.0 {
299                    1
300                } else {
301                    0
302                }
303            }
304            Token::Float64(num) => *num as u64,
305            Token::Vector(vec) => {
306                if !vec.is_empty() {
307                    vec[0].try_compatible_u64()
308                } else {
309                    0
310                }
311            }
312            _ => panic!("Not compatible value!"),
313        }
314    }
315}
316
317impl PartialEq for Token {
318    fn eq(&self, other: &Self) -> bool {
319        match (self, other) {
320            (Self::UInt8(_), Self::UInt8(_)) => true,
321            (Self::UInt16(_), Self::UInt16(_)) => true,
322            (Self::UInt32(_), Self::UInt32(_)) => true,
323            (Self::Int8(_), Self::Int8(_)) => true,
324            (Self::Int16(_), Self::Int16(_)) => true,
325            (Self::Int32(_), Self::Int32(_)) => true,
326            (Self::Float32(_), Self::Float32(_)) => true,
327            (Self::Float64(_), Self::Float64(_)) => true,
328            (Self::Char4(_), Self::Char4(_)) => true,
329            (Self::Char256(_), Self::Char256(_)) => true,
330            (Self::Str16(_), Self::Str16(_)) => true,
331            (Self::Str32(_), Self::Str32(_)) => true,
332            (Self::Union(_), Self::Union(_)) => true,
333            (Self::Vector(_), Self::Vector(_)) => true,
334            (_, _) => false,
335        }
336    }
337}
338
339impl Encode for Token {
340    fn to_le_vec(&self) -> Vec<u8> {
341        match self {
342            Token::UInt8(value) => value.to_le_bytes().to_vec(),
343            Token::UInt16(value) => value.to_le_vec(),
344            Token::UInt32(value) => value.to_le_vec(),
345
346            Token::Int8(value) => value.to_le_bytes().to_vec(),
347            Token::Int16(value) => value.to_le_bytes().to_vec(),
348            Token::Int32(value) => value.to_le_bytes().to_vec(),
349
350            Token::Float32(value) => value.to_le_bytes().to_vec(),
351            Token::Float64(value) => value.to_le_bytes().to_vec(),
352
353            Token::Char4(str) => str.clone().to_le_vec(),
354            Token::Char256(str) => str.clone().to_le_vec(),
355
356            Token::Str16(string) => string.to_le_vec(),
357            Token::Str32(string) => string.to_le_vec(),
358
359            Token::Union(union) => union.to_le_vec(),
360            Token::Vector(vec) => vec.to_le_vec(),
361        }
362    }
363}
364
365impl From<u8> for Token {
366    fn from(uint8: u8) -> Self {
367        Token::UInt8(uint8)
368    }
369}
370
371impl From<u16> for Token {
372    fn from(uint16: u16) -> Self {
373        Token::UInt16(uint16)
374    }
375}
376
377impl From<u32> for Token {
378    fn from(uint32: u32) -> Self {
379        Token::UInt32(uint32)
380    }
381}
382
383impl From<i8> for Token {
384    fn from(int8: i8) -> Self {
385        Token::Int8(int8)
386    }
387}
388
389impl From<i16> for Token {
390    fn from(int16: i16) -> Self {
391        Token::Int16(int16)
392    }
393}
394
395impl From<i32> for Token {
396    fn from(int32: i32) -> Self {
397        Token::Int32(int32)
398    }
399}
400
401impl From<f32> for Token {
402    fn from(float32: f32) -> Self {
403        Token::Float32(float32)
404    }
405}
406
407impl From<f64> for Token {
408    fn from(float64: f64) -> Self {
409        Token::Float64(float64)
410    }
411}
412
413impl From<C4> for Token {
414    fn from(char4: C4) -> Self {
415        Token::Char4(char4)
416    }
417}
418
419impl From<C256> for Token {
420    fn from(char256: C256) -> Self {
421        Token::Char256(char256)
422    }
423}
424
425impl From<DynString<u16>> for Token {
426    fn from(str16: DynString<u16>) -> Self {
427        Token::Str16(str16)
428    }
429}
430
431impl From<DynString<u32>> for Token {
432    fn from(str32: DynString<u32>) -> Self {
433        Token::Str32(str32)
434    }
435}
436
437impl From<PatchedMap> for Token {
438    fn from(map: PatchedMap) -> Self {
439        Token::Union(map)
440    }
441}
442
443impl From<Vec<Token>> for Token {
444    fn from(vec: Vec<Token>) -> Self {
445        Token::Vector(vec)
446    }
447}