binary_codec/
config.rs

1use std::collections::HashMap;
2
3#[derive(Clone, Debug)]
4pub struct SerializerConfig<T = ()>
5where
6    T: Clone,
7{
8    toggle_keys: HashMap<String, bool>,
9    length_keys: HashMap<String, usize>,
10    variant_keys: HashMap<String, u8>,
11    multi_disc_config: HashMap<String, HashMap<u8, String>>,
12    multi_disc_list: HashMap<String, Vec<u8>>,
13    pub discriminator: Option<u8>,
14    pub data: Option<T>,
15}
16
17impl Default for SerializerConfig {
18    fn default() -> Self {
19        Self::new(None::<()>)
20    }
21}
22
23impl<T: Clone> SerializerConfig<T> {
24    pub fn new(data: Option<T>) -> Self {
25        Self {
26            toggle_keys: HashMap::new(),
27            length_keys: HashMap::new(),
28            variant_keys: HashMap::new(),
29            multi_disc_config: HashMap::new(),
30            multi_disc_list: HashMap::new(),
31            discriminator: None,
32            data,
33        }
34    }
35
36    pub fn configure_multi_disc(&mut self, enum_name: &str, disc: u8, multi_by: &str) {
37        let entry = self
38            .multi_disc_config
39            .entry(enum_name.to_string())
40            .or_insert_with(HashMap::new);
41
42        entry.insert(disc, multi_by.to_string());
43    }
44
45    pub fn get_multi_disc_size(&self, enum_name: &str) -> usize {
46        self.get_toggled_multi_discs(enum_name).len()
47    }
48
49    pub fn get_next_multi_disc(&mut self, field: &str, enum_name: &str) -> Option<u8> {
50        let discs = self.get_toggled_multi_discs(enum_name);
51        let entry = self
52            .multi_disc_list
53            .entry(format!("{}.{}", field, enum_name))
54            .or_insert(discs);
55
56        entry.pop()
57    }
58
59    fn get_toggled_multi_discs(&self, enum_name: &str) -> Vec<u8> {
60        let mut discs = Vec::new();
61        if let Some(disc_map) = self.multi_disc_config.get(enum_name) {
62            for (disc, toggle) in disc_map.iter() {
63                if self.get_toggle(toggle).unwrap_or(false) {
64                    discs.push(*disc);
65                }
66            }
67        }
68        discs.sort();
69        discs.reverse();
70        discs
71    }
72
73    pub fn set_toggle(&mut self, key: &str, value: bool) {
74        self.toggle_keys.insert(key.to_string(), value);
75    }
76
77    pub fn set_length(&mut self, key: &str, value: usize) {
78        self.length_keys.insert(key.to_string(), value);
79    }
80
81    pub fn set_variant(&mut self, key: &str, value: u8) {
82        self.variant_keys.insert(key.to_string(), value);
83    }
84
85    pub fn get_toggle(&self, key: &str) -> Option<bool> {
86        if key.starts_with('!') {
87            let key = &key[1..];
88            return self.toggle_keys.get(key).map(|v| !*v);
89        }
90
91        self.toggle_keys.get(key).copied()
92    }
93
94    pub fn get_length(&self, key: &str) -> Option<usize> {
95        self.length_keys.get(key).copied()
96    }
97
98    pub fn get_variant(&self, key: &str) -> Option<u8> {
99        self.variant_keys.get(key).copied()
100            .or_else(|| self.toggle_keys.get(key).map(|t| if *t { 1 } else { 0 }))
101    }
102
103    pub fn reset(&mut self) {
104        self.discriminator = None;
105    }
106}