1use crate::{
2 AbstractionElement, ArPackage, AutosarAbstractionError, Element, IdentifiableAbstractionElement,
3 abstraction_element, datatype,
4};
5use autosar_data::{ElementName, EnumItem};
6use datatype::{AbstractAutosarDataType, CompuMethod, DataConstr, Unit};
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
14pub struct ApplicationArrayDataType(Element);
15abstraction_element!(ApplicationArrayDataType, ApplicationArrayDataType);
16impl IdentifiableAbstractionElement for ApplicationArrayDataType {}
17impl AbstractAutosarDataType for ApplicationArrayDataType {}
18
19impl ApplicationArrayDataType {
20 pub(crate) fn new<T: Into<ApplicationDataType> + AbstractionElement>(
22 name: &str,
23 package: &ArPackage,
24 element_type: &T,
25 size: ApplicationArraySize,
26 ) -> Result<Self, AutosarAbstractionError> {
27 let element_type = element_type.clone().into();
28 Self::new_internal(name, package, &element_type, size)
29 }
30
31 fn new_internal(
32 name: &str,
33 package: &ArPackage,
34 element_type: &ApplicationDataType,
35 size: ApplicationArraySize,
36 ) -> Result<Self, AutosarAbstractionError> {
37 let elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
38 let application_array_data_type =
39 elements.create_named_sub_element(ElementName::ApplicationArrayDataType, name)?;
40
41 application_array_data_type
42 .create_sub_element(ElementName::Category)?
43 .set_character_data("ARRAY")?;
44
45 let application_array_data_type = Self(application_array_data_type);
46 ApplicationArrayElement::new("Element", &application_array_data_type, element_type)?;
47
48 application_array_data_type.set_size(size)?;
50
51 Ok(application_array_data_type)
52 }
53
54 #[must_use]
56 pub fn array_element(&self) -> Option<ApplicationArrayElement> {
57 self.element().get_sub_element(ElementName::Element)?.try_into().ok()
58 }
59
60 pub fn set_size(&self, size: ApplicationArraySize) -> Result<(), AutosarAbstractionError> {
62 let array_element = self.array_element().ok_or(AutosarAbstractionError::InvalidParameter(
63 "Array data type has no array element".to_string(),
64 ))?;
65 if let Some(datatype) = array_element.data_type() {
66 let is_array_datatype = matches!(datatype, ApplicationDataType::Array(_));
67 if is_array_datatype && matches!(size, ApplicationArraySize::VariableLinear(_)) {
68 return Err(AutosarAbstractionError::InvalidParameter(
69 "When the size type is VariableLinear, the element type may not be an array".to_string(),
70 ));
71 } else if !is_array_datatype
72 && matches!(
73 size,
74 ApplicationArraySize::VariableSquare
75 | ApplicationArraySize::VariableRectangular(_)
76 | ApplicationArraySize::VariableFullyFlexible(_)
77 )
78 {
79 return Err(AutosarAbstractionError::InvalidParameter(
80 "When the size type is VariableSquare, VariableRectangular or VariableFullyFlexible, the element type must be an array".to_string(),
81 ));
82 }
83 }
84 let array_element_elem = array_element.element();
85 match size {
86 ApplicationArraySize::Fixed(size) => {
87 let _ = self
88 .element()
89 .remove_sub_element_kind(ElementName::DynamicArraySizeProfile);
90 array_element_elem
91 .get_or_create_sub_element(ElementName::MaxNumberOfElements)?
92 .set_character_data(size)?;
93 array_element_elem
94 .get_or_create_sub_element(ElementName::ArraySizeSemantics)?
95 .set_character_data(EnumItem::FixedSize)?;
96 let _ = array_element_elem.remove_sub_element_kind(ElementName::ArraySizeHandling);
97 }
98 ApplicationArraySize::VariableLinear(max_size) => {
99 self.element()
100 .get_or_create_sub_element(ElementName::DynamicArraySizeProfile)?
101 .set_character_data("VSA_LINEAR")?;
102 array_element_elem
103 .get_or_create_sub_element(ElementName::MaxNumberOfElements)?
104 .set_character_data(max_size)?;
105 array_element_elem
106 .get_or_create_sub_element(ElementName::ArraySizeSemantics)?
107 .set_character_data(EnumItem::VariableSize)?;
108 array_element_elem
109 .get_or_create_sub_element(ElementName::ArraySizeHandling)?
110 .set_character_data(EnumItem::AllIndicesSameArraySize)?;
111 }
112 ApplicationArraySize::VariableSquare => {
113 self.element()
114 .get_or_create_sub_element(ElementName::DynamicArraySizeProfile)?
115 .set_character_data("VSA_SQUARE")?;
116 let _ = array_element_elem.remove_sub_element_kind(ElementName::MaxNumberOfElements);
117 array_element_elem
118 .get_or_create_sub_element(ElementName::ArraySizeSemantics)?
119 .set_character_data(EnumItem::VariableSize)?;
120 array_element_elem
121 .get_or_create_sub_element(ElementName::ArraySizeHandling)?
122 .set_character_data(EnumItem::InheritedFromArrayElementTypeSize)?;
123 }
124 ApplicationArraySize::VariableRectangular(max_size) => {
125 self.element()
126 .get_or_create_sub_element(ElementName::DynamicArraySizeProfile)?
127 .set_character_data("VSA_RECTANGULAR")?;
128 array_element_elem
129 .get_or_create_sub_element(ElementName::MaxNumberOfElements)?
130 .set_character_data(max_size)?;
131 array_element_elem
132 .get_or_create_sub_element(ElementName::ArraySizeSemantics)?
133 .set_character_data(EnumItem::VariableSize)?;
134 array_element_elem
135 .get_or_create_sub_element(ElementName::ArraySizeHandling)?
136 .set_character_data(EnumItem::AllIndicesSameArraySize)?;
137 }
138 ApplicationArraySize::VariableFullyFlexible(max_size) => {
139 self.element()
140 .get_or_create_sub_element(ElementName::DynamicArraySizeProfile)?
141 .set_character_data("VSA_FULLY_FLEXIBLE")?;
142 array_element_elem
143 .get_or_create_sub_element(ElementName::MaxNumberOfElements)?
144 .set_character_data(max_size)?;
145 array_element_elem
146 .get_or_create_sub_element(ElementName::ArraySizeSemantics)?
147 .set_character_data(EnumItem::VariableSize)?;
148 array_element_elem
149 .get_or_create_sub_element(ElementName::ArraySizeHandling)?
150 .set_character_data(EnumItem::AllIndicesDifferentArraySize)?;
151 }
152 }
153
154 Ok(())
155 }
156
157 #[must_use]
159 pub fn size(&self) -> Option<ApplicationArraySize> {
160 let max_number_of_elements = self
161 .array_element()?
162 .element()
163 .get_sub_element(ElementName::MaxNumberOfElements);
164
165 if let Some(size_profile) = self
166 .element()
167 .get_sub_element(ElementName::DynamicArraySizeProfile)
168 .and_then(|elem| elem.character_data().and_then(|cdata| cdata.string_value()))
169 {
170 match size_profile.as_str() {
171 "VSA_LINEAR" => {
172 let max_size = max_number_of_elements?.character_data()?.parse_integer()?;
173 Some(ApplicationArraySize::VariableLinear(max_size))
174 }
175 "VSA_SQUARE" => Some(ApplicationArraySize::VariableSquare),
176 "VSA_RECTANGULAR" => {
177 let max_size = max_number_of_elements?.character_data()?.parse_integer()?;
178 Some(ApplicationArraySize::VariableRectangular(max_size))
179 }
180 "VSA_FULLY_FLEXIBLE" => {
181 let max_size = max_number_of_elements?.character_data()?.parse_integer()?;
182 Some(ApplicationArraySize::VariableFullyFlexible(max_size))
183 }
184 _ => None,
185 }
186 } else {
187 let size = max_number_of_elements?.character_data()?.parse_integer()?;
188 Some(ApplicationArraySize::Fixed(size))
189 }
190 }
191}
192
193#[derive(Debug, Clone, PartialEq, Eq, Hash)]
197pub enum ApplicationArraySize {
198 Fixed(u64),
200 VariableLinear(u64),
202 VariableSquare,
206 VariableRectangular(u64),
209 VariableFullyFlexible(u64),
212}
213
214#[derive(Debug, Clone, PartialEq, Eq, Hash)]
218pub struct ApplicationArrayElement(Element);
219abstraction_element!(ApplicationArrayElement, Element);
220impl IdentifiableAbstractionElement for ApplicationArrayElement {}
221
222impl ApplicationArrayElement {
223 fn new(
224 name: &str,
225 parent: &ApplicationArrayDataType,
226 data_type: &ApplicationDataType,
227 ) -> Result<Self, AutosarAbstractionError> {
228 let application_array_element = parent.element().create_named_sub_element(ElementName::Element, name)?;
229 let application_array_element = Self(application_array_element);
230
231 application_array_element.set_data_type(data_type)?;
232
233 Ok(application_array_element)
234 }
235
236 pub fn set_data_type<T: Into<ApplicationDataType> + AbstractionElement>(
238 &self,
239 data_type: &T,
240 ) -> Result<(), AutosarAbstractionError> {
241 let data_type: ApplicationDataType = data_type.clone().into();
242 self.element()
243 .get_or_create_sub_element(ElementName::TypeTref)?
244 .set_reference_target(data_type.element())?;
245 if let Some(category) = data_type.category() {
247 self.element()
248 .get_or_create_sub_element(ElementName::Category)?
249 .set_character_data(category)?;
250 } else {
251 let _ = self.element().remove_sub_element_kind(ElementName::Category);
253 }
254
255 Ok(())
256 }
257
258 #[must_use]
260 pub fn data_type(&self) -> Option<ApplicationDataType> {
261 self.element()
262 .get_sub_element(ElementName::TypeTref)?
263 .get_reference_target()
264 .ok()?
265 .try_into()
266 .ok()
267 }
268}
269
270#[derive(Debug, Clone, PartialEq, Eq, Hash)]
276pub struct ApplicationRecordDataType(Element);
277abstraction_element!(ApplicationRecordDataType, ApplicationRecordDataType);
278impl IdentifiableAbstractionElement for ApplicationRecordDataType {}
279impl AbstractAutosarDataType for ApplicationRecordDataType {}
280
281impl ApplicationRecordDataType {
282 pub(crate) fn new(name: &str, package: &ArPackage) -> Result<Self, AutosarAbstractionError> {
284 let elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
285 let application_record_data_type =
286 elements.create_named_sub_element(ElementName::ApplicationRecordDataType, name)?;
287
288 application_record_data_type
289 .create_sub_element(ElementName::Category)?
290 .set_character_data("STRUCTURE")?;
291
292 Ok(Self(application_record_data_type))
293 }
294
295 pub fn create_record_element<T: Into<ApplicationDataType> + Clone>(
297 &self,
298 name: &str,
299 data_type: &T,
300 ) -> Result<ApplicationRecordElement, AutosarAbstractionError> {
301 ApplicationRecordElement::new(name, self, &data_type.clone().into())
302 }
303
304 pub fn record_elements(&self) -> impl Iterator<Item = ApplicationRecordElement> + Send + 'static {
306 self.element()
307 .get_sub_element(ElementName::Elements)
308 .into_iter()
309 .flat_map(|elements| elements.sub_elements())
310 .filter_map(|element| ApplicationRecordElement::try_from(element).ok())
311 }
312}
313
314#[derive(Debug, Clone, PartialEq, Eq, Hash)]
318pub struct ApplicationRecordElement(Element);
319abstraction_element!(ApplicationRecordElement, ApplicationRecordElement);
320impl IdentifiableAbstractionElement for ApplicationRecordElement {}
321
322impl ApplicationRecordElement {
323 fn new(
324 name: &str,
325 parent: &ApplicationRecordDataType,
326 data_type: &ApplicationDataType,
327 ) -> Result<Self, AutosarAbstractionError> {
328 let application_record_element = parent
329 .element()
330 .get_or_create_sub_element(ElementName::Elements)?
331 .create_named_sub_element(ElementName::ApplicationRecordElement, name)?;
332
333 let application_record_element = Self(application_record_element);
334 application_record_element.set_data_type(data_type)?;
335
336 Ok(application_record_element)
337 }
338
339 pub fn set_data_type<T: Into<ApplicationDataType> + AbstractionElement>(
341 &self,
342 data_type: &T,
343 ) -> Result<(), AutosarAbstractionError> {
344 let data_type: ApplicationDataType = data_type.clone().into();
345 self.element()
346 .get_or_create_sub_element(ElementName::TypeTref)?
347 .set_reference_target(data_type.element())?;
348 if let Some(category) = data_type.category() {
349 self.element()
350 .get_or_create_sub_element(ElementName::Category)?
351 .set_character_data(category)?;
352 } else {
353 let _ = self.element().remove_sub_element_kind(ElementName::Category);
355 }
356
357 Ok(())
358 }
359
360 #[must_use]
362 pub fn data_type(&self) -> Option<ApplicationDataType> {
363 self.element()
364 .get_sub_element(ElementName::TypeTref)?
365 .get_reference_target()
366 .ok()?
367 .try_into()
368 .ok()
369 }
370}
371
372#[derive(Debug, Clone, PartialEq, Eq, Hash)]
378pub struct ApplicationPrimitiveDataType(Element);
379abstraction_element!(ApplicationPrimitiveDataType, ApplicationPrimitiveDataType);
380impl IdentifiableAbstractionElement for ApplicationPrimitiveDataType {}
381impl AbstractAutosarDataType for ApplicationPrimitiveDataType {}
382
383impl ApplicationPrimitiveDataType {
384 pub(crate) fn new(
386 name: &str,
387 package: &ArPackage,
388 category: ApplicationPrimitiveCategory,
389 compu_method: Option<&CompuMethod>,
390 unit: Option<&Unit>,
391 data_constraint: Option<&DataConstr>,
392 ) -> Result<Self, AutosarAbstractionError> {
393 let elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
394 let application_primitive_data_type =
395 elements.create_named_sub_element(ElementName::ApplicationPrimitiveDataType, name)?;
396
397 let application_primitive_data_type = Self(application_primitive_data_type);
398
399 application_primitive_data_type.set_category(category)?;
400 application_primitive_data_type.set_compu_method(compu_method)?;
401 application_primitive_data_type.set_unit(unit)?;
402 application_primitive_data_type.set_data_constraint(data_constraint)?;
403
404 Ok(application_primitive_data_type)
405 }
406
407 pub fn set_category(&self, category: ApplicationPrimitiveCategory) -> Result<(), AutosarAbstractionError> {
409 self.element()
410 .get_or_create_sub_element(ElementName::Category)?
411 .set_character_data(category.to_string())?;
412
413 Ok(())
414 }
415
416 #[must_use]
418 pub fn category(&self) -> Option<ApplicationPrimitiveCategory> {
419 self.element()
420 .get_sub_element(ElementName::Category)?
421 .character_data()?
422 .string_value()?
423 .parse()
424 .ok()
425 }
426
427 pub fn set_compu_method(&self, compu_method: Option<&CompuMethod>) -> Result<(), AutosarAbstractionError> {
429 if let Some(compu_method) = compu_method {
430 self.element()
431 .get_or_create_sub_element(ElementName::SwDataDefProps)?
432 .get_or_create_sub_element(ElementName::SwDataDefPropsVariants)?
433 .get_or_create_sub_element(ElementName::SwDataDefPropsConditional)?
434 .get_or_create_sub_element(ElementName::CompuMethodRef)?
435 .set_reference_target(compu_method.element())?;
436 } else {
437 let _ = self
438 .element()
439 .get_sub_element(ElementName::SwDataDefProps)
440 .and_then(|sddp| sddp.get_sub_element(ElementName::SwDataDefPropsVariants))
441 .and_then(|sddpv| sddpv.get_sub_element(ElementName::SwDataDefPropsConditional))
442 .and_then(|sddpc| sddpc.remove_sub_element_kind(ElementName::CompuMethodRef).ok());
443 }
444
445 Ok(())
446 }
447
448 #[must_use]
450 pub fn compu_method(&self) -> Option<CompuMethod> {
451 self.element()
452 .get_sub_element(ElementName::SwDataDefProps)?
453 .get_sub_element(ElementName::SwDataDefPropsVariants)?
454 .get_sub_element(ElementName::SwDataDefPropsConditional)?
455 .get_sub_element(ElementName::CompuMethodRef)?
456 .get_reference_target()
457 .ok()?
458 .try_into()
459 .ok()
460 }
461
462 pub fn set_unit(&self, unit: Option<&Unit>) -> Result<(), AutosarAbstractionError> {
464 if let Some(unit) = unit {
465 self.element()
466 .get_or_create_sub_element(ElementName::SwDataDefProps)?
467 .get_or_create_sub_element(ElementName::SwDataDefPropsVariants)?
468 .get_or_create_sub_element(ElementName::SwDataDefPropsConditional)?
469 .get_or_create_sub_element(ElementName::UnitRef)?
470 .set_reference_target(unit.element())?;
471 } else {
472 let _ = self
473 .element()
474 .get_sub_element(ElementName::SwDataDefProps)
475 .and_then(|sddp| sddp.get_sub_element(ElementName::SwDataDefPropsVariants))
476 .and_then(|sddpv| sddpv.get_sub_element(ElementName::SwDataDefPropsConditional))
477 .and_then(|sddpc| sddpc.remove_sub_element_kind(ElementName::UnitRef).ok());
478 }
479
480 Ok(())
481 }
482
483 #[must_use]
485 pub fn unit(&self) -> Option<Unit> {
486 self.element()
487 .get_sub_element(ElementName::SwDataDefProps)?
488 .get_sub_element(ElementName::SwDataDefPropsVariants)?
489 .get_sub_element(ElementName::SwDataDefPropsConditional)?
490 .get_sub_element(ElementName::UnitRef)?
491 .get_reference_target()
492 .ok()?
493 .try_into()
494 .ok()
495 }
496
497 pub fn set_data_constraint(&self, data_constraint: Option<&DataConstr>) -> Result<(), AutosarAbstractionError> {
499 if let Some(data_constraint) = data_constraint {
500 self.element()
501 .get_or_create_sub_element(ElementName::SwDataDefProps)?
502 .get_or_create_sub_element(ElementName::SwDataDefPropsVariants)?
503 .get_or_create_sub_element(ElementName::SwDataDefPropsConditional)?
504 .get_or_create_sub_element(ElementName::DataConstrRef)?
505 .set_reference_target(data_constraint.element())?;
506 } else {
507 let _ = self
508 .element()
509 .get_sub_element(ElementName::SwDataDefProps)
510 .and_then(|sddp| sddp.get_sub_element(ElementName::SwDataDefPropsVariants))
511 .and_then(|sddpv| sddpv.get_sub_element(ElementName::SwDataDefPropsConditional))
512 .and_then(|sddpc| sddpc.remove_sub_element_kind(ElementName::DataConstrRef).ok());
513 }
514
515 Ok(())
516 }
517
518 #[must_use]
520 pub fn data_constraint(&self) -> Option<DataConstr> {
521 self.element()
522 .get_sub_element(ElementName::SwDataDefProps)?
523 .get_sub_element(ElementName::SwDataDefPropsVariants)?
524 .get_sub_element(ElementName::SwDataDefPropsConditional)?
525 .get_sub_element(ElementName::DataConstrRef)?
526 .get_reference_target()
527 .ok()?
528 .try_into()
529 .ok()
530 }
531}
532
533#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
537pub enum ApplicationPrimitiveCategory {
538 Value,
540 ValBlk,
542 String,
544 Boolean,
546 ComAxis,
548 ResAxis,
550 Curve,
552 Map,
554 Cuboid,
556 Cube4,
558 Cube5,
560}
561
562impl std::fmt::Display for ApplicationPrimitiveCategory {
563 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
564 match self {
565 ApplicationPrimitiveCategory::Value => f.write_str("VALUE"),
566 ApplicationPrimitiveCategory::ValBlk => f.write_str("VAL_BLK"),
567 ApplicationPrimitiveCategory::String => f.write_str("STRING"),
568 ApplicationPrimitiveCategory::Boolean => f.write_str("BOOLEAN"),
569 ApplicationPrimitiveCategory::ComAxis => f.write_str("COM_AXIS"),
570 ApplicationPrimitiveCategory::ResAxis => f.write_str("RES_AXIS"),
571 ApplicationPrimitiveCategory::Curve => f.write_str("CURVE"),
572 ApplicationPrimitiveCategory::Map => f.write_str("MAP"),
573 ApplicationPrimitiveCategory::Cuboid => f.write_str("CUBOID"),
574 ApplicationPrimitiveCategory::Cube4 => f.write_str("CUBE_4"),
575 ApplicationPrimitiveCategory::Cube5 => f.write_str("CUBE_5"),
576 }
577 }
578}
579
580impl std::str::FromStr for ApplicationPrimitiveCategory {
581 type Err = AutosarAbstractionError;
582
583 fn from_str(s: &str) -> Result<Self, Self::Err> {
584 match s {
585 "VALUE" => Ok(ApplicationPrimitiveCategory::Value),
586 "VAL_BLK" => Ok(ApplicationPrimitiveCategory::ValBlk),
587 "STRING" => Ok(ApplicationPrimitiveCategory::String),
588 "BOOLEAN" => Ok(ApplicationPrimitiveCategory::Boolean),
589 "COM_AXIS" => Ok(ApplicationPrimitiveCategory::ComAxis),
590 "RES_AXIS" => Ok(ApplicationPrimitiveCategory::ResAxis),
591 "CURVE" => Ok(ApplicationPrimitiveCategory::Curve),
592 "MAP" => Ok(ApplicationPrimitiveCategory::Map),
593 "CUBOID" => Ok(ApplicationPrimitiveCategory::Cuboid),
594 "CUBE_4" => Ok(ApplicationPrimitiveCategory::Cube4),
595 "CUBE_5" => Ok(ApplicationPrimitiveCategory::Cube5),
596 _ => Err(AutosarAbstractionError::ValueConversionError {
597 value: s.to_string(),
598 dest: "ApplicationPrimitiveCategory".to_string(),
599 }),
600 }
601 }
602}
603
604#[derive(Debug, Clone, PartialEq, Eq, Hash)]
608pub enum ApplicationDataType {
609 Array(ApplicationArrayDataType),
611 Record(ApplicationRecordDataType),
613 Primitive(ApplicationPrimitiveDataType),
615}
616
617impl AbstractionElement for ApplicationDataType {
618 fn element(&self) -> &Element {
619 match self {
620 ApplicationDataType::Array(e) => e.element(),
621 ApplicationDataType::Record(e) => e.element(),
622 ApplicationDataType::Primitive(e) => e.element(),
623 }
624 }
625}
626
627impl TryFrom<Element> for ApplicationDataType {
628 type Error = AutosarAbstractionError;
629
630 fn try_from(element: Element) -> Result<Self, Self::Error> {
631 match element.element_name() {
632 ElementName::ApplicationArrayDataType => Ok(ApplicationDataType::Array(element.try_into()?)),
633 ElementName::ApplicationRecordDataType => Ok(ApplicationDataType::Record(element.try_into()?)),
634 ElementName::ApplicationPrimitiveDataType => Ok(ApplicationDataType::Primitive(element.try_into()?)),
635 _ => Err(AutosarAbstractionError::ConversionError {
636 element,
637 dest: "ApplicationDataType".to_string(),
638 }),
639 }
640 }
641}
642
643impl IdentifiableAbstractionElement for ApplicationDataType {}
644
645impl From<ApplicationPrimitiveDataType> for ApplicationDataType {
646 fn from(val: ApplicationPrimitiveDataType) -> Self {
647 ApplicationDataType::Primitive(val)
648 }
649}
650
651impl From<ApplicationRecordDataType> for ApplicationDataType {
652 fn from(val: ApplicationRecordDataType) -> Self {
653 ApplicationDataType::Record(val)
654 }
655}
656
657impl From<ApplicationArrayDataType> for ApplicationDataType {
658 fn from(val: ApplicationArrayDataType) -> Self {
659 ApplicationDataType::Array(val)
660 }
661}
662
663impl ApplicationDataType {
664 #[must_use]
666 pub fn category(&self) -> Option<String> {
667 self.element()
668 .get_sub_element(ElementName::Category)?
669 .character_data()?
670 .string_value()
671 }
672}
673
674#[cfg(test)]
677mod tests {
678 use super::*;
679 use crate::AutosarModelAbstraction;
680 use autosar_data::AutosarVersion;
681 use datatype::{CompuMethodContent, CompuMethodLinearContent};
682
683 #[test]
684 fn test_application_array_data_type() {
685 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
686 let package = model.get_or_create_package("/DataTypes").unwrap();
687 let element_type = ApplicationPrimitiveDataType::new(
688 "Element",
689 &package,
690 ApplicationPrimitiveCategory::Value,
691 None,
692 None,
693 None,
694 )
695 .unwrap();
696 let array_data_type =
697 ApplicationArrayDataType::new("Array", &package, &element_type, ApplicationArraySize::Fixed(10)).unwrap();
698 let array_type_2 =
699 ApplicationArrayDataType::new("Array2", &package, &element_type, ApplicationArraySize::Fixed(100)).unwrap();
700
701 assert_eq!(
702 array_data_type.array_element().unwrap().data_type().unwrap(),
703 ApplicationDataType::Primitive(element_type)
704 );
705 assert_eq!(array_data_type.size().unwrap(), ApplicationArraySize::Fixed(10));
706
707 array_data_type
708 .set_size(ApplicationArraySize::VariableLinear(100))
709 .unwrap();
710 assert_eq!(
711 array_data_type.size().unwrap(),
712 ApplicationArraySize::VariableLinear(100)
713 );
714
715 let result = array_data_type.set_size(ApplicationArraySize::VariableSquare);
717 assert!(result.is_err());
718 let result = array_data_type.set_size(ApplicationArraySize::VariableRectangular(100));
719 assert!(result.is_err());
720 let result = array_data_type.set_size(ApplicationArraySize::VariableFullyFlexible(100));
721 assert!(result.is_err());
722
723 array_data_type
725 .array_element()
726 .unwrap()
727 .set_data_type(&array_type_2)
728 .unwrap();
729 array_data_type.set_size(ApplicationArraySize::VariableSquare).unwrap();
730 assert_eq!(array_data_type.size().unwrap(), ApplicationArraySize::VariableSquare);
731 array_data_type
732 .set_size(ApplicationArraySize::VariableRectangular(100))
733 .unwrap();
734 assert_eq!(
735 array_data_type.size().unwrap(),
736 ApplicationArraySize::VariableRectangular(100)
737 );
738 array_data_type
739 .set_size(ApplicationArraySize::VariableFullyFlexible(100))
740 .unwrap();
741 assert_eq!(
742 array_data_type.size().unwrap(),
743 ApplicationArraySize::VariableFullyFlexible(100)
744 );
745
746 let element_type_2 = ApplicationPrimitiveDataType::new(
748 "Element2",
749 &package,
750 ApplicationPrimitiveCategory::Value,
751 None,
752 None,
753 None,
754 )
755 .unwrap();
756 let array_element = array_data_type.array_element().unwrap();
757 array_element.set_data_type(&element_type_2).unwrap();
758 assert_eq!(
759 array_element.data_type().unwrap(),
760 ApplicationDataType::Primitive(element_type_2)
761 );
762 }
763
764 #[test]
765 fn test_application_record_data_type() {
766 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
767 let package = model.get_or_create_package("/DataTypes").unwrap();
768 let record_data_type = ApplicationRecordDataType::new("Record", &package).unwrap();
769 let element_type = ApplicationPrimitiveDataType::new(
770 "Element",
771 &package,
772 ApplicationPrimitiveCategory::Value,
773 None,
774 None,
775 None,
776 )
777 .unwrap();
778 let record_element = record_data_type
779 .create_record_element("Element", &element_type)
780 .unwrap();
781
782 assert_eq!(
783 record_element.data_type().unwrap(),
784 ApplicationDataType::Primitive(element_type)
785 );
786 assert_eq!(record_data_type.record_elements().next().unwrap(), record_element);
787 }
788
789 #[test]
790 fn test_application_primitive_data_type() {
791 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
792 let package = model.get_or_create_package("/DataTypes").unwrap();
793 let compu_method = CompuMethod::new(
794 "CompuMethod",
795 &package,
796 CompuMethodContent::Linear(CompuMethodLinearContent {
797 direction: datatype::CompuScaleDirection::IntToPhys,
798 offset: 0.0,
799 factor: 100.0,
800 divisor: 1.0,
801 lower_limit: None,
802 upper_limit: None,
803 }),
804 )
805 .unwrap();
806 let unit = Unit::new("Unit", &package, Some("Unit name")).unwrap();
807 let data_constraint = DataConstr::new("DataConstraint", &package).unwrap();
808 let primitive_data_type = ApplicationPrimitiveDataType::new(
809 "Primitive",
810 &package,
811 ApplicationPrimitiveCategory::Value,
812 Some(&compu_method),
813 Some(&unit),
814 Some(&data_constraint),
815 )
816 .unwrap();
817
818 assert_eq!(
819 primitive_data_type.category().unwrap(),
820 ApplicationPrimitiveCategory::Value
821 );
822 assert_eq!(primitive_data_type.compu_method().unwrap(), compu_method);
823 assert_eq!(primitive_data_type.unit().unwrap(), unit);
824 assert_eq!(primitive_data_type.data_constraint().unwrap(), data_constraint);
825
826 primitive_data_type
827 .set_category(ApplicationPrimitiveCategory::Boolean)
828 .unwrap();
829 assert_eq!(
830 primitive_data_type.category().unwrap(),
831 ApplicationPrimitiveCategory::Boolean
832 );
833 primitive_data_type.set_compu_method(None).unwrap();
834 assert!(primitive_data_type.compu_method().is_none());
835 primitive_data_type.set_unit(None).unwrap();
836 assert!(primitive_data_type.unit().is_none());
837 primitive_data_type.set_data_constraint(None).unwrap();
838 assert!(primitive_data_type.data_constraint().is_none());
839 }
840
841 #[test]
842 fn test_application_data_type() {
843 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
844 let package = model.get_or_create_package("/DataTypes").unwrap();
845 let element_type = ApplicationPrimitiveDataType::new(
846 "Element",
847 &package,
848 ApplicationPrimitiveCategory::Value,
849 None,
850 None,
851 None,
852 )
853 .unwrap();
854 let array_data_type =
855 ApplicationArrayDataType::new("Array", &package, &element_type, ApplicationArraySize::Fixed(10)).unwrap();
856 let record_data_type = ApplicationRecordDataType::new("Record", &package).unwrap();
857 let primitive_data_type = ApplicationPrimitiveDataType::new(
858 "Primitive",
859 &package,
860 ApplicationPrimitiveCategory::Value,
861 None,
862 None,
863 None,
864 )
865 .unwrap();
866
867 let data_type: ApplicationDataType = array_data_type.clone().into();
868 assert_eq!(data_type, ApplicationDataType::Array(array_data_type.clone()));
869 assert_eq!(data_type.category().unwrap(), "ARRAY");
870
871 let data_type: ApplicationDataType = record_data_type.clone().into();
872 assert_eq!(data_type, ApplicationDataType::Record(record_data_type.clone()));
873 assert_eq!(data_type.category().unwrap(), "STRUCTURE");
874
875 let data_type: ApplicationDataType = primitive_data_type.clone().into();
876 assert_eq!(data_type, ApplicationDataType::Primitive(primitive_data_type.clone()));
877 assert_eq!(data_type.category().unwrap(), "VALUE");
878
879 let result = ApplicationDataType::try_from(package.element().clone());
880 assert!(result.is_err());
881 }
882}