1use crate::dcfield::DCField;
23use crate::hashgen::*;
24use std::collections::HashMap;
25
26#[derive(Debug)]
28pub struct SwitchCase<'dc> {
29 switch: &'dc DCSwitch<'dc>,
30 breaks: bool,
35 value: Vec<u8>,
37 fields: Vec<DCField<'dc>>,
38}
39
40impl std::fmt::Display for SwitchCase<'_> {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 if self.is_default() {
43 writeln!(f, "default:")?;
44 } else {
45 write!(f, "case ")?;
46 self.switch.key.format_packed_data(f, &self.value, false)?;
47 writeln!(f, ":")?;
48 }
49
50 for field in &self.fields {
51 f.write_str(&field.to_string())?;
52 }
53 if self.breaks {
54 writeln!(f, "break;")?;
55 }
56 Ok(())
57 }
58}
59
60impl LegacyDCHash for SwitchCase<'_> {
61 fn generate_hash(&self, hashgen: &mut DCHashGenerator) {
62 if !self.is_default() {
63 hashgen.add_blob(self.value.clone());
64 }
65
66 hashgen.add_int(self.get_num_fields() as i32);
67
68 for field in &self.fields {
69 field.generate_hash(hashgen);
70 }
71 }
72}
73
74impl<'dc> SwitchCase<'dc> {
75 pub fn is_default(&self) -> bool {
77 self.value.is_empty()
78 }
79
80 pub fn get_num_fields(&self) -> usize {
82 self.fields.len()
83 }
84
85 pub fn get_field(&self, index: usize) -> Option<&'dc DCField> {
86 self.fields.get(index)
87 }
88
89 pub fn get_field_by_name(&self, _name: String) -> Option<&'dc DCField> {
90 todo!()
91 }
92}
93
94#[derive(Debug)]
98pub struct DCSwitch<'dc> {
99 name: Option<String>,
100 key: DCField<'dc>,
101 cases: Vec<SwitchCase<'dc>>,
102 default_case: Option<SwitchCase<'dc>>,
103 case_fields: Vec<&'dc DCField<'dc>>,
104 cases_by_value: HashMap<Vec<u8>, usize>,
105}
106
107impl From<interim::DCSwitch> for DCSwitch<'_> {
108 fn from(value: interim::DCSwitch) -> Self {
109 Self {
110 name: value.name,
111 key: todo!(),
112 cases: vec![],
113 default_case: None,
114 case_fields: vec![],
115 cases_by_value: HashMap::default(),
116 }
117 }
118}
119
120impl std::fmt::Display for DCSwitch<'_> {
121 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122 write!(f, "switch")?;
123
124 if let Some(name) = &self.name {
125 write!(f, " {}", name)?;
126 }
127 write!(f, " (")?;
128 f.write_str(&self.key.to_string())?;
129
130 writeln!(f, ") {{")?;
131
132 for case in &self.cases {
133 f.write_str(&case.to_string())?;
134 }
135 writeln!(f, "}};")
136 }
137}
138
139impl LegacyDCHash for DCSwitch<'_> {
140 fn generate_hash(&self, hashgen: &mut DCHashGenerator) {
141 if let Some(name) = self.get_name() {
142 hashgen.add_string(name)
143 }
144
145 self.key.generate_hash(hashgen);
146
147 hashgen.add_int(self.get_num_cases() as i32);
148
149 for case in &self.cases {
150 case.generate_hash(hashgen);
151 }
152
153 if let Some(default) = &self.default_case {
154 default.generate_hash(hashgen);
155 }
156 }
157}
158
159impl<'dc> DCSwitch<'dc> {
160 #[inline(always)]
162 pub fn get_name(&self) -> Option<String> {
163 self.name.clone()
164 }
165
166 #[inline(always)]
171 pub fn get_key_parameter(&self) -> &'dc DCField {
172 &self.key
173 }
174
175 #[inline(always)]
179 pub fn get_num_cases(&self) -> usize {
180 self.cases.len()
181 }
182
183 pub fn get_case(&self, index: usize) -> Option<&'dc SwitchCase> {
185 self.cases.get(index)
186 }
187
188 pub fn get_default_case(&self) -> Option<&'dc SwitchCase> {
192 self.default_case.as_ref()
193 }
194
195 pub fn get_case_index_by_value(&self, value: Vec<u8>) -> Option<usize> {
199 self.cases_by_value.get(&value).copied()
200 }
201
202 pub fn apply_switch(&self, _value: Vec<u8>, _length: usize) {}
204}
205
206pub(crate) mod interim {
209 #[derive(Debug)]
210 pub struct SwitchCase {
211 pub breaks: bool,
212 pub value: Vec<u8>,
213 }
214
215 impl SwitchCase {
216 fn add_case_field(&mut self) {}
217 }
218
219 #[derive(Debug)]
220 pub struct DCSwitch {
221 pub name: Option<String>,
222 pub key_parameter: u8, }
224
225 impl DCSwitch {
226 fn add_case(&mut self) {}
227 }
228}