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_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}