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     /// Variant toggle setting: key_name=1|2|3|4
86    pub fn get_variant_toggle(&mut self, setting: &str) -> Option<bool> {
87        let mut parts = setting.split("=");
88        let key = parts.next().expect("key=discriminators");
89        let discs: Vec<u8> = parts.next().expect("key=discriminators").split("|")
90            .map(|v| v.parse().expect("a valid u8")).collect();
91
92        let variant = self.get_variant(key)?;
93        Some(discs.contains(&variant))
94    }
95
96    pub fn get_toggle(&self, key: &str) -> Option<bool> {
97        if key.starts_with('!') {
98            let key = &key[1..];
99            return self.toggle_keys.get(key).map(|v| !*v);
100        }
101
102        self.toggle_keys.get(key).copied()
103    }
104
105    pub fn get_length(&self, key: &str) -> Option<usize> {
106        self.length_keys.get(key).copied()
107    }
108
109    pub fn get_variant(&self, key: &str) -> Option<u8> {
110        self.variant_keys
111            .get(key)
112            .copied()
113            .or_else(|| self.toggle_keys.get(key).map(|t| if *t { 1 } else { 0 }))
114    }
115
116    pub fn reset(&mut self) {
117        self.discriminator = None;
118    }
119}