1use crate::datagram::datagram::Datagram;
24use crate::dcatomic::DCAtomicField;
25use crate::dckeyword::{DCKeywordList, IdentifyKeyword};
26use crate::dclass::DClass;
27use crate::dcmolecular::DCMolecularField;
28use crate::dconfig::*;
29use crate::dcstruct::DCStruct;
30use crate::dctype::DCTypeDefinition;
31use crate::globals;
32use crate::hashgen::*;
33
34#[derive(Debug)]
50pub enum ClassField<'dc> {
51 Field(DCField<'dc>),
52 Atomic(DCAtomicField<'dc>),
53 Molecular(DCMolecularField<'dc>),
54}
55
56#[derive(Debug)]
59pub enum StructField<'dc> {
60 Field(DCField<'dc>),
61 Molecular(DCMolecularField<'dc>),
62}
63
64#[derive(Debug)]
68pub enum FieldParent<'dc> {
69 DClass(&'dc DClass<'dc>),
70 Strukt(&'dc DCStruct<'dc>), }
72
73macro_rules! has_keyword {
75 ($self:ident, $i:literal) => {
76 $self
77 .keyword_list
78 .has_keyword(IdentifyKeyword::ByName($i.to_owned()))
79 };
80}
81
82#[derive(Debug)]
86pub struct DCField<'dc> {
87 keyword_list: DCKeywordList<'dc>,
88 parent_element: FieldParent<'dc>,
89 field_name: String,
90 field_id: globals::FieldId,
91 field_type: Option<DCTypeDefinition>,
92 default_value_stale: bool,
93 has_default_value: bool,
94 default_value: Vec<u8>, bogus_field: bool,
96}
97
98impl std::fmt::Display for DCField<'_> {
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 writeln!(f, "TODO")
101 }
102}
103
104impl DCFileConfigAccessor for DCField<'_> {
105 fn get_dc_config(&self) -> &DCFileConfig {
106 match self.parent_element {
107 FieldParent::DClass(dc) => dc.get_dc_config(),
108 FieldParent::Strukt(s) => s.get_dc_config(),
109 }
110 }
111}
112
113impl LegacyDCHash for DCField<'_> {
114 fn generate_hash(&self, hashgen: &mut DCHashGenerator) {
115 self.keyword_list.generate_hash(hashgen);
116 self.field_type.clone().unwrap().generate_hash(hashgen);
117
118 hashgen.add_string(self.field_name.clone());
124
125 if self.get_dc_config().dc_multiple_inheritance {
129 hashgen.add_int(i32::from(self.field_id));
130 }
131 }
132}
133
134impl<'dc> DCField<'dc> {
135 #[inline(always)]
136 pub fn get_field_id(&self) -> globals::FieldId {
137 self.field_id
138 }
139
140 #[inline(always)]
141 pub fn get_field_name(&self) -> String {
142 self.field_name.clone()
143 }
144
145 pub fn get_dclass(&self) -> &'dc DClass {
149 match self.parent_element {
150 FieldParent::DClass(dclass_ref) => dclass_ref,
151 FieldParent::Strukt(_) => panic!("Field parent is not a DClass."),
152 }
153 }
154
155 #[inline(always)]
156 pub fn set_field_id(&mut self, id: globals::FieldId) {
157 self.field_id = id
158 }
159
160 #[inline(always)]
161 pub fn set_field_name(&mut self, name: String) {
162 self.field_name = name
163 }
164
165 pub fn set_field_type(&mut self, dtype: DCTypeDefinition) {
166 self.field_type = Some(dtype);
167 self.has_default_value = false;
168 self.default_value = vec![];
169 }
170
171 pub fn set_field_keyword_list(&mut self, kw_list: DCKeywordList<'dc>) {
172 self.keyword_list = kw_list;
173 }
174
175 pub fn set_default_value(&mut self, value: Vec<u8>) {
176 self.default_value = value;
177 self.has_default_value = true;
178 self.default_value_stale = false;
179 }
180
181 #[inline(always)]
182 pub fn set_bogus_field(&mut self, is_bogus: bool) {
183 self.bogus_field = is_bogus
184 }
185
186 #[inline(always)]
187 pub fn has_default_value(&self) -> bool {
188 self.has_default_value
189 }
190
191 pub fn validate_ranges(&self, _packed_data: &Datagram) -> bool {
192 todo!()
193 }
194
195 pub fn format_packed_data(
198 &self,
199 f: &mut std::fmt::Formatter<'_>,
200 _data: &[u8],
201 _show_field_names: bool,
202 ) -> std::fmt::Result {
203 f.write_str("TODO") }
205
206 #[inline(always)]
207 pub fn is_bogus_field(&self) -> bool {
208 self.bogus_field
209 }
210
211 #[inline(always)]
212 pub fn is_required(&self) -> bool {
213 has_keyword!(self, "required")
214 }
215
216 #[inline(always)]
217 pub fn is_broadcast(&self) -> bool {
218 has_keyword!(self, "broadcast")
219 }
220
221 #[inline(always)]
222 pub fn is_ram(&self) -> bool {
223 has_keyword!(self, "ram")
224 }
225
226 #[inline(always)]
227 pub fn is_db(&self) -> bool {
228 has_keyword!(self, "db")
229 }
230
231 #[inline(always)]
232 pub fn is_clsend(&self) -> bool {
233 has_keyword!(self, "clsend")
234 }
235
236 #[inline(always)]
237 pub fn is_clrecv(&self) -> bool {
238 has_keyword!(self, "clrecv")
239 }
240
241 #[inline(always)]
242 pub fn is_ownsend(&self) -> bool {
243 has_keyword!(self, "ownsend")
244 }
245
246 #[inline(always)]
247 pub fn is_ownrecv(&self) -> bool {
248 has_keyword!(self, "ownrecv")
249 }
250
251 #[inline(always)]
252 pub fn is_airecv(&self) -> bool {
253 has_keyword!(self, "airecv")
254 }
255
256 fn _refresh_default_value(&self) {
257 todo!()
258 }
259}