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 bits: u8,
14    pub pos: usize,
15    pub discriminator: Option<u8>,
16    pub data: Option<T>,
17}
18
19impl Default for SerializerConfig {
20    fn default() -> Self {
21        Self::new(None::<()>)
22    }
23}
24
25impl<T: Clone> SerializerConfig<T> {
26    pub fn new(data: Option<T>) -> Self {
27        Self {
28            toggle_keys: HashMap::new(),
29            length_keys: HashMap::new(),
30            variant_keys: HashMap::new(),
31            multi_disc_config: HashMap::new(),
32            multi_disc_list: HashMap::new(),
33            bits: 0,
34            pos: 0,
35            discriminator: None,
36            data,
37        }
38    }
39
40    pub fn configure_multi_disc(&mut self, enum_name: &str, disc: u8, multi_by: &str) {
41        let entry = self
42            .multi_disc_config
43            .entry(enum_name.to_string())
44            .or_insert_with(HashMap::new);
45
46        entry.insert(disc, multi_by.to_string());
47    }
48
49    pub fn get_multi_disc_size(&self, enum_name: &str) -> usize {
50        self.get_toggled_multi_discs(enum_name).len()
51    }
52
53    pub fn get_next_multi_disc(&mut self, field: &str, enum_name: &str) -> Option<u8> {
54        let discs = self.get_toggled_multi_discs(enum_name);
55        let entry = self
56            .multi_disc_list
57            .entry(format!("{}.{}", field, enum_name))
58            .or_insert(discs);
59
60        entry.pop()
61    }
62
63    fn get_toggled_multi_discs(&self, enum_name: &str) -> Vec<u8> {
64        let mut discs = Vec::new();
65        if let Some(disc_map) = self.multi_disc_config.get(enum_name) {
66            for (disc, toggle) in disc_map.iter() {
67                if self.get_toggle(toggle).unwrap_or(false) {
68                    discs.push(*disc);
69                }
70            }
71        }
72        discs.sort();
73        discs.reverse();
74        discs
75    }
76
77    pub fn next_reset_bits_pos(&self) -> usize {
78        if self.bits == 0 {
79            self.pos
80        } else {
81            self.pos + 1
82        }
83    }
84
85    pub fn reset_bits(&mut self, is_read: bool) {
86        if self.bits != 0 && is_read {
87            self.pos += 1;
88        }
89        self.bits = 0;
90    }
91
92    pub fn set_toggle(&mut self, key: &str, value: bool) {
93        self.toggle_keys.insert(key.to_string(), value);
94    }
95
96    pub fn set_length(&mut self, key: &str, value: usize) {
97        self.length_keys.insert(key.to_string(), value);
98    }
99
100    pub fn set_variant(&mut self, key: &str, value: u8) {
101        self.variant_keys.insert(key.to_string(), value);
102    }
103
104    pub fn get_toggle(&self, key: &str) -> Option<bool> {
105        if key.starts_with('!') {
106            let key = &key[1..];
107            return self.toggle_keys.get(key).map(|v| !*v);
108        }
109
110        self.toggle_keys.get(key).copied()
111    }
112
113    pub fn get_length(&self, key: &str) -> Option<usize> {
114        self.length_keys.get(key).copied()
115    }
116
117    pub fn get_variant(&self, key: &str) -> Option<u8> {
118        self.variant_keys.get(key).copied()
119    }
120
121    pub fn reset(&mut self) {
122        self.bits = 0;
123        self.pos = 0;
124        self.discriminator = None;
125    }
126}