1use std::str::FromStr;
2
3use crate::{
4 AbstractionElement, ArPackage, AutosarAbstractionError, Element, IdentifiableAbstractionElement,
5 abstraction_element,
6 datatype::{ApplicationArrayElement, ApplicationPrimitiveCategory, ApplicationRecordElement, Unit},
7 software_component::{ArgumentDataPrototype, ParameterDataPrototype, VariableDataPrototype},
8};
9use autosar_data::{ElementName, EnumItem};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
16pub struct ConstantSpecification(Element);
17abstraction_element!(ConstantSpecification, ConstantSpecification);
18impl IdentifiableAbstractionElement for ConstantSpecification {}
19
20impl ConstantSpecification {
21 pub(crate) fn new(
22 name: &str,
23 package: &ArPackage,
24 value: ValueSpecification,
25 ) -> Result<ConstantSpecification, AutosarAbstractionError> {
26 let elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
27
28 let const_spec_elem = elements
29 .create_named_sub_element(ElementName::ConstantSpecification, name)
30 .unwrap();
31 let const_spec = Self(const_spec_elem);
32 const_spec.set_value_specification(value)?;
34
35 Ok(const_spec)
36 }
37
38 pub fn set_value_specification<T: Into<ValueSpecification>>(
40 &self,
41 value: T,
42 ) -> Result<(), AutosarAbstractionError> {
43 let value: ValueSpecification = value.into();
44 let _ = self.element().remove_sub_element_kind(ElementName::ValueSpec);
46 let value_spec_elem = self.element().create_sub_element(ElementName::ValueSpec)?;
47 value.store(&value_spec_elem)?;
48 Ok(())
49 }
50
51 #[must_use]
53 pub fn value_specification(&self) -> Option<ValueSpecification> {
54 let spec_elem = self
55 .element()
56 .get_sub_element(ElementName::ValueSpec)
57 .and_then(|vs_elem| vs_elem.get_sub_element_at(0))?;
58 ValueSpecification::load(&spec_elem)
59 }
60}
61
62#[derive(Debug, Clone, PartialEq)]
66pub struct ArrayValueSpecification {
67 pub label: Option<String>,
69 pub values: Vec<ValueSpecification>,
71}
72
73impl ArrayValueSpecification {
74 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
75 let array_elem = parent.create_sub_element(ElementName::ArrayValueSpecification)?;
76 store_label(&array_elem, &self.label)?;
77 let elements_elem = array_elem.create_sub_element(ElementName::Elements)?;
78 for value in &self.values {
79 value.store(&elements_elem)?;
80 }
81 Ok(())
82 }
83
84 fn load(element: &Element) -> Option<Self> {
85 let label = load_label(element);
86 let elements_elem = element.get_sub_element(ElementName::Elements)?;
87 let values = elements_elem
88 .sub_elements()
89 .filter_map(|elem| ValueSpecification::load(&elem))
90 .collect::<Vec<_>>();
91
92 Some(Self { label, values })
93 }
94}
95
96impl From<ArrayValueSpecification> for ValueSpecification {
97 fn from(value_spec: ArrayValueSpecification) -> Self {
98 ValueSpecification::Array(value_spec)
99 }
100}
101
102#[derive(Debug, Clone, PartialEq)]
106pub struct RecordValueSpecification {
107 pub label: Option<String>,
109 pub values: Vec<ValueSpecification>,
112}
113
114impl RecordValueSpecification {
115 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
116 let record_elem = parent.create_sub_element(ElementName::RecordValueSpecification)?;
117 store_label(&record_elem, &self.label)?;
118 let fields_elem = record_elem.create_sub_element(ElementName::Fields)?;
119 for value in &self.values {
120 value.store(&fields_elem)?;
121 }
122 Ok(())
123 }
124
125 fn load(element: &Element) -> Option<Self> {
126 let label = load_label(element);
127 let fields_elem = element.get_sub_element(ElementName::Fields)?;
128 let values = fields_elem
129 .sub_elements()
130 .filter_map(|elem| ValueSpecification::load(&elem))
131 .collect::<Vec<_>>();
132
133 Some(Self { label, values })
134 }
135}
136
137impl From<RecordValueSpecification> for ValueSpecification {
138 fn from(value_spec: RecordValueSpecification) -> Self {
139 ValueSpecification::Record(value_spec)
140 }
141}
142
143#[derive(Debug, Clone, PartialEq)]
147pub struct TextValueSpecification {
148 pub label: Option<String>,
150 pub value: String,
152}
153
154impl TextValueSpecification {
155 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
156 let text_elem = parent.create_sub_element(ElementName::TextValueSpecification)?;
157 store_label(&text_elem, &self.label)?;
158 let value_elem = text_elem.create_sub_element(ElementName::Value)?;
159 value_elem.set_character_data(self.value.clone())?;
160 Ok(())
161 }
162
163 fn load(element: &Element) -> Option<Self> {
164 let label = load_label(element);
165 let value = element
166 .get_sub_element(ElementName::Value)?
167 .character_data()?
168 .string_value()?;
169
170 Some(Self { label, value })
171 }
172}
173
174impl From<TextValueSpecification> for ValueSpecification {
175 fn from(value_spec: TextValueSpecification) -> Self {
176 ValueSpecification::Text(value_spec)
177 }
178}
179
180#[derive(Debug, Clone, PartialEq)]
184pub struct NumericalValueSpecification {
185 pub label: Option<String>,
187 pub value: f64,
189}
190
191impl NumericalValueSpecification {
192 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
193 let num_elem = parent.create_sub_element(ElementName::NumericalValueSpecification)?;
194 store_label(&num_elem, &self.label)?;
195 let value_elem = num_elem.create_sub_element(ElementName::Value)?;
196 value_elem.set_character_data(self.value)?;
197 Ok(())
198 }
199
200 fn load(element: &Element) -> Option<Self> {
201 let label = load_label(element);
202 let value = element
203 .get_sub_element(ElementName::Value)?
204 .character_data()?
205 .parse_float()?;
206
207 Some(Self { label, value })
208 }
209}
210
211impl From<NumericalValueSpecification> for ValueSpecification {
212 fn from(value_spec: NumericalValueSpecification) -> Self {
213 ValueSpecification::Numerical(value_spec)
214 }
215}
216
217#[derive(Debug, Clone, PartialEq)]
221pub struct ConstantReference {
222 pub label: Option<String>,
224 pub constant: ConstantSpecification,
226}
227
228impl ConstantReference {
229 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
230 let const_ref_elem = parent.create_sub_element(ElementName::ConstantReference)?;
231 store_label(&const_ref_elem, &self.label)?;
232 const_ref_elem
233 .create_sub_element(ElementName::ConstantRef)
234 .and_then(|cr_elem| cr_elem.set_reference_target(self.constant.element()))?;
235 Ok(())
236 }
237
238 fn load(element: &Element) -> Option<Self> {
239 let label = load_label(element);
240 let constant_elem = element
241 .get_sub_element(ElementName::ConstantRef)?
242 .get_reference_target()
243 .ok()?;
244 let constant = ConstantSpecification::try_from(constant_elem).ok()?;
245
246 Some(Self { label, constant })
247 }
248}
249
250impl From<ConstantReference> for ValueSpecification {
251 fn from(value_spec: ConstantReference) -> Self {
252 ValueSpecification::ConstantReference(value_spec)
253 }
254}
255
256#[derive(Debug, Clone, PartialEq)]
260pub struct ApplicationValueSpecification {
261 pub label: Option<String>,
263 pub category: ApplicationPrimitiveCategory,
265 pub sw_axis_conts: Vec<SwAxisCont>,
267 pub sw_value_cont: SwValueCont,
269}
270
271impl ApplicationValueSpecification {
272 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
273 let app_elem = parent.create_sub_element(ElementName::ApplicationValueSpecification)?;
274 store_label(&app_elem, &self.label)?;
275 let category_elem = app_elem.create_sub_element(ElementName::Category)?;
276 category_elem.set_character_data(self.category.to_string())?;
277 let sw_axis_conts_elem = app_elem.create_sub_element(ElementName::SwAxisConts)?;
278 for sw_axis in &self.sw_axis_conts {
279 sw_axis.store(&sw_axis_conts_elem)?;
280 }
281 let sw_value_cont_elem = app_elem.create_sub_element(ElementName::SwValueCont)?;
282 self.sw_value_cont.store(&sw_value_cont_elem)?;
283
284 Ok(())
285 }
286
287 fn load(element: &Element) -> Option<Self> {
288 let label = load_label(element);
289 let category_string = element
290 .get_sub_element(ElementName::Category)?
291 .character_data()?
292 .string_value()?;
293 let category = ApplicationPrimitiveCategory::from_str(&category_string).ok()?;
294 let sw_axis_conts_elem = element.get_sub_element(ElementName::SwAxisConts)?;
295 let sw_axis_conts = sw_axis_conts_elem
296 .sub_elements()
297 .filter_map(|elem| SwAxisCont::load(&elem))
298 .collect::<Vec<_>>();
299 let sw_value_cont_elem = element.get_sub_element(ElementName::SwValueCont)?;
300 let sw_value_cont = SwValueCont::load(&sw_value_cont_elem)?;
301
302 Some(Self {
303 label,
304 category,
305 sw_axis_conts,
306 sw_value_cont,
307 })
308 }
309}
310
311impl From<ApplicationValueSpecification> for ValueSpecification {
312 fn from(value_spec: ApplicationValueSpecification) -> Self {
313 ValueSpecification::Application(value_spec)
314 }
315}
316
317#[derive(Debug, Clone, PartialEq)]
321pub struct NotAvailableValueSpecification {
322 pub label: Option<String>,
324 pub default_pattern: Option<u64>, }
327
328impl NotAvailableValueSpecification {
329 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
330 let not_available_elem = parent.create_sub_element(ElementName::NotAvailableValueSpecification)?;
331 store_label(¬_available_elem, &self.label)?;
332 if let Some(pattern) = &self.default_pattern {
333 if let Ok(pattern_elem) = not_available_elem.create_sub_element(ElementName::DefaultPattern) {
335 pattern_elem.set_character_data(pattern.to_string())?;
336 }
337 }
338 Ok(())
339 }
340
341 fn load(element: &Element) -> Option<Self> {
342 let label = load_label(element);
343 let default_pattern = element
344 .get_sub_element(ElementName::DefaultPattern)
345 .and_then(|dp_elem| dp_elem.character_data())
346 .and_then(|cdata| cdata.parse_integer());
347 Some(Self { label, default_pattern })
348 }
349}
350
351impl From<NotAvailableValueSpecification> for ValueSpecification {
352 fn from(value_spec: NotAvailableValueSpecification) -> Self {
353 ValueSpecification::NotAvailable(value_spec)
354 }
355}
356
357#[derive(Debug, Clone, PartialEq)]
361pub struct ReferenceValueSpecification {
362 pub label: Option<String>,
364 pub reference_value: DataPrototype,
366}
367
368impl ReferenceValueSpecification {
369 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
370 let ref_value_elem = parent.create_sub_element(ElementName::ReferenceValueSpecification)?;
371 store_label(&ref_value_elem, &self.label)?;
372 ref_value_elem
373 .create_sub_element(ElementName::ReferenceValueRef)
374 .and_then(|rvr_elem| rvr_elem.set_reference_target(self.reference_value.element()))?;
375 Ok(())
376 }
377
378 fn load(element: &Element) -> Option<Self> {
379 let label = load_label(element);
380 let reference_value_elem = element
381 .get_sub_element(ElementName::ReferenceValueRef)?
382 .get_reference_target()
383 .ok()?;
384 let reference_value = DataPrototype::try_from(reference_value_elem).ok()?;
385
386 Some(Self { label, reference_value })
387 }
388}
389
390impl From<ReferenceValueSpecification> for ValueSpecification {
391 fn from(value_spec: ReferenceValueSpecification) -> Self {
392 ValueSpecification::Reference(value_spec)
393 }
394}
395
396#[derive(Debug, Clone, PartialEq)]
400pub struct ApplicationRuleBasedValueSpecification {
401 pub label: Option<String>,
403 pub category: ApplicationPrimitiveCategory,
405 pub sw_axis_cont: Vec<RuleBasedAxisCont>,
407 pub sw_value_cont: RuleBasedValueCont,
409}
410
411impl ApplicationRuleBasedValueSpecification {
412 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
413 let app_rule_elem = parent.create_sub_element(ElementName::ApplicationRuleBasedValueSpecification)?;
414 store_label(&app_rule_elem, &self.label)?;
415 let category_elem = app_rule_elem.create_sub_element(ElementName::Category)?;
416 category_elem.set_character_data(self.category.to_string())?;
417 let sw_axis_cont_elem = app_rule_elem.create_sub_element(ElementName::SwAxisConts)?;
418 for sw_axis in &self.sw_axis_cont {
419 sw_axis.store(&sw_axis_cont_elem)?;
420 }
421 self.sw_value_cont.store(&app_rule_elem)?;
422
423 Ok(())
424 }
425
426 fn load(element: &Element) -> Option<Self> {
427 let label = load_label(element);
428
429 let category_string = element
430 .get_sub_element(ElementName::Category)?
431 .character_data()?
432 .string_value()?;
433 let category = ApplicationPrimitiveCategory::from_str(&category_string).ok()?;
434
435 let sw_axis_cont_elem = element.get_sub_element(ElementName::SwAxisConts)?;
436 let sw_axis_cont = sw_axis_cont_elem
437 .sub_elements()
438 .filter_map(|elem| RuleBasedAxisCont::load(&elem))
439 .collect::<Vec<_>>();
440
441 let sw_value_cont_elem = element.get_sub_element(ElementName::SwValueCont)?;
442 let sw_value_cont = RuleBasedValueCont::load(&sw_value_cont_elem)?;
443
444 Some(Self {
445 label,
446 category,
447 sw_axis_cont,
448 sw_value_cont,
449 })
450 }
451}
452
453impl From<ApplicationRuleBasedValueSpecification> for ValueSpecification {
454 fn from(value_spec: ApplicationRuleBasedValueSpecification) -> Self {
455 ValueSpecification::ApplicationRuleBased(value_spec)
456 }
457}
458
459#[derive(Debug, Clone, PartialEq)]
463pub struct CompositeRuleBasedValueSpecification {
464 pub label: Option<String>,
466 pub argument: Vec<CompositeValueSpecification>,
468 pub compound_primitive_argument: Vec<CompositeRuleBasedValueArgument>,
470 pub max_size_to_fill: Option<u64>,
472 pub rule: RuleBasedFillUntil,
474}
475
476impl CompositeRuleBasedValueSpecification {
477 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
478 let comp_rule_elem = parent.create_sub_element(ElementName::CompositeRuleBasedValueSpecification)?;
479 store_label(&comp_rule_elem, &self.label)?;
480 let arguments_elem = comp_rule_elem.create_sub_element(ElementName::Arguments)?;
481 for arg in &self.argument {
482 arg.store(&arguments_elem)?;
483 }
484 let compound_primitive_arguments_elem =
485 comp_rule_elem.create_sub_element(ElementName::CompoundPrimitiveArguments)?;
486 for arg in &self.compound_primitive_argument {
487 arg.store(&compound_primitive_arguments_elem)?;
488 }
489 if let Some(max_size) = self.max_size_to_fill {
490 let max_size_elem = comp_rule_elem.create_sub_element(ElementName::MaxSizeToFill)?;
491 max_size_elem.set_character_data(max_size.to_string())?;
492 }
493 let rule_elem = comp_rule_elem.create_sub_element(ElementName::Rule)?;
494 rule_elem.set_character_data(self.rule.to_string())?;
495
496 Ok(())
497 }
498
499 fn load(element: &Element) -> Option<Self> {
500 let label = load_label(element);
501 let arguments_elem = element.get_sub_element(ElementName::Arguments)?;
502 let argument = arguments_elem
503 .sub_elements()
504 .filter_map(|elem| CompositeValueSpecification::load(&elem))
505 .collect::<Vec<_>>();
506 let compound_primitive_arguments_elem = element.get_sub_element(ElementName::CompoundPrimitiveArguments)?;
507 let compound_primitive_argument = compound_primitive_arguments_elem
508 .sub_elements()
509 .filter_map(|elem| CompositeRuleBasedValueArgument::load(&elem))
510 .collect::<Vec<_>>();
511 let max_size_to_fill = element
512 .get_sub_element(ElementName::MaxSizeToFill)
513 .and_then(|ms_elem| ms_elem.character_data())
514 .and_then(|cdata| cdata.parse_integer());
515 let rule_string = element
516 .get_sub_element(ElementName::Rule)?
517 .character_data()?
518 .string_value()?;
519 let rule = RuleBasedFillUntil::from_str(&rule_string).ok()?;
520
521 Some(Self {
522 label,
523 argument,
524 compound_primitive_argument,
525 max_size_to_fill,
526 rule,
527 })
528 }
529}
530
531impl From<CompositeRuleBasedValueSpecification> for ValueSpecification {
532 fn from(value_spec: CompositeRuleBasedValueSpecification) -> Self {
533 ValueSpecification::CompositeRuleBased(value_spec)
534 }
535}
536
537#[derive(Debug, Clone, PartialEq)]
541pub struct NumericalRuleBasedValueSpecification {
542 pub label: Option<String>,
544 pub rule_based_values: RuleBasedValueSpecification,
546}
547
548impl NumericalRuleBasedValueSpecification {
549 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
550 let num_rule_elem = parent.create_sub_element(ElementName::NumericalRuleBasedValueSpecification)?;
551 store_label(&num_rule_elem, &self.label)?;
552 self.rule_based_values.store(&num_rule_elem)?;
553
554 Ok(())
555 }
556
557 fn load(element: &Element) -> Option<Self> {
558 let label = load_label(element);
559 let rule_based_values_elem = element.get_sub_element(ElementName::RuleBasedValues)?;
560 let rule_based_values = RuleBasedValueSpecification::load(&rule_based_values_elem)?;
561
562 Some(Self {
563 label,
564 rule_based_values,
565 })
566 }
567}
568
569impl From<NumericalRuleBasedValueSpecification> for ValueSpecification {
570 fn from(value_spec: NumericalRuleBasedValueSpecification) -> Self {
571 ValueSpecification::NumericalRuleBased(value_spec)
572 }
573}
574
575#[derive(Debug, Clone, PartialEq)]
578pub enum ValueSpecification {
580 Array(ArrayValueSpecification),
582 Record(RecordValueSpecification),
584 Text(TextValueSpecification),
586 Numerical(NumericalValueSpecification),
588 ConstantReference(ConstantReference),
590 Application(ApplicationValueSpecification),
592 NotAvailable(NotAvailableValueSpecification),
594 Reference(ReferenceValueSpecification),
596 ApplicationRuleBased(ApplicationRuleBasedValueSpecification),
598 CompositeRuleBased(CompositeRuleBasedValueSpecification),
600 NumericalRuleBased(NumericalRuleBasedValueSpecification),
602}
603
604impl ValueSpecification {
605 pub(crate) fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
606 match self {
607 Self::Array(array_spec) => array_spec.store(parent),
608 Self::Record(record_spec) => record_spec.store(parent),
609 Self::Text(text_spec) => text_spec.store(parent),
610 Self::Numerical(num_spec) => num_spec.store(parent),
611 Self::ConstantReference(constant_ref) => constant_ref.store(parent),
612 Self::Application(app_spec) => app_spec.store(parent),
613 Self::NotAvailable(not_available_spec) => not_available_spec.store(parent),
614 Self::Reference(ref_value_spec) => ref_value_spec.store(parent),
615 Self::ApplicationRuleBased(app_rule_spec) => app_rule_spec.store(parent),
616 Self::CompositeRuleBased(comp_rule_spec) => comp_rule_spec.store(parent),
617 Self::NumericalRuleBased(num_rule_spec) => num_rule_spec.store(parent),
618 }
619 }
620
621 pub(crate) fn load(elem: &Element) -> Option<ValueSpecification> {
622 match elem.element_name() {
623 ElementName::ArrayValueSpecification => ArrayValueSpecification::load(elem).map(Self::Array),
624 ElementName::RecordValueSpecification => RecordValueSpecification::load(elem).map(Self::Record),
625 ElementName::TextValueSpecification => TextValueSpecification::load(elem).map(Self::Text),
626 ElementName::NumericalValueSpecification => NumericalValueSpecification::load(elem).map(Self::Numerical),
627 ElementName::ConstantReference => ConstantReference::load(elem).map(Self::ConstantReference),
628 ElementName::ApplicationValueSpecification => {
629 ApplicationValueSpecification::load(elem).map(Self::Application)
630 }
631 ElementName::NotAvailableValueSpecification => {
632 NotAvailableValueSpecification::load(elem).map(Self::NotAvailable)
633 }
634 ElementName::ReferenceValueSpecification => ReferenceValueSpecification::load(elem).map(Self::Reference),
635 ElementName::ApplicationRuleBasedValueSpecification => {
636 ApplicationRuleBasedValueSpecification::load(elem).map(Self::ApplicationRuleBased)
637 }
638 ElementName::CompositeRuleBasedValueSpecification => {
639 CompositeRuleBasedValueSpecification::load(elem).map(Self::CompositeRuleBased)
640 }
641 ElementName::NumericalRuleBasedValueSpecification => {
642 NumericalRuleBasedValueSpecification::load(elem).map(Self::NumericalRuleBased)
643 }
644 _ => None,
645 }
646 }
647}
648
649fn store_label(parent: &Element, label: &Option<String>) -> Result<(), AutosarAbstractionError> {
650 if let Some(label) = label {
651 let label_elem = parent.create_sub_element(ElementName::ShortLabel)?;
652 label_elem.set_character_data(label.clone())?;
653 }
654 Ok(())
655}
656
657fn load_label(element: &Element) -> Option<String> {
658 let label_elem = element.get_sub_element(ElementName::ShortLabel)?;
659 label_elem.character_data()?.string_value()
660}
661
662#[derive(Debug, Clone, Copy, PartialEq, Eq)]
666pub enum RuleBasedFillUntil {
667 End,
670 MaxSize,
673}
674
675impl FromStr for RuleBasedFillUntil {
676 type Err = AutosarAbstractionError;
677
678 fn from_str(value: &str) -> Result<Self, Self::Err> {
679 match value {
680 "FILL_UNTIL_END" => Ok(RuleBasedFillUntil::End),
681 "FILL_UNTIL_MAX_SIZE" => Ok(RuleBasedFillUntil::MaxSize),
682 _ => Err(AutosarAbstractionError::ValueConversionError {
683 value: value.to_string(),
684 dest: "RuleBasedFillUntil".to_string(),
685 }),
686 }
687 }
688}
689
690impl std::fmt::Display for RuleBasedFillUntil {
691 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
692 match self {
693 RuleBasedFillUntil::End => f.write_str("FILL_UNTIL_END"),
694 RuleBasedFillUntil::MaxSize => f.write_str("FILL_UNTIL_MAX_SIZE"),
695 }
696 }
697}
698
699#[derive(Debug, Clone, PartialEq)]
703pub struct SwAxisCont {
704 pub category: SwAxisContCategory,
706 pub sw_array_size: Vec<u64>,
708 pub sw_axis_index: u64,
710 pub sw_values_phys: Vec<SwValue>,
712 pub unit: Option<Unit>,
714 pub unit_display_name: Option<String>,
716}
717
718impl SwAxisCont {
719 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
720 let sw_axis_cont_elem = parent.create_sub_element(ElementName::SwAxisCont)?;
721 let category_elem = sw_axis_cont_elem.create_sub_element(ElementName::Category)?;
722 category_elem.set_character_data::<EnumItem>(self.category.into())?;
723 let sw_array_size_elem = sw_axis_cont_elem.create_sub_element(ElementName::SwArraysize)?;
724 for size in &self.sw_array_size {
725 let size_elem = sw_array_size_elem.create_sub_element(ElementName::Vf)?;
726 size_elem.set_character_data(*size)?;
727 }
728 let sw_axis_index_elem = sw_axis_cont_elem.create_sub_element(ElementName::SwAxisIndex)?;
729 sw_axis_index_elem.set_character_data(self.sw_axis_index.to_string())?;
730 let sw_values_phys_elem = sw_axis_cont_elem.create_sub_element(ElementName::SwValuesPhys)?;
731 for value in &self.sw_values_phys {
732 value.store(&sw_values_phys_elem)?;
733 }
734
735 if let Some(unit) = &self.unit {
736 sw_axis_cont_elem
737 .create_sub_element(ElementName::UnitRef)
738 .and_then(|unit_elem| unit_elem.set_reference_target(unit.element()))?;
739 }
740 if let Some(unit_display_name) = &self.unit_display_name {
741 let _ = sw_axis_cont_elem
743 .create_sub_element(ElementName::UnitDisplayName)
744 .and_then(|udn_elem| udn_elem.set_character_data(unit_display_name.clone()));
745 }
746
747 Ok(())
748 }
749
750 fn load(element: &Element) -> Option<Self> {
751 let category_elem = element.get_sub_element(ElementName::Category)?;
752 let category = SwAxisContCategory::try_from(category_elem.character_data()?.enum_value()?).ok()?;
753 let sw_array_size_elem = element.get_sub_element(ElementName::SwArraysize)?;
754 let sw_array_size = sw_array_size_elem
757 .sub_elements()
758 .filter_map(|elem| elem.character_data()?.parse_integer())
759 .collect::<Vec<_>>();
760
761 let sw_axis_index_elem = element.get_sub_element(ElementName::SwAxisIndex)?;
762 let sw_axis_index = sw_axis_index_elem.character_data()?.parse_integer()?;
763
764 let sw_values_phys_elem = element.get_sub_element(ElementName::SwValuesPhys)?;
765 let sw_values_phys = sw_values_phys_elem
766 .sub_elements()
767 .filter_map(|elem| SwValue::load(&elem))
768 .collect::<Vec<_>>();
769
770 let unit = element
771 .get_sub_element(ElementName::UnitRef)
772 .and_then(|unit_elem| unit_elem.get_reference_target().ok())
773 .and_then(|unit_elem| Unit::try_from(unit_elem).ok());
774 let unit_display_name = element
775 .get_sub_element(ElementName::UnitDisplayName)
776 .and_then(|udn_elem| udn_elem.character_data())
777 .and_then(|cdata| cdata.string_value());
778
779 Some(Self {
780 category,
781 sw_array_size,
782 sw_axis_index,
783 sw_values_phys,
784 unit,
785 unit_display_name,
786 })
787 }
788}
789
790#[derive(Debug, Clone, Copy, PartialEq, Eq)]
795pub enum SwAxisContCategory {
796 StdAxis,
798 ComAxis,
800 ResAxis,
802}
803
804impl TryFrom<EnumItem> for SwAxisContCategory {
805 type Error = AutosarAbstractionError;
806
807 fn try_from(value: EnumItem) -> Result<Self, Self::Error> {
808 match value {
809 EnumItem::StdAxis => Ok(SwAxisContCategory::StdAxis), EnumItem::Stdaxis => Ok(SwAxisContCategory::StdAxis), EnumItem::ComAxis => Ok(SwAxisContCategory::ComAxis), EnumItem::Comaxis => Ok(SwAxisContCategory::ComAxis), EnumItem::ResAxis => Ok(SwAxisContCategory::ResAxis), EnumItem::Resaxis => Ok(SwAxisContCategory::ResAxis), _ => Err(AutosarAbstractionError::ValueConversionError {
816 value: value.to_string(),
817 dest: "SwAxisContCategory".to_string(),
818 }),
819 }
820 }
821}
822
823impl From<SwAxisContCategory> for EnumItem {
824 fn from(value: SwAxisContCategory) -> Self {
825 match value {
826 SwAxisContCategory::StdAxis => EnumItem::Stdaxis,
827 SwAxisContCategory::ComAxis => EnumItem::Comaxis,
828 SwAxisContCategory::ResAxis => EnumItem::Resaxis,
829 }
830 }
831}
832
833#[derive(Debug, Clone, PartialEq)]
837pub struct SwValueCont {
838 pub sw_array_size: Vec<u64>,
840 pub sw_values_phys: Vec<SwValue>,
842}
843
844impl SwValueCont {
845 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
846 let sw_array_size_elem = parent.create_sub_element(ElementName::SwArraysize)?;
847 for size in &self.sw_array_size {
848 let size_elem = sw_array_size_elem.create_sub_element(ElementName::Vf)?;
849 size_elem.set_character_data(*size)?;
850 }
851
852 let sw_values_phys_elem = parent.create_sub_element(ElementName::SwValuesPhys)?;
853 for value in &self.sw_values_phys {
854 value.store(&sw_values_phys_elem)?;
855 }
856 Ok(())
857 }
858
859 fn load(element: &Element) -> Option<Self> {
860 let sw_array_size_elem = element.get_sub_element(ElementName::SwArraysize)?;
861 let sw_array_size = sw_array_size_elem
862 .sub_elements()
863 .filter_map(|elem| elem.character_data()?.parse_integer())
864 .collect::<Vec<_>>();
865
866 let sw_values_phys_elem = element.get_sub_element(ElementName::SwValuesPhys)?;
867 let sw_values_phys = sw_values_phys_elem
868 .sub_elements()
869 .filter_map(|elem| SwValue::load(&elem))
870 .collect::<Vec<_>>();
871
872 Some(Self {
873 sw_array_size,
874 sw_values_phys,
875 })
876 }
877}
878
879#[derive(Debug, Clone, PartialEq)]
883pub enum SwValue {
884 V(f64),
886 Vf(f64),
888 Vg {
890 label: Option<String>,
892 vg_content: Vec<SwValue>,
894 },
895 Vt(String),
897 VtfNumber(f64),
899 VtfText(String),
901}
902
903impl SwValue {
904 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
905 match self {
906 SwValue::V(value) => {
907 let value_elem = parent.create_sub_element(ElementName::V)?;
908 value_elem.set_character_data(value.to_string())?;
909 }
910 SwValue::Vf(value) => {
911 let value_elem = parent.create_sub_element(ElementName::Vf)?;
912 value_elem.set_character_data(value.to_string())?;
913 }
914 SwValue::Vg { label, vg_content } => {
915 let value_group_elem = parent.create_sub_element(ElementName::Vg)?;
916 if let Some(label) = label {
917 let label_elem = value_group_elem
918 .create_sub_element(ElementName::Label)?
919 .create_sub_element(ElementName::L4)?;
920 label_elem.set_character_data(label.clone())?;
921 }
922 for value in vg_content {
923 value.store(&value_group_elem)?;
924 }
925 }
926 SwValue::Vt(value) => {
927 let value_elem = parent.create_sub_element(ElementName::Vt)?;
928 value_elem.set_character_data(value.clone())?;
929 }
930 SwValue::VtfNumber(value) => {
931 let value_elem = parent
932 .create_sub_element(ElementName::Vtf)?
933 .create_sub_element(ElementName::Vf)?;
934 value_elem.set_character_data(*value)?;
935 }
936 SwValue::VtfText(value) => {
937 let value_elem = parent
938 .create_sub_element(ElementName::Vtf)?
939 .create_sub_element(ElementName::Vt)?;
940 value_elem.set_character_data(value.clone())?;
941 }
942 }
943 Ok(())
944 }
945
946 fn load(element: &Element) -> Option<Self> {
947 let value = match element.element_name() {
948 ElementName::V => {
949 let value = element.character_data()?.parse_float()?;
950 SwValue::V(value)
951 }
952 ElementName::Vf => {
953 let value = element.character_data()?.parse_float()?;
954 SwValue::Vf(value)
955 }
956 ElementName::Vg => {
957 let label = element
958 .get_sub_element(ElementName::Label)
959 .and_then(|label_elem| label_elem.get_sub_element(ElementName::L4))
960 .and_then(|sl_elem| sl_elem.character_data())
961 .and_then(|cdata| cdata.string_value());
962 let vg_content = element
963 .sub_elements()
964 .filter_map(|elem| SwValue::load(&elem))
965 .collect::<Vec<_>>();
966 SwValue::Vg { label, vg_content }
967 }
968 ElementName::Vt => {
969 let value = element.character_data()?.string_value()?;
970 SwValue::Vt(value)
971 }
972 ElementName::Vtf => {
973 if let Some(vf) = element.get_sub_element(ElementName::Vf) {
975 SwValue::VtfNumber(vf.character_data()?.parse_float()?)
976 } else if let Some(vt) = element.get_sub_element(ElementName::Vt) {
977 SwValue::VtfText(vt.character_data()?.string_value()?)
978 } else {
979 return None;
980 }
981 }
982 _ => return None,
983 };
984 Some(value)
985 }
986}
987
988#[derive(Debug, Clone, PartialEq)]
992pub struct RuleBasedAxisCont {
993 pub category: SwAxisContCategory,
995 pub sw_array_size: Vec<u64>,
997 pub sw_axis_index: u64,
999 pub rule_based_values: RuleBasedValueSpecification,
1001 pub unit: Option<Unit>,
1003}
1004
1005impl RuleBasedAxisCont {
1006 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
1007 let axis_cont_elem = parent.create_sub_element(ElementName::RuleBasedAxisCont)?;
1008 let category_elem = axis_cont_elem.create_sub_element(ElementName::Category)?;
1009 category_elem.set_character_data::<EnumItem>(self.category.into())?;
1010 let sw_array_size_elem = axis_cont_elem.create_sub_element(ElementName::SwArraysize)?;
1011 for size in &self.sw_array_size {
1012 let size_elem = sw_array_size_elem.create_sub_element(ElementName::Vf)?;
1013 size_elem.set_character_data(*size)?;
1014 }
1015 let sw_axis_index_elem = axis_cont_elem.create_sub_element(ElementName::SwAxisIndex)?;
1016 sw_axis_index_elem.set_character_data(self.sw_axis_index.to_string())?;
1017 self.rule_based_values.store(&axis_cont_elem)?;
1018
1019 if let Some(unit) = &self.unit {
1020 axis_cont_elem
1021 .create_sub_element(ElementName::UnitRef)
1022 .and_then(|unit_elem| unit_elem.set_reference_target(unit.element()))?;
1023 }
1024
1025 Ok(())
1026 }
1027
1028 fn load(element: &Element) -> Option<Self> {
1029 let category_elem = element.get_sub_element(ElementName::Category)?;
1030 let category = SwAxisContCategory::try_from(category_elem.character_data()?.enum_value()?).ok()?;
1031 let sw_array_size_elem = element.get_sub_element(ElementName::SwArraysize)?;
1032 let sw_array_size = sw_array_size_elem
1035 .sub_elements()
1036 .filter_map(|elem| elem.character_data()?.parse_integer())
1037 .collect::<Vec<_>>();
1038
1039 let sw_axis_index_elem = element.get_sub_element(ElementName::SwAxisIndex)?;
1040 let sw_axis_index = sw_axis_index_elem.character_data()?.parse_integer()?;
1041
1042 let rule_based_values_elem = element.get_sub_element(ElementName::RuleBasedValues)?;
1043 let rule_based_values = RuleBasedValueSpecification::load(&rule_based_values_elem)?;
1044
1045 let unit = element
1046 .get_sub_element(ElementName::UnitRef)
1047 .and_then(|unit_elem| unit_elem.get_reference_target().ok())
1048 .and_then(|unit_elem| Unit::try_from(unit_elem).ok());
1049
1050 Some(Self {
1051 category,
1052 sw_array_size,
1053 sw_axis_index,
1054 rule_based_values,
1055 unit,
1056 })
1057 }
1058}
1059
1060#[derive(Debug, Clone, PartialEq)]
1064pub struct RuleBasedValueCont {
1065 pub rule_based_values: RuleBasedValueSpecification,
1067 pub sw_array_size: Vec<u64>,
1069 pub unit: Option<Unit>,
1071}
1072
1073impl RuleBasedValueCont {
1074 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
1075 let sw_value_cont_elem = parent.create_sub_element(ElementName::SwValueCont)?;
1076 self.rule_based_values.store(&sw_value_cont_elem)?;
1077 let sw_array_size_elem = sw_value_cont_elem.create_sub_element(ElementName::SwArraysize)?;
1078 for size in &self.sw_array_size {
1079 let size_elem = sw_array_size_elem.create_sub_element(ElementName::Vf)?;
1080 size_elem.set_character_data(*size)?;
1081 }
1082 if let Some(unit) = &self.unit {
1083 sw_value_cont_elem
1084 .create_sub_element(ElementName::UnitRef)
1085 .and_then(|unit_elem| unit_elem.set_reference_target(unit.element()))?;
1086 }
1087 Ok(())
1088 }
1089
1090 fn load(element: &Element) -> Option<Self> {
1091 let rule_based_values_elem = element.get_sub_element(ElementName::RuleBasedValues)?;
1092 let rule_based_values = RuleBasedValueSpecification::load(&rule_based_values_elem)?;
1093 let sw_array_size_elem = element.get_sub_element(ElementName::SwArraysize)?;
1094 let sw_array_size = sw_array_size_elem
1095 .sub_elements()
1096 .filter_map(|elem| elem.character_data()?.parse_integer())
1097 .collect::<Vec<_>>();
1098 let unit = element
1099 .get_sub_element(ElementName::UnitRef)
1100 .and_then(|unit_elem| unit_elem.get_reference_target().ok())
1101 .and_then(|unit_elem| Unit::try_from(unit_elem).ok());
1102
1103 Some(Self {
1104 rule_based_values,
1105 sw_array_size,
1106 unit,
1107 })
1108 }
1109}
1110
1111#[derive(Debug, Clone, PartialEq)]
1115pub struct RuleBasedValueSpecification {
1116 pub arguments: Vec<RuleArgument>,
1118 pub max_size_to_fill: Option<u64>,
1120 pub rule: RuleBasedFillUntil,
1122}
1123
1124impl RuleBasedValueSpecification {
1125 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
1126 let rule_based_value_elem = parent.create_sub_element(ElementName::RuleBasedValues)?;
1127 let arguments_elem = rule_based_value_elem
1129 .create_sub_element(ElementName::Argumentss)?
1130 .create_sub_element(ElementName::RuleArguments)?;
1131 for argument in &self.arguments {
1132 argument.store(&arguments_elem)?;
1133 }
1134 if let Some(max_size) = self.max_size_to_fill {
1135 let max_size_elem = rule_based_value_elem.create_sub_element(ElementName::MaxSizeToFill)?;
1136 max_size_elem.set_character_data(max_size.to_string())?;
1137 }
1138 let rule_elem = rule_based_value_elem.create_sub_element(ElementName::Rule)?;
1139 rule_elem.set_character_data(self.rule.to_string())?;
1140 Ok(())
1141 }
1142
1143 fn load(element: &Element) -> Option<Self> {
1144 let arguments = element
1145 .get_sub_element(ElementName::Argumentss)?
1146 .get_sub_element(ElementName::RuleArguments)?
1147 .sub_elements()
1148 .filter_map(|elem| RuleArgument::load(&elem))
1149 .collect::<Vec<_>>();
1150
1151 let max_size_to_fill = element
1152 .get_sub_element(ElementName::MaxSizeToFill)
1153 .and_then(|elem| elem.character_data())
1154 .and_then(|cdata| cdata.parse_integer());
1155
1156 let rule_text = element
1157 .get_sub_element(ElementName::Rule)?
1158 .character_data()?
1159 .string_value()?;
1160 let rule = RuleBasedFillUntil::from_str(&rule_text).ok()?;
1161
1162 Some(Self {
1163 arguments,
1164 max_size_to_fill,
1165 rule,
1166 })
1167 }
1168}
1169
1170#[derive(Debug, Clone, PartialEq)]
1174pub enum CompositeValueSpecification {
1175 Array(ArrayValueSpecification),
1177 Record(RecordValueSpecification),
1179}
1180
1181impl CompositeValueSpecification {
1182 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
1183 match self {
1184 Self::Array(array) => array.store(parent),
1185 Self::Record(record) => record.store(parent),
1186 }
1187 }
1188
1189 fn load(element: &Element) -> Option<Self> {
1190 match element.element_name() {
1191 ElementName::ArrayValueSpecification => ArrayValueSpecification::load(element).map(Self::Array),
1192 ElementName::RecordValueSpecification => RecordValueSpecification::load(element).map(Self::Record),
1193 _ => None,
1194 }
1195 }
1196}
1197
1198#[derive(Debug, Clone, PartialEq)]
1202pub enum CompositeRuleBasedValueArgument {
1203 Application(ApplicationValueSpecification),
1205 ApplicationRuleBased(ApplicationRuleBasedValueSpecification),
1207}
1208
1209impl CompositeRuleBasedValueArgument {
1210 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
1211 match self {
1212 Self::Application(app) => app.store(parent),
1213 Self::ApplicationRuleBased(app_rule) => app_rule.store(parent),
1214 }
1215 }
1216
1217 fn load(element: &Element) -> Option<Self> {
1218 match element.element_name() {
1219 ElementName::ApplicationValueSpecification => {
1220 ApplicationValueSpecification::load(element).map(Self::Application)
1221 }
1222 ElementName::ApplicationRuleBasedValueSpecification => {
1223 ApplicationRuleBasedValueSpecification::load(element).map(Self::ApplicationRuleBased)
1224 }
1225 _ => None,
1226 }
1227 }
1228}
1229
1230#[derive(Debug, Clone, PartialEq)]
1233pub enum RuleArgument {
1235 V(f64),
1237 Vf(f64),
1239 Vt(String),
1241 VtfNumber(f64),
1243 VtfText(String),
1245}
1246
1247impl RuleArgument {
1248 fn store(&self, parent: &Element) -> Result<(), AutosarAbstractionError> {
1249 match self {
1250 RuleArgument::V(value) => {
1251 let value_elem = parent.create_sub_element(ElementName::V)?;
1252 value_elem.set_character_data(value.to_string())?;
1253 }
1254 RuleArgument::Vf(value) => {
1255 let value_elem = parent.create_sub_element(ElementName::Vf)?;
1256 value_elem.set_character_data(value.to_string())?;
1257 }
1258 RuleArgument::Vt(value) => {
1259 let value_elem = parent.create_sub_element(ElementName::Vt)?;
1260 value_elem.set_character_data(value.clone())?;
1261 }
1262 RuleArgument::VtfNumber(value) => {
1263 let value_elem = parent
1264 .create_sub_element(ElementName::Vtf)?
1265 .create_sub_element(ElementName::Vf)?;
1266 value_elem.set_character_data(*value)?;
1267 }
1268 RuleArgument::VtfText(value) => {
1269 let value_elem = parent
1270 .create_sub_element(ElementName::Vtf)?
1271 .create_sub_element(ElementName::Vt)?;
1272 value_elem.set_character_data(value.clone())?;
1273 }
1274 }
1275 Ok(())
1276 }
1277
1278 fn load(element: &Element) -> Option<Self> {
1279 let value = match element.element_name() {
1280 ElementName::V => {
1281 let value = element.character_data()?.parse_float()?;
1282 RuleArgument::V(value)
1283 }
1284 ElementName::Vf => {
1285 let value = element.character_data()?.parse_float()?;
1286 RuleArgument::Vf(value)
1287 }
1288 ElementName::Vt => {
1289 let value = element.character_data()?.string_value()?;
1290 RuleArgument::Vt(value)
1291 }
1292 ElementName::Vtf => {
1293 if let Some(vf) = element.get_sub_element(ElementName::Vf) {
1295 RuleArgument::VtfNumber(vf.character_data()?.parse_float()?)
1296 } else if let Some(vt) = element.get_sub_element(ElementName::Vt) {
1297 RuleArgument::VtfText(vt.character_data()?.string_value()?)
1298 } else {
1299 return None;
1300 }
1301 }
1302 _ => return None,
1303 };
1304 Some(value)
1305 }
1306}
1307
1308#[derive(Debug, Clone, PartialEq, Eq)]
1312pub enum DataPrototype {
1313 ArgumentDataPrototype(ArgumentDataPrototype),
1315 ParameterDataPrototype(ParameterDataPrototype),
1317 VariableDataPrototype(VariableDataPrototype),
1319 ApplicationArrayElement(ApplicationArrayElement),
1321 ApplicationRecordElement(ApplicationRecordElement),
1323}
1324
1325impl TryFrom<Element> for DataPrototype {
1326 type Error = AutosarAbstractionError;
1327
1328 fn try_from(value: Element) -> Result<Self, Self::Error> {
1329 match value.element_name() {
1330 ElementName::ArgumentDataPrototype => {
1331 ArgumentDataPrototype::try_from(value).map(Self::ArgumentDataPrototype)
1332 }
1333 ElementName::ParameterDataPrototype => {
1334 ParameterDataPrototype::try_from(value).map(Self::ParameterDataPrototype)
1335 }
1336 ElementName::VariableDataPrototype => {
1337 VariableDataPrototype::try_from(value).map(Self::VariableDataPrototype)
1338 }
1339 ElementName::Element => ApplicationArrayElement::try_from(value).map(Self::ApplicationArrayElement),
1340 ElementName::ApplicationRecordElement => {
1341 ApplicationRecordElement::try_from(value).map(Self::ApplicationRecordElement)
1342 }
1343 _ => Err(AutosarAbstractionError::ConversionError {
1344 element: value,
1345 dest: "DataPrototype".to_string(),
1346 }),
1347 }
1348 }
1349}
1350
1351impl AbstractionElement for DataPrototype {
1352 fn element(&self) -> &Element {
1353 match self {
1354 DataPrototype::ArgumentDataPrototype(arg) => arg.element(),
1355 DataPrototype::ParameterDataPrototype(param) => param.element(),
1356 DataPrototype::VariableDataPrototype(var) => var.element(),
1357 DataPrototype::ApplicationArrayElement(arr) => arr.element(),
1358 DataPrototype::ApplicationRecordElement(rec) => rec.element(),
1359 }
1360 }
1361}
1362
1363#[cfg(test)]
1366mod test {
1367 use std::vec;
1368
1369 use super::*;
1370 use crate::{
1371 AutosarModelAbstraction,
1372 datatype::{BaseTypeEncoding, ImplementationDataTypeSettings},
1373 software_component::{ArgumentDirection, ClientServerInterface},
1374 };
1375 use autosar_data::AutosarVersion;
1376
1377 #[test]
1378 fn constant_specification() {
1379 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1380 let package = model.get_or_create_package("/Pkg").unwrap();
1381
1382 let constant = package
1383 .create_constant_specification(
1384 "ConstantSpec",
1385 NumericalValueSpecification {
1386 label: None,
1387 value: 12.0,
1388 },
1389 )
1390 .unwrap();
1391 assert_eq!(constant.name().unwrap(), "ConstantSpec");
1392
1393 let spec = ArrayValueSpecification {
1394 label: Some("ArrayValue".to_string()),
1395 values: vec![
1396 NumericalValueSpecification {
1397 label: None,
1398 value: 11.0,
1399 }
1400 .into(),
1401 NumericalValueSpecification {
1402 label: None,
1403 value: 12.3,
1404 }
1405 .into(),
1406 ],
1407 };
1408 constant.set_value_specification(spec.clone()).unwrap();
1409 assert_eq!(constant.value_specification().unwrap(), spec.into());
1410 }
1411
1412 #[test]
1413 fn numerical_value_specification() {
1414 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1415 let package = model.get_or_create_package("/Pkg").unwrap();
1416
1417 let spec = NumericalValueSpecification {
1418 label: Some("NumericalValue".to_string()),
1419 value: 33.3,
1420 };
1421 let constant = package
1422 .create_constant_specification("ConstantSpec", spec.clone())
1423 .unwrap();
1424 let spec_read = constant.value_specification().unwrap();
1425 assert_eq!(spec_read, spec.into());
1426 }
1427
1428 #[test]
1429 fn array_value_specification() {
1430 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1431 let package = model.get_or_create_package("/Pkg").unwrap();
1432
1433 let spec = ArrayValueSpecification {
1434 label: Some("ArrayValue".to_string()),
1435 values: vec![
1436 NumericalValueSpecification {
1437 label: None,
1438 value: 11.0,
1439 }
1440 .into(),
1441 NumericalValueSpecification {
1442 label: None,
1443 value: 12.3,
1444 }
1445 .into(),
1446 ],
1447 };
1448 let constant = package
1449 .create_constant_specification("ConstantSpec", spec.clone())
1450 .unwrap();
1451 let spec_read = constant.value_specification().unwrap();
1452 assert_eq!(spec_read, spec.into());
1453 }
1454
1455 #[test]
1456 fn record_value_specification() {
1457 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1458 let package = model.get_or_create_package("/Pkg").unwrap();
1459
1460 let spec = RecordValueSpecification {
1461 label: Some("RecordValue".to_string()),
1462 values: vec![
1463 NumericalValueSpecification {
1464 label: None,
1465 value: 1.0,
1466 }
1467 .into(),
1468 NumericalValueSpecification {
1469 label: None,
1470 value: 3.1,
1471 }
1472 .into(),
1473 ],
1474 };
1475 let constant = package
1476 .create_constant_specification("ConstantSpec", spec.clone())
1477 .unwrap();
1478 let spec_read = constant.value_specification().unwrap();
1479 assert_eq!(spec_read, spec.into());
1480 }
1481
1482 #[test]
1483 fn text_value_specification() {
1484 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1485 let package = model.get_or_create_package("/Pkg").unwrap();
1486
1487 let spec = TextValueSpecification {
1488 label: Some("TextValue".to_string()),
1489 value: "Hello World".to_string(),
1490 };
1491 let constant = package
1492 .create_constant_specification("ConstantSpec", spec.clone())
1493 .unwrap();
1494 let spec_read = constant.value_specification().unwrap();
1495 assert_eq!(spec_read, spec.into());
1496 }
1497
1498 #[test]
1499 fn reference_value_specification() {
1500 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1501 let package = model.get_or_create_package("/Pkg").unwrap();
1502
1503 let base_type = package
1504 .create_sw_base_type("base", 32, BaseTypeEncoding::None, None, None, None)
1505 .unwrap();
1506 let impl_settings = ImplementationDataTypeSettings::Value {
1507 name: "ImplementationValue".to_string(),
1508 base_type,
1509 compu_method: None,
1510 data_constraint: None,
1511 };
1512 let datatype = package.create_implementation_data_type(&impl_settings).unwrap();
1513 let app_data_type = package
1514 .create_application_primitive_data_type(
1515 "AppDataType",
1516 ApplicationPrimitiveCategory::Value,
1517 None,
1518 None,
1519 None,
1520 )
1521 .unwrap();
1522
1523 let client_server_interface = ClientServerInterface::new("CS_Interface", &package).unwrap();
1526 let cs_operation = client_server_interface.create_operation("Operation").unwrap();
1527 let argument_data_prototype = cs_operation
1528 .create_argument("adp", &datatype, ArgumentDirection::In)
1529 .unwrap();
1530
1531 let spec = ReferenceValueSpecification {
1532 label: Some("ReferenceValue".to_string()),
1533 reference_value: DataPrototype::ArgumentDataPrototype(argument_data_prototype),
1534 };
1535 let constant = package
1536 .create_constant_specification("ConstantSpec1", spec.clone())
1537 .unwrap();
1538 let spec_read = constant.value_specification().unwrap();
1539 assert_eq!(spec_read, spec.into());
1540
1541 let parameter_interface = package.create_parameter_interface("P_Interface").unwrap();
1543 let parameter_data_prototype = parameter_interface.create_parameter("pdp", &datatype).unwrap();
1544
1545 let spec = ReferenceValueSpecification {
1546 label: Some("ReferenceValue".to_string()),
1547 reference_value: DataPrototype::ParameterDataPrototype(parameter_data_prototype),
1548 };
1549 let constant = package
1550 .create_constant_specification("ConstantSpec2", spec.clone())
1551 .unwrap();
1552 let spec_read = constant.value_specification().unwrap();
1553 assert_eq!(spec_read, spec.into());
1554
1555 let sender_receiver_interface = package.create_sender_receiver_interface("SR_Interface").unwrap();
1557 let variable_data_prototype = sender_receiver_interface.create_data_element("vdp", &datatype).unwrap();
1558
1559 let spec = ReferenceValueSpecification {
1560 label: Some("ReferenceValue".to_string()),
1561 reference_value: DataPrototype::VariableDataPrototype(variable_data_prototype),
1562 };
1563 let constant = package
1564 .create_constant_specification("ConstantSpec3", spec.clone())
1565 .unwrap();
1566 let spec_read = constant.value_specification().unwrap();
1567 assert_eq!(spec_read, spec.into());
1568
1569 let application_array_data_type = package
1571 .create_application_array_data_type(
1572 "ArrayDataType",
1573 &app_data_type,
1574 crate::datatype::ApplicationArraySize::Fixed(1),
1575 )
1576 .unwrap();
1577 let application_array_element = application_array_data_type.array_element().unwrap();
1578
1579 let spec = ReferenceValueSpecification {
1580 label: Some("ReferenceValue".to_string()),
1581 reference_value: DataPrototype::ApplicationArrayElement(application_array_element),
1582 };
1583 let constant = package
1584 .create_constant_specification("ConstantSpec4", spec.clone())
1585 .unwrap();
1586 let spec_read = constant.value_specification().unwrap();
1587 assert_eq!(spec_read, spec.into());
1588
1589 let application_record_data_type = package.create_application_record_data_type("RecordDataType").unwrap();
1591 let application_record_element = application_record_data_type
1592 .create_record_element("Element", &app_data_type)
1593 .unwrap();
1594
1595 let spec = ReferenceValueSpecification {
1596 label: Some("ReferenceValue".to_string()),
1597 reference_value: DataPrototype::ApplicationRecordElement(application_record_element),
1598 };
1599 let constant = package
1600 .create_constant_specification("ConstantSpec5", spec.clone())
1601 .unwrap();
1602 let spec_read = constant.value_specification().unwrap();
1603 assert_eq!(spec_read, spec.into());
1604 }
1605
1606 #[test]
1607 fn constant_reference_specification() {
1608 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1609 let package = model.get_or_create_package("/Pkg").unwrap();
1610
1611 let spec = NumericalValueSpecification {
1612 label: None,
1613 value: 1.0,
1614 };
1615 let target_constant = package.create_constant_specification("Target", spec).unwrap();
1616
1617 let spec = ConstantReference {
1618 label: Some("ConstantReference".to_string()),
1619 constant: target_constant,
1620 };
1621 let constant = package
1622 .create_constant_specification("ConstantSpec", spec.clone())
1623 .unwrap();
1624 let spec_read = constant.value_specification().unwrap();
1625 assert_eq!(spec_read, spec.into());
1626 }
1627
1628 #[test]
1629 fn application_value_specification() {
1630 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1631 let package = model.get_or_create_package("/Pkg").unwrap();
1632 let unit = package.create_unit("abc", Some("display_name")).unwrap();
1633
1634 let spec = ApplicationValueSpecification {
1635 label: Some("ApplicationValue".to_string()),
1636 category: ApplicationPrimitiveCategory::ResAxis,
1637 sw_axis_conts: vec![
1638 SwAxisCont {
1639 category: SwAxisContCategory::StdAxis,
1640 sw_array_size: vec![1, 2],
1641 sw_axis_index: 1,
1642 sw_values_phys: vec![SwValue::V(0.0), SwValue::Vf(1.0), SwValue::Vt("text".to_string())],
1643 unit: Some(unit),
1644 unit_display_name: Some("display_name".to_string()),
1645 },
1646 SwAxisCont {
1647 category: SwAxisContCategory::ComAxis,
1648 sw_array_size: vec![3, 4],
1649 sw_axis_index: 2,
1650 sw_values_phys: vec![
1651 SwValue::Vg {
1652 label: Some("label".to_string()),
1653 vg_content: vec![SwValue::VtfNumber(42.0)],
1654 },
1655 SwValue::VtfText("text".to_string()),
1656 ],
1657 unit: None,
1658 unit_display_name: None,
1659 },
1660 ],
1661 sw_value_cont: SwValueCont {
1662 sw_array_size: vec![1, 2],
1663 sw_values_phys: vec![SwValue::Vf(0.0), SwValue::Vf(1.0)],
1664 },
1665 };
1666 let constant = package
1667 .create_constant_specification("ConstantSpec", spec.clone())
1668 .unwrap();
1669 let spec_read = constant.value_specification().unwrap();
1670 assert_eq!(spec_read, spec.into());
1671 }
1672
1673 #[test]
1674 fn not_available_value_specification() {
1675 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1676 let package = model.get_or_create_package("/Pkg").unwrap();
1677
1678 let spec = NotAvailableValueSpecification {
1679 label: Some("NotAvailableValue".to_string()),
1680 default_pattern: Some(0x11),
1681 };
1682 let constant = package
1683 .create_constant_specification("ConstantSpec", spec.clone())
1684 .unwrap();
1685 let spec_read = constant.value_specification().unwrap();
1686 assert_eq!(spec_read, spec.into());
1687 }
1688
1689 #[test]
1690 fn aplication_rule_based_value_specification() {
1691 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1692 let package = model.get_or_create_package("/Pkg").unwrap();
1693 let unit = package.create_unit("abc", Some("display_name")).unwrap();
1694
1695 let spec = ApplicationRuleBasedValueSpecification {
1696 label: Some("ApplicationRuleBasedValue".to_string()),
1697 category: ApplicationPrimitiveCategory::ResAxis,
1698 sw_axis_cont: vec![
1699 RuleBasedAxisCont {
1700 category: SwAxisContCategory::StdAxis,
1701 sw_array_size: vec![1, 2],
1702 sw_axis_index: 1,
1703 rule_based_values: RuleBasedValueSpecification {
1704 arguments: vec![
1705 RuleArgument::V(0.0),
1706 RuleArgument::Vf(1.0),
1707 RuleArgument::Vt("text".to_string()),
1708 RuleArgument::VtfNumber(2.0),
1709 RuleArgument::VtfText("text2".to_string()),
1710 ],
1711 max_size_to_fill: Some(10),
1712 rule: RuleBasedFillUntil::MaxSize,
1713 },
1714 unit: Some(unit.clone()),
1715 },
1716 RuleBasedAxisCont {
1717 category: SwAxisContCategory::ComAxis,
1718 sw_array_size: vec![3, 4],
1719 sw_axis_index: 2,
1720 rule_based_values: RuleBasedValueSpecification {
1721 arguments: vec![RuleArgument::Vf(0.0), RuleArgument::Vf(1.0)],
1722 max_size_to_fill: None,
1723 rule: RuleBasedFillUntil::End,
1724 },
1725 unit: None,
1726 },
1727 ],
1728 sw_value_cont: RuleBasedValueCont {
1729 rule_based_values: RuleBasedValueSpecification {
1730 arguments: vec![RuleArgument::Vf(0.0), RuleArgument::Vf(1.0)],
1731 max_size_to_fill: None,
1732 rule: RuleBasedFillUntil::End,
1733 },
1734 sw_array_size: vec![1, 2],
1735 unit: Some(unit),
1736 },
1737 };
1738 let constant = package
1739 .create_constant_specification("ConstantSpec", spec.clone())
1740 .unwrap();
1741 let spec_read = constant.value_specification().unwrap();
1742 assert_eq!(spec_read, spec.into());
1743 }
1744
1745 #[test]
1746 fn composite_rule_based_value_specification() {
1747 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1748 let package = model.get_or_create_package("/Pkg").unwrap();
1749
1750 let spec = CompositeRuleBasedValueSpecification {
1751 label: Some("CompositeRuleBasedValue".to_string()),
1752 argument: vec![CompositeValueSpecification::Array(ArrayValueSpecification {
1753 label: Some("ArrayValue".to_string()),
1754 values: vec![
1755 NumericalValueSpecification {
1756 label: None,
1757 value: 123.4,
1758 }
1759 .into(),
1760 NumericalValueSpecification {
1761 label: None,
1762 value: 0.12345,
1763 }
1764 .into(),
1765 ],
1766 })],
1767 compound_primitive_argument: vec![
1768 CompositeRuleBasedValueArgument::Application(ApplicationValueSpecification {
1769 label: Some("ApplicationValue".to_string()),
1770 category: ApplicationPrimitiveCategory::ResAxis,
1771 sw_axis_conts: vec![],
1772 sw_value_cont: SwValueCont {
1773 sw_array_size: vec![1, 2],
1774 sw_values_phys: vec![SwValue::Vf(0.0), SwValue::Vf(1.0)],
1775 },
1776 }),
1777 CompositeRuleBasedValueArgument::ApplicationRuleBased(ApplicationRuleBasedValueSpecification {
1778 label: Some("ApplicationRuleBasedValue".to_string()),
1779 category: ApplicationPrimitiveCategory::ResAxis,
1780 sw_axis_cont: vec![],
1781 sw_value_cont: RuleBasedValueCont {
1782 rule_based_values: RuleBasedValueSpecification {
1783 arguments: vec![RuleArgument::Vf(0.0), RuleArgument::Vf(1.0)],
1784 max_size_to_fill: None,
1785 rule: RuleBasedFillUntil::End,
1786 },
1787 sw_array_size: vec![1, 2],
1788 unit: None,
1789 },
1790 }),
1791 ],
1792 max_size_to_fill: Some(10),
1793 rule: RuleBasedFillUntil::MaxSize,
1794 };
1795 let constant = package
1796 .create_constant_specification("ConstantSpec", spec.clone())
1797 .unwrap();
1798 let spec_read = constant.value_specification().unwrap();
1799 assert_eq!(spec_read, spec.into());
1800 }
1801
1802 #[test]
1803 fn numerical_rule_based_value_specification() {
1804 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
1805 let package = model.get_or_create_package("/Pkg").unwrap();
1806
1807 let spec = NumericalRuleBasedValueSpecification {
1808 label: Some("NumericalRuleBasedValue".to_string()),
1809 rule_based_values: RuleBasedValueSpecification {
1810 arguments: vec![RuleArgument::Vf(0.0), RuleArgument::Vf(1.0)],
1811 max_size_to_fill: Some(10),
1812 rule: RuleBasedFillUntil::MaxSize,
1813 },
1814 };
1815 let constant = package
1816 .create_constant_specification("ConstantSpec", spec.clone())
1817 .unwrap();
1818 let spec_read = constant.value_specification().unwrap();
1819 assert_eq!(spec_read, spec.into());
1820 }
1821
1822 #[test]
1823 fn conversions() {
1824 let value = RuleBasedFillUntil::End;
1826 let value_str = value.to_string();
1827 assert_eq!(value_str, "FILL_UNTIL_END");
1828 assert_eq!(RuleBasedFillUntil::from_str(&value_str).unwrap(), value);
1829
1830 let value = RuleBasedFillUntil::MaxSize;
1831 let value_str = value.to_string();
1832 assert_eq!(value_str, "FILL_UNTIL_MAX_SIZE");
1833 assert_eq!(RuleBasedFillUntil::from_str(&value_str).unwrap(), value);
1834
1835 let value = SwAxisContCategory::StdAxis;
1837 let enum_val: EnumItem = value.into();
1838 assert_eq!(enum_val, EnumItem::Stdaxis);
1839 assert_eq!(SwAxisContCategory::try_from(enum_val).unwrap(), value);
1840 let enum_val = EnumItem::StdAxis;
1842 assert_eq!(SwAxisContCategory::try_from(enum_val).unwrap(), value);
1843
1844 let value = SwAxisContCategory::ComAxis;
1845 let enum_val: EnumItem = value.into();
1846 assert_eq!(enum_val, EnumItem::Comaxis);
1847 assert_eq!(SwAxisContCategory::try_from(enum_val).unwrap(), value);
1848 let enum_val = EnumItem::ComAxis;
1850 assert_eq!(SwAxisContCategory::try_from(enum_val).unwrap(), value);
1851
1852 let value = SwAxisContCategory::ResAxis;
1853 let enum_val: EnumItem = value.into();
1854 assert_eq!(enum_val, EnumItem::Resaxis);
1855 assert_eq!(SwAxisContCategory::try_from(enum_val).unwrap(), value);
1856 let enum_val = EnumItem::ResAxis;
1858 assert_eq!(SwAxisContCategory::try_from(enum_val).unwrap(), value);
1859
1860 assert!(SwAxisContCategory::try_from(EnumItem::Aa).is_err());
1862 }
1863}