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 println!("Setting toggle key {} to {}", key, value);
94 self.toggle_keys.insert(key.to_string(), value);
95 }
96
97 pub fn set_length(&mut self, key: &str, value: usize) {
98 self.length_keys.insert(key.to_string(), value);
99 }
100
101 pub fn set_variant(&mut self, key: &str, value: u8) {
102 self.variant_keys.insert(key.to_string(), value);
103 }
104
105 pub fn get_toggle(&self, key: &str) -> Option<bool> {
106 if key.starts_with('!') {
107 let key = &key[1..];
108 return self.toggle_keys.get(key).map(|v| !*v);
109 }
110
111 self.toggle_keys.get(key).copied()
112 }
113
114 pub fn get_length(&self, key: &str) -> Option<usize> {
115 self.length_keys.get(key).copied()
116 }
117
118 pub fn get_variant(&self, key: &str) -> Option<u8> {
119 self.variant_keys.get(key).copied()
120 }
121
122 pub fn reset(&mut self) {
123 self.bits = 0;
124 self.pos = 0;
125 self.discriminator = None;
126 }
127}