autosar_data_abstraction/ecu_configuration/values/
reference.rs1use crate::ecu_configuration::{AbstractEcucReferenceDef, EcucAnyReferenceDef, EcucInstanceReferenceDef};
2use crate::{AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element};
3use autosar_data::{Element, ElementName};
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9pub struct EcucInstanceReferenceValue(Element);
10abstraction_element!(EcucInstanceReferenceValue, EcucInstanceReferenceValue);
11
12impl EcucInstanceReferenceValue {
13 pub(crate) fn new(
14 parent: &Element,
15 definition: &EcucInstanceReferenceDef,
16 target_context: &[&Element],
17 target: &Element,
18 ) -> Result<Self, AutosarAbstractionError> {
19 let instance_ref_elem = parent.create_sub_element(ElementName::EcucInstanceReferenceValue)?;
20 let instance_ref = Self(instance_ref_elem);
21
22 instance_ref.set_definition(definition)?;
23 instance_ref.set_target(target_context, target)?;
24
25 Ok(instance_ref)
26 }
27
28 pub fn set_definition(&self, definition: &EcucInstanceReferenceDef) -> Result<(), AutosarAbstractionError> {
30 self.element()
31 .get_or_create_sub_element(ElementName::DefinitionRef)?
32 .set_reference_target(definition.element())?;
33
34 Ok(())
35 }
36
37 #[must_use]
43 pub fn definition(&self) -> Option<EcucInstanceReferenceDef> {
44 let definition_elem = self
45 .element()
46 .get_sub_element(ElementName::DefinitionRef)?
47 .get_reference_target()
48 .ok()?;
49 EcucInstanceReferenceDef::try_from(definition_elem).ok()
50 }
51
52 #[must_use]
57 pub fn definition_ref(&self) -> Option<String> {
58 self.element()
59 .get_sub_element(ElementName::DefinitionRef)?
60 .character_data()?
61 .string_value()
62 }
63
64 pub fn set_target(&self, taget_context: &[&Element], target: &Element) -> Result<(), AutosarAbstractionError> {
70 let _ = self.element().remove_sub_element_kind(ElementName::ValueIref);
72 let value_iref_elem = self.element().create_sub_element(ElementName::ValueIref)?;
75 for context_elem in taget_context {
76 value_iref_elem
77 .create_sub_element(ElementName::ContextElementRef)?
78 .set_reference_target(context_elem)?;
79 }
80 value_iref_elem
82 .create_sub_element(ElementName::TargetRef)?
83 .set_reference_target(target)?;
84
85 Ok(())
86 }
87
88 #[must_use]
93 pub fn target(&self) -> Option<(Vec<Element>, Element)> {
94 let value_iref_elem = self.element().get_sub_element(ElementName::ValueIref)?;
95 let target = value_iref_elem
96 .get_sub_element(ElementName::TargetRef)?
97 .get_reference_target()
98 .ok()?;
99
100 let context_elements: Vec<_> = value_iref_elem
101 .sub_elements()
102 .filter(|elem| elem.element_name() == ElementName::ContextElementRef)
103 .filter_map(|context_ref| context_ref.get_reference_target().ok())
104 .collect();
105
106 Some((context_elements, target))
107 }
108
109 pub fn set_index(&self, index: Option<u64>) -> Result<(), AutosarAbstractionError> {
114 if let Some(index) = index {
115 self.element()
116 .get_or_create_sub_element(ElementName::Index)?
117 .set_character_data(index)?;
118 } else {
119 let _ = self.element().remove_sub_element_kind(ElementName::Index);
120 }
121
122 Ok(())
123 }
124
125 #[must_use]
130 pub fn index(&self) -> Option<u64> {
131 self.element()
132 .get_sub_element(ElementName::Index)?
133 .character_data()?
134 .parse_integer()
135 }
136
137 pub fn set_is_auto_value(&self, is_auto_value: Option<bool>) -> Result<(), AutosarAbstractionError> {
141 if let Some(is_auto_value) = is_auto_value {
142 self.element()
143 .get_or_create_sub_element(ElementName::IsAutoValue)?
144 .set_character_data(is_auto_value)?;
145 } else {
146 let _ = self.element().remove_sub_element_kind(ElementName::IsAutoValue);
147 }
148
149 Ok(())
150 }
151
152 #[must_use]
154 pub fn is_auto_value(&self) -> Option<bool> {
155 self.element()
156 .get_sub_element(ElementName::IsAutoValue)?
157 .character_data()?
158 .parse_bool()
159 }
160}
161
162#[derive(Debug, Clone, PartialEq, Eq, Hash)]
166pub struct EcucReferenceValue(Element);
167abstraction_element!(EcucReferenceValue, EcucReferenceValue);
168
169impl EcucReferenceValue {
170 pub(crate) fn new<T: AbstractEcucReferenceDef>(
171 parent: &Element,
172 definition: &T,
173 target: &Element,
174 ) -> Result<Self, AutosarAbstractionError> {
175 let reference_elem = parent.create_sub_element(ElementName::EcucReferenceValue)?;
176 let reference = Self(reference_elem);
177
178 reference.set_definition(definition)?;
179 reference.set_target(target)?;
180
181 Ok(reference)
182 }
183
184 pub fn set_definition<T: AbstractEcucReferenceDef>(&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]
199 pub fn definition(&self) -> Option<EcucAnyReferenceDef> {
200 let definition_elem = self
201 .element()
202 .get_sub_element(ElementName::DefinitionRef)?
203 .get_reference_target()
204 .ok()?;
205 EcucAnyReferenceDef::try_from(definition_elem).ok()
206 }
207
208 #[must_use]
213 pub fn definition_ref(&self) -> Option<String> {
214 self.element()
215 .get_sub_element(ElementName::DefinitionRef)?
216 .character_data()?
217 .string_value()
218 }
219
220 pub fn set_target(&self, target: &Element) -> Result<(), AutosarAbstractionError> {
222 self.element()
223 .get_or_create_sub_element(ElementName::ValueRef)?
224 .set_reference_target(target)?;
225
226 Ok(())
227 }
228
229 #[must_use]
231 pub fn target(&self) -> Option<Element> {
232 self.element()
233 .get_sub_element(ElementName::ValueRef)?
234 .get_reference_target()
235 .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 let _ = 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
266 pub fn set_is_auto_value(&self, is_auto_value: Option<bool>) -> Result<(), AutosarAbstractionError> {
270 if let Some(is_auto_value) = is_auto_value {
271 self.element()
272 .get_or_create_sub_element(ElementName::IsAutoValue)?
273 .set_character_data(is_auto_value)?;
274 } else {
275 let _ = self.element().remove_sub_element_kind(ElementName::IsAutoValue);
276 }
277
278 Ok(())
279 }
280
281 #[must_use]
283 pub fn is_auto_value(&self) -> Option<bool> {
284 self.element()
285 .get_sub_element(ElementName::IsAutoValue)?
286 .character_data()?
287 .parse_bool()
288 }
289}
290
291#[derive(Debug, Clone, PartialEq, Eq, Hash)]
296pub enum EcucAnyReferenceValue {
297 Instance(EcucInstanceReferenceValue),
299 Reference(EcucReferenceValue),
301}
302
303impl TryFrom<Element> for EcucAnyReferenceValue {
304 type Error = AutosarAbstractionError;
305
306 fn try_from(element: Element) -> Result<Self, Self::Error> {
307 match element.element_name() {
308 ElementName::EcucInstanceReferenceValue => {
309 Ok(EcucAnyReferenceValue::Instance(EcucInstanceReferenceValue(element)))
310 }
311 ElementName::EcucReferenceValue => Ok(EcucAnyReferenceValue::Reference(EcucReferenceValue(element))),
312 _ => Err(AutosarAbstractionError::ConversionError {
313 element,
314 dest: "EcucAnyReferenceValue".to_string(),
315 }),
316 }
317 }
318}
319
320impl AbstractionElement for EcucAnyReferenceValue {
321 fn element(&self) -> &Element {
322 match self {
323 EcucAnyReferenceValue::Instance(instance) => instance.element(),
324 EcucAnyReferenceValue::Reference(reference) => reference.element(),
325 }
326 }
327}
328
329impl IdentifiableAbstractionElement for EcucAnyReferenceValue {}
330
331#[cfg(test)]
334mod test {
335 use crate::{
336 AbstractionElement, AutosarModelAbstraction, ecu_configuration::EcucAnyReferenceValue,
337 software_component::AbstractSwComponentType,
338 };
339 use autosar_data::AutosarVersion;
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 let instance_ref_def = container_def
353 .create_instance_reference_def("InstanceRefDef", "origin")
354 .unwrap();
355 let foreign_reference_def = container_def
356 .create_foreign_reference_def("ForeignRefDef", "origin")
357 .unwrap();
358 let choice_reference_def = container_def
359 .create_choice_reference_def("ChoiceRefDef", "origin")
360 .unwrap();
361 let reference_def = container_def.create_reference_def("RefDef", "origin").unwrap();
362 let uri_reference_def = container_def.create_uri_reference_def("UriRefDef", "origin").unwrap();
363
364 let ecuc_config_values = val_package
366 .create_ecuc_module_configuration_values("Module", &module_def)
367 .unwrap();
368 let container_values = ecuc_config_values
369 .create_container_value("Container", &container_def)
370 .unwrap();
371
372 let comp = val_package.create_composition_sw_component_type("comp").unwrap();
376 let port_interface = val_package.create_sender_receiver_interface("sr_interface").unwrap();
377 let r_port_prototype = comp.create_r_port("sr_r_port", &port_interface).unwrap();
378 let instance_ref = container_values
380 .create_instance_reference(
381 &instance_ref_def,
382 &[r_port_prototype.element()],
383 r_port_prototype.element(),
384 )
385 .unwrap();
386 assert!(instance_ref.definition().is_none());
388 assert_eq!(instance_ref.definition_ref(), instance_ref_def.element().path().ok());
389 let (target_context, target) = instance_ref.target().unwrap();
390 assert_eq!(&target, r_port_prototype.element());
391 assert_eq!(target_context, &[r_port_prototype.element().clone()]);
392 assert_eq!(instance_ref.index(), None);
393 instance_ref.set_index(Some(42)).unwrap();
394 assert_eq!(instance_ref.index(), Some(42));
395 assert_eq!(instance_ref.is_auto_value(), None);
396 instance_ref.set_is_auto_value(Some(true)).unwrap();
397 assert_eq!(instance_ref.is_auto_value(), Some(true));
398
399 let foreign_ref = container_values
400 .create_reference_value(&foreign_reference_def, val_package.element())
401 .unwrap();
402 assert!(foreign_ref.definition().is_none());
403 assert_eq!(
404 foreign_ref.definition_ref(),
405 foreign_reference_def.element().path().ok()
406 );
407 assert_eq!(&foreign_ref.target().unwrap(), val_package.element());
408 assert_eq!(foreign_ref.index(), None);
409 foreign_ref.set_index(Some(42)).unwrap();
410 assert_eq!(foreign_ref.index(), Some(42));
411 assert_eq!(foreign_ref.is_auto_value(), None);
412 foreign_ref.set_is_auto_value(Some(true)).unwrap();
413 assert_eq!(foreign_ref.is_auto_value(), Some(true));
414
415 let choice_ref = container_values
416 .create_reference_value(&choice_reference_def, val_package.element())
417 .unwrap();
418 assert!(choice_ref.definition().is_none());
419 assert_eq!(choice_ref.definition_ref(), choice_reference_def.element().path().ok());
420 assert_eq!(&choice_ref.target().unwrap(), val_package.element());
421 assert_eq!(choice_ref.index(), None);
422 choice_ref.set_index(Some(42)).unwrap();
423 assert_eq!(choice_ref.index(), Some(42));
424 assert_eq!(choice_ref.is_auto_value(), None);
425 choice_ref.set_is_auto_value(Some(true)).unwrap();
426 assert_eq!(choice_ref.is_auto_value(), Some(true));
427
428 let ref_ref = container_values
429 .create_reference_value(&reference_def, val_package.element())
430 .unwrap();
431 assert!(ref_ref.definition().is_none());
432 assert_eq!(ref_ref.definition_ref(), reference_def.element().path().ok());
433 assert_eq!(&ref_ref.target().unwrap(), val_package.element());
434 assert_eq!(ref_ref.index(), None);
435 ref_ref.set_index(Some(42)).unwrap();
436 assert_eq!(ref_ref.index(), Some(42));
437 assert_eq!(ref_ref.is_auto_value(), None);
438 ref_ref.set_is_auto_value(Some(true)).unwrap();
439 assert_eq!(ref_ref.is_auto_value(), Some(true));
440
441 let uri_ref = container_values
442 .create_reference_value(&uri_reference_def, val_package.element())
443 .unwrap();
444 assert!(uri_ref.definition().is_none());
445 assert_eq!(uri_ref.definition_ref(), uri_reference_def.element().path().ok());
446 assert_eq!(&uri_ref.target().unwrap(), val_package.element());
447 assert_eq!(uri_ref.index(), None);
448 uri_ref.set_index(Some(42)).unwrap();
449 assert_eq!(uri_ref.index(), Some(42));
450 assert_eq!(uri_ref.is_auto_value(), None);
451 uri_ref.set_is_auto_value(Some(true)).unwrap();
452 assert_eq!(uri_ref.is_auto_value(), Some(true));
453
454 assert_eq!(container_values.reference_values().count(), 5);
455
456 let any_ref = EcucAnyReferenceValue::try_from(instance_ref.element().clone()).unwrap();
457 assert!(matches!(any_ref, EcucAnyReferenceValue::Instance(_)));
458 assert_eq!(any_ref.element(), instance_ref.element());
459 let any_ref = EcucAnyReferenceValue::try_from(foreign_ref.element().clone()).unwrap();
460 assert!(matches!(any_ref, EcucAnyReferenceValue::Reference(_)));
461 assert_eq!(any_ref.element(), foreign_ref.element());
462 let err = EcucAnyReferenceValue::try_from(val_package.element().clone());
463 assert!(err.is_err());
464 }
465}