1use crate::dcfield::DCField;
23use crate::hashgen::*;
24use std::collections::HashMap;
25
26#[derive(Debug)]
28pub struct SwitchCase {
29 breaks: bool,
34 value: Vec<u8>,
36 fields: Vec<DCField>,
37}
38
39impl std::fmt::Display for SwitchCase {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 if self.is_default() {
42 writeln!(f, "default:")?;
43 } else {
44 write!(f, "case ")?;
45 writeln!(f, ":")?;
47 }
48
49 for field in &self.fields {
50 f.write_str(&field.to_string())?;
51 }
52 if self.breaks {
53 writeln!(f, "break;")?;
54 }
55 Ok(())
56 }
57}
58
59impl LegacyDCHash for SwitchCase {
60 fn generate_hash(&self, hashgen: &mut DCHashGenerator) {
61 if !self.is_default() {
62 hashgen.add_blob(self.value.clone());
63 }
64
65 hashgen.add_int(self.get_num_fields() as i32);
66
67 for field in &self.fields {
68 field.generate_hash(hashgen);
69 }
70 }
71}
72
73impl<'dc> SwitchCase {
74 pub fn is_default(&self) -> bool {
76 self.value.is_empty()
77 }
78
79 pub fn get_num_fields(&self) -> usize {
81 self.fields.len()
82 }
83
84 pub fn get_field(&self, index: usize) -> Option<&DCField> {
85 self.fields.get(index)
86 }
87
88 pub fn get_field_by_name(&self, _name: String) -> Option<&DCField> {
89 todo!()
90 }
91}
92
93#[derive(Debug)]
97pub struct DCSwitch {
98 name: Option<String>,
99 key: DCField,
100 cases: Vec<SwitchCase>,
101 default_case: Option<SwitchCase>,
102 cases_by_value: HashMap<Vec<u8>, usize>,
103}
104
105impl std::fmt::Display for DCSwitch {
106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107 write!(f, "switch")?;
108
109 if let Some(name) = &self.name {
110 write!(f, " {}", name)?;
111 }
112 write!(f, " (")?;
113 f.write_str(&self.key.to_string())?;
114
115 writeln!(f, ") {{")?;
116
117 for case in &self.cases {
118 f.write_str(&case.to_string())?;
119 }
120 writeln!(f, "}};")
121 }
122}
123
124impl LegacyDCHash for DCSwitch {
125 fn generate_hash(&self, hashgen: &mut DCHashGenerator) {
126 if let Some(name) = self.get_name() {
127 hashgen.add_string(name)
128 }
129
130 self.key.generate_hash(hashgen);
131
132 hashgen.add_int(self.get_num_cases() as i32);
133
134 for case in &self.cases {
135 case.generate_hash(hashgen);
136 }
137
138 if let Some(default) = &self.default_case {
139 default.generate_hash(hashgen);
140 }
141 }
142}
143
144impl DCSwitch {
145 #[inline(always)]
147 pub fn get_name(&self) -> Option<String> {
148 self.name.clone()
149 }
150
151 #[inline(always)]
156 pub fn get_key_parameter(&self) -> &DCField {
157 &self.key
158 }
159
160 #[inline(always)]
164 pub fn get_num_cases(&self) -> usize {
165 self.cases.len()
166 }
167
168 pub fn get_case(&self, index: usize) -> Option<&SwitchCase> {
170 self.cases.get(index)
171 }
172
173 pub fn get_default_case(&self) -> Option<&SwitchCase> {
177 self.default_case.as_ref()
178 }
179
180 pub fn get_case_index_by_value(&self, value: Vec<u8>) -> Option<usize> {
184 self.cases_by_value.get(&value).copied()
185 }
186
187 pub fn apply_switch(&self, _value: Vec<u8>, _length: usize) {}
189}