autosar_data_abstraction/ecu_configuration/values/
parameter.rs1use crate::{
2 AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element,
3 ecu_configuration::{EcucAddInfoParamDef, EcucParamDef, EcucParameterDef},
4};
5use autosar_data::{Element, ElementName};
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
11pub struct EcucAddInfoParamValue(Element);
12abstraction_element!(EcucAddInfoParamValue, EcucAddInfoParamValue);
13
14impl EcucAddInfoParamValue {
15 pub(crate) fn new(parent: &Element, definition: &EcucAddInfoParamDef) -> Result<Self, AutosarAbstractionError> {
16 let add_info_param_elem = parent.create_sub_element(ElementName::EcucAddInfoParamValue)?;
17 add_info_param_elem
18 .get_or_create_sub_element(ElementName::DefinitionRef)?
19 .set_reference_target(definition.element())?;
20 Ok(Self(add_info_param_elem))
21 }
22
23 }
25
26#[derive(Debug, Clone, PartialEq, Eq, Hash)]
33pub struct EcucNumericalParamValue(Element);
34abstraction_element!(EcucNumericalParamValue, EcucNumericalParamValue);
35
36impl EcucNumericalParamValue {
37 pub(crate) fn new<T: EcucParamDef>(
38 parent: &Element,
39 definition: &T,
40 value: &str,
41 ) -> Result<Self, AutosarAbstractionError> {
42 let numerical_param_elem = parent.create_sub_element(ElementName::EcucNumericalParamValue)?;
43
44 let numerical_param = Self(numerical_param_elem);
45 numerical_param.set_definition(definition)?;
46 numerical_param.set_value(value)?;
47
48 Ok(numerical_param)
49 }
50
51 pub fn set_definition<T: EcucParamDef>(&self, definition: &T) -> Result<(), AutosarAbstractionError> {
53 self.element()
54 .get_or_create_sub_element(ElementName::DefinitionRef)?
55 .set_reference_target(definition.element())?;
56
57 Ok(())
58 }
59
60 #[must_use]
66 pub fn definition(&self) -> Option<EcucParameterDef> {
67 let definition_elem = self
68 .element()
69 .get_sub_element(ElementName::DefinitionRef)?
70 .get_reference_target()
71 .ok()?;
72 EcucParameterDef::try_from(definition_elem).ok()
73 }
74
75 #[must_use]
80 pub fn definition_ref(&self) -> Option<String> {
81 self.element()
82 .get_sub_element(ElementName::DefinitionRef)?
83 .character_data()?
84 .string_value()
85 }
86
87 pub fn set_value(&self, value: &str) -> Result<(), AutosarAbstractionError> {
89 self.element()
90 .get_or_create_sub_element(ElementName::Value)?
91 .set_character_data(value)?;
92
93 Ok(())
94 }
95
96 #[must_use]
98 pub fn value(&self) -> Option<String> {
99 self.element()
100 .get_sub_element(ElementName::Value)?
101 .character_data()?
102 .string_value()
103 }
104
105 #[must_use]
107 pub fn value_bool(&self) -> Option<bool> {
108 self.element()
109 .get_sub_element(ElementName::Value)?
110 .character_data()?
111 .parse_bool()
112 }
113
114 #[must_use]
116 pub fn value_int(&self) -> Option<i64> {
117 self.element()
118 .get_sub_element(ElementName::Value)?
119 .character_data()?
120 .parse_integer()
121 }
122
123 #[must_use]
125 pub fn value_float(&self) -> Option<f64> {
126 self.element()
127 .get_sub_element(ElementName::Value)?
128 .character_data()?
129 .parse_float()
130 }
131
132 pub fn set_index(&self, index: Option<u64>) -> Result<(), AutosarAbstractionError> {
137 if let Some(index) = index {
138 self.element()
139 .get_or_create_sub_element(ElementName::Index)?
140 .set_character_data(index)?;
141 } else {
142 let _ = self.element().remove_sub_element_kind(ElementName::Index);
143 }
144
145 Ok(())
146 }
147
148 #[must_use]
153 pub fn index(&self) -> Option<u64> {
154 self.element()
155 .get_sub_element(ElementName::Index)?
156 .character_data()?
157 .parse_integer()
158 }
159
160 pub fn set_is_auto_value(&self, is_auto_value: Option<bool>) -> Result<(), AutosarAbstractionError> {
164 if let Some(is_auto_value) = is_auto_value {
165 self.element()
166 .get_or_create_sub_element(ElementName::IsAutoValue)?
167 .set_character_data(is_auto_value)?;
168 } else {
169 let _ = self.element().remove_sub_element_kind(ElementName::IsAutoValue);
170 }
171
172 Ok(())
173 }
174
175 #[must_use]
177 pub fn is_auto_value(&self) -> Option<bool> {
178 self.element()
179 .get_sub_element(ElementName::IsAutoValue)?
180 .character_data()?
181 .parse_bool()
182 }
183}
184
185#[derive(Debug, Clone, PartialEq, Eq, Hash)]
190pub struct EcucTextualParamValue(Element);
191abstraction_element!(EcucTextualParamValue, EcucTextualParamValue);
192
193impl EcucTextualParamValue {
194 pub(crate) fn new<T: EcucParamDef>(
195 parent: &Element,
196 definition: &T,
197 value: &str,
198 ) -> Result<Self, AutosarAbstractionError> {
199 let textual_param_elem = parent.create_sub_element(ElementName::EcucTextualParamValue)?;
200
201 let textual_param = Self(textual_param_elem);
202 textual_param.set_definition(definition)?;
203 textual_param.set_value(value)?;
204
205 Ok(textual_param)
206 }
207
208 pub fn set_definition<T: EcucParamDef>(&self, definition: &T) -> Result<(), AutosarAbstractionError> {
210 self.element()
211 .get_or_create_sub_element(ElementName::DefinitionRef)?
212 .set_reference_target(definition.element())?;
213
214 Ok(())
215 }
216
217 #[must_use]
224 pub fn definition(&self) -> Option<EcucParameterDef> {
225 let definition_elem = self
226 .element()
227 .get_sub_element(ElementName::DefinitionRef)?
228 .get_reference_target()
229 .ok()?;
230 EcucParameterDef::try_from(definition_elem).ok()
231 }
232
233 #[must_use]
238 pub fn definition_ref(&self) -> Option<String> {
239 self.element()
240 .get_sub_element(ElementName::DefinitionRef)?
241 .character_data()?
242 .string_value()
243 }
244
245 pub fn set_value(&self, value: &str) -> Result<(), AutosarAbstractionError> {
247 self.element()
248 .get_or_create_sub_element(ElementName::Value)?
249 .set_character_data(value)?;
250
251 Ok(())
252 }
253
254 #[must_use]
256 pub fn value(&self) -> Option<String> {
257 self.element()
258 .get_sub_element(ElementName::Value)?
259 .character_data()?
260 .string_value()
261 }
262
263 pub fn set_index(&self, index: Option<u64>) -> Result<(), AutosarAbstractionError> {
268 if let Some(index) = index {
269 self.element()
270 .get_or_create_sub_element(ElementName::Index)?
271 .set_character_data(index)?;
272 } else {
273 let _ = self.element().remove_sub_element_kind(ElementName::Index);
274 }
275
276 Ok(())
277 }
278
279 #[must_use]
284 pub fn index(&self) -> Option<u64> {
285 self.element()
286 .get_sub_element(ElementName::Index)?
287 .character_data()?
288 .parse_integer()
289 }
290
291 pub fn set_is_auto_value(&self, is_auto_value: Option<bool>) -> Result<(), AutosarAbstractionError> {
295 if let Some(is_auto_value) = is_auto_value {
296 self.element()
297 .get_or_create_sub_element(ElementName::IsAutoValue)?
298 .set_character_data(is_auto_value)?;
299 } else {
300 let _ = self.element().remove_sub_element_kind(ElementName::IsAutoValue);
301 }
302
303 Ok(())
304 }
305
306 #[must_use]
310 pub fn is_auto_value(&self) -> Option<bool> {
311 self.element()
312 .get_sub_element(ElementName::IsAutoValue)?
313 .character_data()?
314 .parse_bool()
315 }
316}
317
318#[derive(Debug, Clone, PartialEq, Eq, Hash)]
323pub enum EcucParameterValue {
324 AddInfo(EcucAddInfoParamValue),
326 Numerical(EcucNumericalParamValue),
328 Textual(EcucTextualParamValue),
330}
331
332impl AbstractionElement for EcucParameterValue {
333 fn element(&self) -> &Element {
334 match self {
335 EcucParameterValue::AddInfo(elem) => elem.element(),
336 EcucParameterValue::Numerical(elem) => elem.element(),
337 EcucParameterValue::Textual(elem) => elem.element(),
338 }
339 }
340}
341
342impl TryFrom<Element> for EcucParameterValue {
343 type Error = AutosarAbstractionError;
344
345 fn try_from(element: Element) -> Result<Self, Self::Error> {
346 match element.element_name() {
347 ElementName::EcucAddInfoParamValue => Ok(EcucParameterValue::AddInfo(EcucAddInfoParamValue(element))),
348 ElementName::EcucNumericalParamValue => Ok(EcucParameterValue::Numerical(EcucNumericalParamValue(element))),
349 ElementName::EcucTextualParamValue => Ok(EcucParameterValue::Textual(EcucTextualParamValue(element))),
350 _ => Err(AutosarAbstractionError::ConversionError {
351 element,
352 dest: "EcucParameterValue".to_string(),
353 }),
354 }
355 }
356}
357
358impl IdentifiableAbstractionElement for EcucParameterValue {}
359
360#[cfg(test)]
363mod test {
364 use crate::{
365 AbstractionElement, AutosarModelAbstraction,
366 ecu_configuration::{EcucParameterDef, EcucParameterValue},
367 };
368 use autosar_data::{AutosarVersion, ElementName};
369
370 #[test]
371 fn test_parameter_values() {
372 let definition_model = AutosarModelAbstraction::create("definition.arxml", AutosarVersion::LATEST);
373 let def_package = definition_model.get_or_create_package("/def_package").unwrap();
374
375 let values_model = AutosarModelAbstraction::create("values.arxml", AutosarVersion::LATEST);
376 let val_package = values_model.get_or_create_package("/val_package").unwrap();
377
378 let module_def = def_package.create_ecuc_module_def("ModuleDef").unwrap();
380 let container_def = module_def.create_param_conf_container_def("ContainerDef").unwrap();
381 let add_info_param_def = container_def
382 .create_add_info_param_def("AddInfoParam", "AUTOSAR_ECUC")
383 .unwrap();
384 let int_param_def = container_def
385 .create_integer_param_def("IntParam", "AUTOSAR_ECUC")
386 .unwrap();
387 let float_param_def = container_def
388 .create_float_param_def("FloatParam", "AUTOSAR_ECUC")
389 .unwrap();
390 let bool_param_def = container_def
391 .create_boolean_param_def("BoolParam", "AUTOSAR_ECUC")
392 .unwrap();
393 let string_param_def = container_def
394 .create_string_param_def("StringParam", "AUTOSAR_ECUC")
395 .unwrap();
396 let fnc_param_def = container_def
397 .create_function_name_param_def("FncParam", "AUTOSAR_ECUC")
398 .unwrap();
399 let link_param_def = container_def
400 .create_linker_symbol_param_def("LinkParam", "AUTOSAR_ECUC")
401 .unwrap();
402 let enum_param_def = container_def
403 .create_enumeration_param_def("EnumParam", "AUTOSAR_ECUC")
404 .unwrap();
405 enum_param_def.create_enumeration_literal("EnumLiteral_1").unwrap();
406 enum_param_def.create_enumeration_literal("EnumLiteral_2").unwrap();
407
408 let ecuc_value_collection = val_package.create_ecuc_value_collection("EcucValues").unwrap();
410 let ecuc_config_values = val_package
411 .create_ecuc_module_configuration_values("Module", &module_def)
412 .unwrap();
413 ecuc_value_collection
414 .add_module_configuration(&ecuc_config_values)
415 .unwrap();
416 let container_values = ecuc_config_values
417 .create_container_value("Container", &container_def)
418 .unwrap();
419
420 let add_info_param_value = container_values
421 .create_add_info_param_value(&add_info_param_def)
422 .unwrap();
423 let int_param_value = container_values
425 .create_numerical_param_value(&int_param_def, "42")
426 .unwrap();
427 assert_eq!(int_param_value.value_int(), Some(42));
428 int_param_value.set_value("43").unwrap();
429 assert_eq!(int_param_value.value_int(), Some(43));
430 int_param_value.set_index(Some(1)).unwrap();
431 assert_eq!(int_param_value.index(), Some(1));
432 int_param_value.set_is_auto_value(Some(true)).unwrap();
433 assert_eq!(int_param_value.is_auto_value(), Some(true));
434 assert_eq!(int_param_value.definition_ref(), int_param_def.element().path().ok());
435 assert!(int_param_value.definition().is_none());
437
438 let float_param_value = container_values
439 .create_numerical_param_value(&float_param_def, "3.14")
440 .unwrap();
441 assert_eq!(float_param_value.value().as_deref(), Some("3.14"));
442 assert_eq!(float_param_value.value_float(), Some(3.14));
443 float_param_value.set_value("2.71").unwrap();
444 assert_eq!(float_param_value.value_float(), Some(2.71));
445 float_param_value.set_index(Some(2)).unwrap();
446 assert_eq!(float_param_value.index(), Some(2));
447 float_param_value.set_is_auto_value(Some(false)).unwrap();
448 assert_eq!(float_param_value.is_auto_value(), Some(false));
449 assert_eq!(
450 float_param_value.definition_ref(),
451 float_param_def.element().path().ok()
452 );
453
454 let bool_param_value = container_values
455 .create_numerical_param_value(&bool_param_def, "true")
456 .unwrap();
457 assert_eq!(bool_param_value.value().as_deref(), Some("true"));
458 assert_eq!(bool_param_value.value_bool(), Some(true));
459 bool_param_value.set_value("false").unwrap();
460 assert_eq!(bool_param_value.value_bool(), Some(false));
461 bool_param_value.set_index(Some(3)).unwrap();
462 assert_eq!(bool_param_value.index(), Some(3));
463 bool_param_value.set_is_auto_value(None).unwrap();
464 assert_eq!(bool_param_value.is_auto_value(), None);
465 assert_eq!(bool_param_value.definition_ref(), bool_param_def.element().path().ok());
466
467 let string_param_value = container_values
468 .create_textual_param_value(&string_param_def, "Hello, World!")
469 .unwrap();
470 assert_eq!(string_param_value.value().as_deref(), Some("Hello, World!"));
471 string_param_value.set_value("Goodbye, World!").unwrap();
472 assert_eq!(string_param_value.value().as_deref(), Some("Goodbye, World!"));
473 string_param_value.set_index(Some(4)).unwrap();
474 assert_eq!(string_param_value.index(), Some(4));
475 string_param_value.set_is_auto_value(Some(true)).unwrap();
476 assert_eq!(string_param_value.is_auto_value(), Some(true));
477 assert_eq!(
478 string_param_value.definition_ref(),
479 string_param_def.element().path().ok()
480 );
481
482 let fnc_param_value = container_values
483 .create_textual_param_value(&fnc_param_def, "function_name")
484 .unwrap();
485 let link_param_value = container_values
486 .create_textual_param_value(&link_param_def, "linker_symbol")
487 .unwrap();
488
489 let enum_param_value = container_values
490 .create_textual_param_value(&enum_param_def, "EnumLiteral_1")
491 .unwrap();
492 assert_eq!(enum_param_value.value().as_deref(), Some("EnumLiteral_1"));
493 enum_param_value.set_value("EnumLiteral_2").unwrap();
494 assert_eq!(enum_param_value.value().as_deref(), Some("EnumLiteral_2"));
495 enum_param_value.set_index(Some(5)).unwrap();
496 assert_eq!(enum_param_value.index(), Some(5));
497 enum_param_value.set_is_auto_value(Some(false)).unwrap();
498 assert_eq!(enum_param_value.is_auto_value(), Some(false));
499 assert_eq!(enum_param_value.definition_ref(), enum_param_def.element().path().ok());
500
501 let mut parameters_iter = container_values.parameter_values();
502 assert_eq!(
503 parameters_iter.next().unwrap(),
504 EcucParameterValue::AddInfo(add_info_param_value.clone())
505 );
506 assert_eq!(
507 parameters_iter.next().unwrap(),
508 EcucParameterValue::Numerical(int_param_value.clone())
509 );
510 assert_eq!(
511 parameters_iter.next().unwrap(),
512 EcucParameterValue::Numerical(float_param_value.clone())
513 );
514 assert_eq!(
515 parameters_iter.next().unwrap(),
516 EcucParameterValue::Numerical(bool_param_value.clone())
517 );
518 assert_eq!(
519 parameters_iter.next().unwrap(),
520 EcucParameterValue::Textual(string_param_value.clone())
521 );
522 assert_eq!(
523 parameters_iter.next().unwrap(),
524 EcucParameterValue::Textual(fnc_param_value.clone())
525 );
526 assert_eq!(
527 parameters_iter.next().unwrap(),
528 EcucParameterValue::Textual(link_param_value.clone())
529 );
530 assert_eq!(
531 parameters_iter.next().unwrap(),
532 EcucParameterValue::Textual(enum_param_value.clone())
533 );
534 assert_eq!(container_values.parameter_values().count(), 8);
535 let ecuc_param = container_values.parameter_values().next().unwrap();
536 assert_eq!(ecuc_param.element(), add_info_param_value.element());
537
538 values_model
541 .root_element()
542 .get_sub_element(ElementName::ArPackages)
543 .unwrap()
544 .create_copied_sub_element(def_package.element())
545 .unwrap();
546 let int_param_def = EcucParameterDef::try_from(
548 values_model
549 .get_element_by_path(&int_param_def.element().path().unwrap())
550 .unwrap(),
551 )
552 .unwrap();
553 let float_param_def = EcucParameterDef::try_from(
554 values_model
555 .get_element_by_path(&float_param_def.element().path().unwrap())
556 .unwrap(),
557 )
558 .unwrap();
559 let bool_param_def = EcucParameterDef::try_from(
560 values_model
561 .get_element_by_path(&bool_param_def.element().path().unwrap())
562 .unwrap(),
563 )
564 .unwrap();
565 let string_param_def = EcucParameterDef::try_from(
566 values_model
567 .get_element_by_path(&string_param_def.element().path().unwrap())
568 .unwrap(),
569 )
570 .unwrap();
571 let enum_param_def = EcucParameterDef::try_from(
572 values_model
573 .get_element_by_path(&enum_param_def.element().path().unwrap())
574 .unwrap(),
575 )
576 .unwrap();
577
578 assert_eq!(int_param_value.definition().unwrap(), int_param_def);
580 assert_eq!(float_param_value.definition().unwrap(), float_param_def);
581 assert_eq!(bool_param_value.definition().unwrap(), bool_param_def);
582 assert_eq!(string_param_value.definition().unwrap(), string_param_def);
583 assert_eq!(enum_param_value.definition().unwrap(), enum_param_def);
584
585 assert_eq!(int_param_value.definition().unwrap().element(), int_param_def.element());
586 }
587}