1use crate::{
2 AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element,
3 ecu_configuration::{
4 EcucAddInfoParamDef, EcucAnyReferenceDef, EcucBooleanParamDef, EcucChoiceReferenceDef, EcucDefinitionElement,
5 EcucEnumerationParamDef, EcucFloatParamDef, EcucForeignReferenceDef, EcucFunctionNameDef,
6 EcucInstanceReferenceDef, EcucIntegerParamDef, EcucLinkerSymbolDef, EcucMultilineStringParamDef,
7 EcucParameterDef, EcucReferenceDef, EcucStringParamDef, EcucUriReferenceDef,
8 },
9};
10use autosar_data::{Element, ElementName};
11
12pub trait AbstractEcucContainerDef: EcucDefinitionElement {}
16
17#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22pub struct EcucChoiceContainerDef(Element);
23abstraction_element!(EcucChoiceContainerDef, EcucChoiceContainerDef);
24impl IdentifiableAbstractionElement for EcucChoiceContainerDef {}
25impl EcucDefinitionElement for EcucChoiceContainerDef {}
26impl AbstractEcucContainerDef for EcucChoiceContainerDef {}
27
28impl EcucChoiceContainerDef {
29 pub(crate) fn new(name: &str, containers_elem: &Element) -> Result<Self, AutosarAbstractionError> {
30 let choice_container_def_elem =
31 containers_elem.create_named_sub_element(ElementName::EcucChoiceContainerDef, name)?;
32
33 Ok(Self(choice_container_def_elem))
34 }
35
36 pub fn create_param_conf_container_def(
38 &self,
39 name: &str,
40 ) -> Result<EcucParamConfContainerDef, AutosarAbstractionError> {
41 let containers_elem = self.element().get_or_create_sub_element(ElementName::Choices)?;
42 EcucParamConfContainerDef::new(name, &containers_elem)
43 }
44
45 pub fn choices(&self) -> impl Iterator<Item = EcucParamConfContainerDef> + Send + use<> {
47 self.element()
48 .get_sub_element(ElementName::Choices)
49 .into_iter()
50 .flat_map(|elem| elem.sub_elements())
51 .filter_map(|elem| EcucParamConfContainerDef::try_from(elem).ok())
52 }
53}
54
55#[derive(Debug, Clone, PartialEq, Eq, Hash)]
59pub struct EcucParamConfContainerDef(Element);
60abstraction_element!(EcucParamConfContainerDef, EcucParamConfContainerDef);
61impl IdentifiableAbstractionElement for EcucParamConfContainerDef {}
62impl EcucDefinitionElement for EcucParamConfContainerDef {}
63impl AbstractEcucContainerDef for EcucParamConfContainerDef {}
64
65impl EcucParamConfContainerDef {
66 pub(crate) fn new(name: &str, containers_elem: &Element) -> Result<Self, AutosarAbstractionError> {
67 let param_conf_container_def_elem =
68 containers_elem.create_named_sub_element(ElementName::EcucParamConfContainerDef, name)?;
69
70 Ok(Self(param_conf_container_def_elem))
71 }
72
73 pub fn create_choice_container_def(&self, name: &str) -> Result<EcucChoiceContainerDef, AutosarAbstractionError> {
75 let containers_elem = self.element().get_or_create_sub_element(ElementName::SubContainers)?;
76 EcucChoiceContainerDef::new(name, &containers_elem)
77 }
78
79 pub fn create_param_conf_container_def(
81 &self,
82 name: &str,
83 ) -> Result<EcucParamConfContainerDef, AutosarAbstractionError> {
84 let containers_elem = self.element().get_or_create_sub_element(ElementName::SubContainers)?;
85 EcucParamConfContainerDef::new(name, &containers_elem)
86 }
87
88 pub fn sub_containers(&self) -> impl Iterator<Item = EcucContainerDef> + Send + use<> {
90 self.element()
91 .get_sub_element(ElementName::SubContainers)
92 .into_iter()
93 .flat_map(|elem| elem.sub_elements())
94 .filter_map(|elem| EcucContainerDef::try_from(elem).ok())
95 }
96
97 pub fn create_add_info_param_def(
99 &self,
100 name: &str,
101 origin: &str,
102 ) -> Result<EcucAddInfoParamDef, AutosarAbstractionError> {
103 let parameters_elem = self.element().get_or_create_sub_element(ElementName::Parameters)?;
104 EcucAddInfoParamDef::new(name, ¶meters_elem, origin)
105 }
106
107 pub fn create_boolean_param_def(
109 &self,
110 name: &str,
111 origin: &str,
112 ) -> Result<EcucBooleanParamDef, AutosarAbstractionError> {
113 let parameters_elem = self.element().get_or_create_sub_element(ElementName::Parameters)?;
114 EcucBooleanParamDef::new(name, ¶meters_elem, origin)
115 }
116
117 pub fn create_enumeration_param_def(
119 &self,
120 name: &str,
121 origin: &str,
122 ) -> Result<EcucEnumerationParamDef, AutosarAbstractionError> {
123 let parameters_elem = self.element().get_or_create_sub_element(ElementName::Parameters)?;
124 EcucEnumerationParamDef::new(name, ¶meters_elem, origin)
125 }
126
127 pub fn create_float_param_def(
129 &self,
130 name: &str,
131 origin: &str,
132 ) -> Result<EcucFloatParamDef, AutosarAbstractionError> {
133 let parameters_elem = self.element().get_or_create_sub_element(ElementName::Parameters)?;
134 EcucFloatParamDef::new(name, ¶meters_elem, origin)
135 }
136
137 pub fn create_integer_param_def(
139 &self,
140 name: &str,
141 origin: &str,
142 ) -> Result<EcucIntegerParamDef, AutosarAbstractionError> {
143 let parameters_elem = self.element().get_or_create_sub_element(ElementName::Parameters)?;
144 EcucIntegerParamDef::new(name, ¶meters_elem, origin)
145 }
146
147 pub fn create_function_name_param_def(
149 &self,
150 name: &str,
151 origin: &str,
152 ) -> Result<EcucFunctionNameDef, AutosarAbstractionError> {
153 let parameters_elem = self.element().get_or_create_sub_element(ElementName::Parameters)?;
154 EcucFunctionNameDef::new(name, ¶meters_elem, origin)
155 }
156
157 pub fn create_linker_symbol_param_def(
159 &self,
160 name: &str,
161 origin: &str,
162 ) -> Result<EcucLinkerSymbolDef, AutosarAbstractionError> {
163 let parameters_elem = self.element().get_or_create_sub_element(ElementName::Parameters)?;
164 EcucLinkerSymbolDef::new(name, ¶meters_elem, origin)
165 }
166
167 pub fn create_multiline_string_param_def(
169 &self,
170 name: &str,
171 origin: &str,
172 ) -> Result<EcucMultilineStringParamDef, AutosarAbstractionError> {
173 let parameters_elem = self.element().get_or_create_sub_element(ElementName::Parameters)?;
174 EcucMultilineStringParamDef::new(name, ¶meters_elem, origin)
175 }
176
177 pub fn create_string_param_def(
179 &self,
180 name: &str,
181 origin: &str,
182 ) -> Result<EcucStringParamDef, AutosarAbstractionError> {
183 let parameters_elem = self.element().get_or_create_sub_element(ElementName::Parameters)?;
184 EcucStringParamDef::new(name, ¶meters_elem, origin)
185 }
186
187 pub fn parameters(&self) -> impl Iterator<Item = EcucParameterDef> + Send + use<> {
189 self.element()
190 .get_sub_element(ElementName::Parameters)
191 .into_iter()
192 .flat_map(|elem| elem.sub_elements())
193 .filter_map(|elem| EcucParameterDef::try_from(elem).ok())
194 }
195
196 pub fn create_foreign_reference_def(
198 &self,
199 name: &str,
200 origin: &str,
201 ) -> Result<EcucForeignReferenceDef, AutosarAbstractionError> {
202 let foreign_references_elem = self.element().get_or_create_sub_element(ElementName::References)?;
203 EcucForeignReferenceDef::new(name, &foreign_references_elem, origin)
204 }
205
206 pub fn create_instance_reference_def(
208 &self,
209 name: &str,
210 origin: &str,
211 ) -> Result<EcucInstanceReferenceDef, AutosarAbstractionError> {
212 let instance_references_elem = self.element().get_or_create_sub_element(ElementName::References)?;
213 EcucInstanceReferenceDef::new(name, &instance_references_elem, origin)
214 }
215
216 pub fn create_choice_reference_def(
218 &self,
219 name: &str,
220 origin: &str,
221 ) -> Result<EcucChoiceReferenceDef, AutosarAbstractionError> {
222 let choice_references_elem = self.element().get_or_create_sub_element(ElementName::References)?;
223 EcucChoiceReferenceDef::new(name, &choice_references_elem, origin)
224 }
225
226 pub fn create_reference_def(&self, name: &str, origin: &str) -> Result<EcucReferenceDef, AutosarAbstractionError> {
228 let references_elem = self.element().get_or_create_sub_element(ElementName::References)?;
229 EcucReferenceDef::new(name, &references_elem, origin)
230 }
231
232 pub fn create_uri_reference_def(
234 &self,
235 name: &str,
236 origin: &str,
237 ) -> Result<EcucUriReferenceDef, AutosarAbstractionError> {
238 let uri_references_elem = self.element().get_or_create_sub_element(ElementName::References)?;
239 EcucUriReferenceDef::new(name, &uri_references_elem, origin)
240 }
241
242 pub fn references(&self) -> impl Iterator<Item = EcucAnyReferenceDef> + Send + use<> {
244 self.element()
245 .get_sub_element(ElementName::References)
246 .into_iter()
247 .flat_map(|elem| elem.sub_elements())
248 .filter_map(|elem| EcucAnyReferenceDef::try_from(elem).ok())
249 }
250}
251
252#[derive(Debug, Clone, PartialEq, Eq, Hash)]
256pub enum EcucContainerDef {
257 Choice(EcucChoiceContainerDef),
259 ParamConf(EcucParamConfContainerDef),
261}
262
263impl AbstractionElement for EcucContainerDef {
264 fn element(&self) -> &Element {
265 match self {
266 EcucContainerDef::Choice(elem) => elem.element(),
267 EcucContainerDef::ParamConf(elem) => elem.element(),
268 }
269 }
270}
271
272impl TryFrom<Element> for EcucContainerDef {
273 type Error = AutosarAbstractionError;
274
275 fn try_from(element: Element) -> Result<Self, Self::Error> {
276 match element.element_name() {
277 ElementName::EcucChoiceContainerDef => Ok(EcucContainerDef::Choice(element.try_into()?)),
278 ElementName::EcucParamConfContainerDef => Ok(EcucContainerDef::ParamConf(element.try_into()?)),
279 _ => Err(AutosarAbstractionError::ConversionError {
280 element,
281 dest: "EcucContainerDef".to_string(),
282 }),
283 }
284 }
285}
286
287impl IdentifiableAbstractionElement for EcucContainerDef {}
288impl EcucDefinitionElement for EcucContainerDef {}
289impl AbstractEcucContainerDef for EcucContainerDef {}
290
291#[cfg(test)]
294mod test {
295 use crate::{AbstractionElement, AutosarModelAbstraction};
296 use autosar_data::AutosarVersion;
297
298 #[test]
299 fn container() {
300 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
301 let package = model.get_or_create_package("/pkg1").unwrap();
302 let ecuc_module = package.create_ecuc_module_def("ecuc_module").unwrap();
303 assert_eq!(ecuc_module.containers().count(), 0);
304
305 let choice_container = ecuc_module.create_choice_container_def("ChoiceContainer").unwrap();
306 assert_eq!(choice_container.choices().count(), 0);
307 choice_container
308 .create_param_conf_container_def("ParamConfContainerChoice1")
309 .unwrap();
310 choice_container
311 .create_param_conf_container_def("ParamConfContainerChoice2")
312 .unwrap();
313 assert_eq!(choice_container.choices().count(), 2);
314
315 let param_conf_container = ecuc_module
316 .create_param_conf_container_def("ParamConfContainer")
317 .unwrap();
318 assert_eq!(param_conf_container.sub_containers().count(), 0);
319 param_conf_container
320 .create_choice_container_def("ChoiceContainer")
321 .unwrap();
322 assert_eq!(param_conf_container.sub_containers().count(), 1);
323
324 assert_eq!(param_conf_container.parameters().count(), 0);
325 param_conf_container
326 .create_add_info_param_def("AddInfoParam", "origin")
327 .unwrap();
328 param_conf_container
329 .create_boolean_param_def("BooleanParam", "origin")
330 .unwrap();
331 param_conf_container
332 .create_enumeration_param_def("EnumerationParam", "origin")
333 .unwrap();
334 param_conf_container
335 .create_float_param_def("FloatParam", "origin")
336 .unwrap();
337 param_conf_container
338 .create_integer_param_def("IntegerParam", "origin")
339 .unwrap();
340 param_conf_container
341 .create_function_name_param_def("FunctionName", "origin")
342 .unwrap();
343 param_conf_container
344 .create_linker_symbol_param_def("LinkerSymbol", "origin")
345 .unwrap();
346 param_conf_container
347 .create_multiline_string_param_def("MultilineStringParam", "origin")
348 .unwrap();
349 param_conf_container
350 .create_string_param_def("StringParam", "origin")
351 .unwrap();
352 assert_eq!(param_conf_container.parameters().count(), 9);
353
354 assert_eq!(param_conf_container.references().count(), 0);
355 param_conf_container
356 .create_foreign_reference_def("ForeignReference", "origin")
357 .unwrap();
358 param_conf_container
359 .create_instance_reference_def("InstanceReference", "origin")
360 .unwrap();
361 param_conf_container
362 .create_choice_reference_def("ChoiceReference", "origin")
363 .unwrap();
364 param_conf_container
365 .create_reference_def("Reference", "origin")
366 .unwrap();
367 param_conf_container
368 .create_uri_reference_def("UriReference", "origin")
369 .unwrap();
370 assert_eq!(param_conf_container.references().count(), 5);
371
372 assert_eq!(ecuc_module.containers().count(), 2);
373 let mut containers_iter = ecuc_module.containers();
374 assert_eq!(containers_iter.next().unwrap().element(), choice_container.element());
375 assert_eq!(
376 containers_iter.next().unwrap().element(),
377 param_conf_container.element()
378 );
379 }
380}