autosar_data_abstraction/ecu_configuration/values/
mod.rs1use crate::{
2 AbstractionElement, ArPackage, AutosarAbstractionError, IdentifiableAbstractionElement, System,
3 abstraction_element,
4 ecu_configuration::{
5 AbstractEcucContainerDef, AbstractEcucReferenceDef, EcucAddInfoParamDef, EcucContainerDef,
6 EcucInstanceReferenceDef, EcucModuleDef,
7 },
8};
9use autosar_data::{Element, ElementName};
10
11mod parameter;
12mod reference;
13
14pub use parameter::*;
15pub use reference::*;
16
17use super::EcucParamDef;
18
19#[derive(Debug, Clone, PartialEq, Eq, Hash)]
23pub struct EcucValueCollection(Element);
24abstraction_element!(EcucValueCollection, EcucValueCollection);
25impl IdentifiableAbstractionElement for EcucValueCollection {}
26
27impl EcucValueCollection {
28 pub(crate) fn new(name: &str, package: &ArPackage) -> Result<Self, AutosarAbstractionError> {
29 let elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
30 let ecuc_value_collection_elem = elements.create_named_sub_element(ElementName::EcucValueCollection, name)?;
31
32 Ok(Self(ecuc_value_collection_elem))
33 }
34
35 pub fn add_module_configuration(
37 &self,
38 module_configuration: &EcucModuleConfigurationValues,
39 ) -> Result<(), AutosarAbstractionError> {
40 let ecuc_values_elem = self.element().get_or_create_sub_element(ElementName::EcucValues)?;
41 ecuc_values_elem
42 .create_sub_element(ElementName::EcucModuleConfigurationValuesRefConditional)?
43 .create_sub_element(ElementName::EcucModuleConfigurationValuesRef)?
44 .set_reference_target(module_configuration.element())?;
45
46 Ok(())
47 }
48
49 pub fn module_configurations(&self) -> impl Iterator<Item = EcucModuleConfigurationValues> + Send + use<> {
51 self.element()
52 .get_sub_element(ElementName::EcucValues)
53 .into_iter()
54 .flat_map(|values_elem| values_elem.sub_elements())
55 .filter_map(|ref_cond| {
56 ref_cond
57 .get_sub_element(ElementName::EcucModuleConfigurationValuesRef)
58 .and_then(|module_config_ref| module_config_ref.get_reference_target().ok())
59 .and_then(|module_elem| EcucModuleConfigurationValues::try_from(module_elem).ok())
60 })
61 }
62
63 pub fn set_ecu_extract_reference(&self, system: &System) -> Result<(), AutosarAbstractionError> {
65 self.element()
66 .get_or_create_sub_element(ElementName::EcuExtractRef)?
67 .set_reference_target(system.element())?;
68
69 Ok(())
70 }
71
72 #[must_use]
74 pub fn ecu_extract_reference(&self) -> Option<System> {
75 let system_elem = self
76 .element()
77 .get_sub_element(ElementName::EcuExtractRef)?
78 .get_reference_target()
79 .ok()?;
80 System::try_from(system_elem).ok()
81 }
82}
83
84#[derive(Debug, Clone, PartialEq, Eq, Hash)]
88pub struct EcucModuleConfigurationValues(Element);
89abstraction_element!(EcucModuleConfigurationValues, EcucModuleConfigurationValues);
90impl IdentifiableAbstractionElement for EcucModuleConfigurationValues {}
91
92impl EcucModuleConfigurationValues {
93 pub(crate) fn new(
94 name: &str,
95 package: &ArPackage,
96 module_definition: &EcucModuleDef,
97 ) -> Result<Self, AutosarAbstractionError> {
98 let elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
99 let module_config_elem = elements.create_named_sub_element(ElementName::EcucModuleConfigurationValues, name)?;
100
101 let module_config = Self(module_config_elem);
102 module_config.set_definition(module_definition)?;
103
104 Ok(module_config)
105 }
106
107 pub fn set_definition(&self, module_definition: &EcucModuleDef) -> Result<(), AutosarAbstractionError> {
109 self.element()
110 .get_or_create_sub_element(ElementName::DefinitionRef)?
111 .set_reference_target(module_definition.element())?;
112
113 Ok(())
114 }
115
116 #[must_use]
121 pub fn definition(&self) -> Option<EcucModuleDef> {
122 let definition_elem = self
123 .element()
124 .get_sub_element(ElementName::DefinitionRef)?
125 .get_reference_target()
126 .ok()?;
127 EcucModuleDef::try_from(definition_elem).ok()
128 }
129
130 #[must_use]
135 pub fn definition_ref(&self) -> Option<String> {
136 self.element()
137 .get_sub_element(ElementName::DefinitionRef)?
138 .character_data()?
139 .string_value()
140 }
141
142 pub fn create_container_value<T: AbstractEcucContainerDef>(
144 &self,
145 name: &str,
146 definition: &T,
147 ) -> Result<EcucContainerValue, AutosarAbstractionError> {
148 let containers_elem = self.element().get_or_create_sub_element(ElementName::Containers)?;
149 EcucContainerValue::new(name, &containers_elem, definition)
150 }
151
152 pub fn container_values(&self) -> impl Iterator<Item = EcucContainerValue> + Send + use<> {
154 self.element()
155 .get_sub_element(ElementName::Containers)
156 .into_iter()
157 .flat_map(|containers_elem| containers_elem.sub_elements())
158 .filter_map(|container_elem| EcucContainerValue::try_from(container_elem).ok())
159 }
160}
161
162#[derive(Debug, Clone, PartialEq, Eq, Hash)]
166pub struct EcucContainerValue(Element);
167abstraction_element!(EcucContainerValue, EcucContainerValue);
168impl IdentifiableAbstractionElement for EcucContainerValue {}
169
170impl EcucContainerValue {
171 pub(crate) fn new<T: AbstractEcucContainerDef>(
172 name: &str,
173 parent: &Element,
174 definition: &T,
175 ) -> Result<Self, AutosarAbstractionError> {
176 let container_value_elem = parent.create_named_sub_element(ElementName::EcucContainerValue, name)?;
177 let container_value = Self(container_value_elem);
178
179 container_value.set_definition(definition)?;
180
181 Ok(container_value)
182 }
183
184 pub fn set_definition<T: AbstractEcucContainerDef>(&self, definition: &T) -> Result<(), AutosarAbstractionError> {
186 self.element()
187 .get_or_create_sub_element(ElementName::DefinitionRef)?
188 .set_reference_target(definition.element())?;
189
190 Ok(())
191 }
192
193 #[must_use]
198 pub fn definition(&self) -> Option<EcucContainerDef> {
199 let definition_elem = self
200 .element()
201 .get_sub_element(ElementName::DefinitionRef)?
202 .get_reference_target()
203 .ok()?;
204 EcucContainerDef::try_from(definition_elem).ok()
205 }
206
207 #[must_use]
212 pub fn definition_ref(&self) -> Option<String> {
213 self.element()
214 .get_sub_element(ElementName::DefinitionRef)?
215 .character_data()?
216 .string_value()
217 }
218
219 pub fn create_sub_container<T: AbstractEcucContainerDef>(
221 &self,
222 name: &str,
223 definition: &T,
224 ) -> Result<EcucContainerValue, AutosarAbstractionError> {
225 let sub_containers_elem = self.element().get_or_create_sub_element(ElementName::SubContainers)?;
226 EcucContainerValue::new(name, &sub_containers_elem, definition)
227 }
228
229 pub fn sub_containers(&self) -> impl Iterator<Item = EcucContainerValue> + Send + use<> {
231 self.element()
232 .get_sub_element(ElementName::SubContainers)
233 .into_iter()
234 .flat_map(|sub_containers| sub_containers.sub_elements())
235 .filter_map(|elem| EcucContainerValue::try_from(elem).ok())
236 }
237
238 pub fn set_index(&self, index: Option<u64>) -> Result<(), AutosarAbstractionError> {
243 if let Some(index) = index {
244 self.element()
245 .get_or_create_sub_element(ElementName::Index)?
246 .set_character_data(index)?;
247 } else {
248 self.element().remove_sub_element_kind(ElementName::Index)?;
249 }
250
251 Ok(())
252 }
253
254 #[must_use]
259 pub fn index(&self) -> Option<u64> {
260 self.element()
261 .get_sub_element(ElementName::Index)?
262 .character_data()?
263 .parse_integer()
264 }
265 pub fn create_numerical_param_value<T: EcucParamDef>(
267 &self,
268 definition: &T,
269 value: &str,
270 ) -> Result<EcucNumericalParamValue, AutosarAbstractionError> {
271 let parameter_values_elem = self.element().get_or_create_sub_element(ElementName::ParameterValues)?;
272 EcucNumericalParamValue::new(¶meter_values_elem, definition, value)
273 }
274
275 pub fn create_textual_param_value<T: EcucParamDef>(
277 &self,
278 definition: &T,
279 value: &str,
280 ) -> Result<EcucTextualParamValue, AutosarAbstractionError> {
281 let parameter_values_elem = self.element().get_or_create_sub_element(ElementName::ParameterValues)?;
282 EcucTextualParamValue::new(¶meter_values_elem, definition, value)
283 }
284
285 pub fn create_add_info_param_value(
287 &self,
288 definition: &EcucAddInfoParamDef,
289 ) -> Result<EcucAddInfoParamValue, AutosarAbstractionError> {
290 let parameter_values_elem = self.element().get_or_create_sub_element(ElementName::ParameterValues)?;
291 EcucAddInfoParamValue::new(¶meter_values_elem, definition)
292 }
293
294 pub fn parameter_values(&self) -> impl Iterator<Item = EcucParameterValue> + Send + use<> {
296 self.element()
297 .get_sub_element(ElementName::ParameterValues)
298 .into_iter()
299 .flat_map(|param_values_elem| param_values_elem.sub_elements())
300 .filter_map(|param_elem| EcucParameterValue::try_from(param_elem).ok())
301 }
302
303 pub fn create_instance_reference(
305 &self,
306 definition: &EcucInstanceReferenceDef,
307 target_context: &[&Element],
308 target: &Element,
309 ) -> Result<EcucInstanceReferenceValue, AutosarAbstractionError> {
310 let reference_values_elem = self.element().get_or_create_sub_element(ElementName::ReferenceValues)?;
311 EcucInstanceReferenceValue::new(&reference_values_elem, definition, target_context, target)
312 }
313
314 pub fn create_reference_value<T: AbstractEcucReferenceDef>(
316 &self,
317 definition: &T,
318 target: &Element,
319 ) -> Result<EcucReferenceValue, AutosarAbstractionError> {
320 let reference_values_elem = self.element().get_or_create_sub_element(ElementName::ReferenceValues)?;
321 EcucReferenceValue::new(&reference_values_elem, definition, target)
322 }
323
324 pub fn reference_values(&self) -> impl Iterator<Item = EcucAnyReferenceValue> + Send + use<> {
326 self.element()
327 .get_sub_element(ElementName::ReferenceValues)
328 .into_iter()
329 .flat_map(|reference_values_elem| reference_values_elem.sub_elements())
330 .filter_map(|reference_elem| EcucAnyReferenceValue::try_from(reference_elem).ok())
331 }
332}
333
334#[cfg(test)]
337mod test {
338 use crate::{AbstractionElement, AutosarModelAbstraction, system};
339 use autosar_data::{AutosarVersion, ElementName};
340
341 #[test]
342 fn test_ecu_configuration_values() {
343 let definition_model = AutosarModelAbstraction::create("definition.arxml", AutosarVersion::LATEST);
344 let def_package = definition_model.get_or_create_package("/def_package").unwrap();
345
346 let values_model = AutosarModelAbstraction::create("values.arxml", AutosarVersion::LATEST);
347 let val_package = values_model.get_or_create_package("/val_package").unwrap();
348
349 let module_def = def_package.create_ecuc_module_def("ModuleDef").unwrap();
351 let container_def = module_def.create_param_conf_container_def("ContainerDef").unwrap();
352
353 let ecuc_value_collection = val_package.create_ecuc_value_collection("EcucValues").unwrap();
355 assert_eq!(ecuc_value_collection.ecu_extract_reference(), None);
356 let system = val_package
357 .create_system("System", system::SystemCategory::EcuExtract)
358 .unwrap();
359 ecuc_value_collection.set_ecu_extract_reference(&system).unwrap();
360 assert_eq!(ecuc_value_collection.ecu_extract_reference().unwrap(), system);
361 assert_eq!(ecuc_value_collection.module_configurations().count(), 0);
362
363 let ecuc_config_values = val_package
364 .create_ecuc_module_configuration_values("Module", &module_def)
365 .unwrap();
366 ecuc_value_collection
367 .add_module_configuration(&ecuc_config_values)
368 .unwrap();
369 assert_eq!(ecuc_value_collection.module_configurations().count(), 1);
370 assert_eq!(ecuc_config_values.definition_ref(), module_def.element().path().ok());
371 assert!(ecuc_config_values.definition().is_none());
373
374 let container_values = ecuc_config_values
375 .create_container_value("Container", &container_def)
376 .unwrap();
377 assert_eq!(container_values.definition_ref(), container_def.element().path().ok());
378 assert!(container_values.definition().is_none());
379 assert_eq!(container_values.index(), None);
380 container_values.set_index(Some(0)).unwrap();
381 assert_eq!(container_values.index(), Some(0));
382 assert_eq!(ecuc_config_values.container_values().count(), 1);
383
384 let sub_container_value = container_values
385 .create_sub_container("SubContainer", &container_def)
386 .unwrap();
387 assert_eq!(
388 sub_container_value.definition_ref(),
389 container_def.element().path().ok()
390 );
391 assert_eq!(container_values.sub_containers().count(), 1);
392
393 values_model
396 .root_element()
397 .get_sub_element(ElementName::ArPackages)
398 .unwrap()
399 .create_copied_sub_element(def_package.element())
400 .unwrap();
401 }
403}