autosar_data_abstraction/datatype/
mapping.rs

1use crate::{
2    AbstractionElement, ArPackage, AutosarAbstractionError, Element, IdentifiableAbstractionElement,
3    abstraction_element, datatype,
4};
5use autosar_data::ElementName;
6use datatype::{ApplicationDataType, ImplementationDataType};
7
8/// A [`DataTypeMappingSet`] contains `DataTypeMap`s
9///
10/// Use [`ArPackage::create_data_type_mapping_set`] to create a new `DataTypeMappingSet`
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub struct DataTypeMappingSet(Element);
13abstraction_element!(DataTypeMappingSet, DataTypeMappingSet);
14impl IdentifiableAbstractionElement for DataTypeMappingSet {}
15
16impl DataTypeMappingSet {
17    /// Create a new `DataTypeMappingSet`
18    pub(crate) fn new(name: &str, package: &ArPackage) -> Result<Self, AutosarAbstractionError> {
19        let elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
20        let mapping_set = elements.create_named_sub_element(ElementName::DataTypeMappingSet, name)?;
21
22        Ok(Self(mapping_set))
23    }
24
25    /// Create a new `DataTypeMap` in the `DataTypeMappingSet`
26    pub fn create_data_type_map<T: Into<ApplicationDataType> + Clone>(
27        &self,
28        implementation_data_type: &ImplementationDataType,
29        application_data_type: &T,
30    ) -> Result<DataTypeMap, AutosarAbstractionError> {
31        let application_data_type = application_data_type.clone().into();
32        let data_type_map = DataTypeMap::new(self.element(), implementation_data_type, &application_data_type)?;
33        Ok(data_type_map)
34    }
35
36    /// Get an iterator over the `DataTypeMap`s in the `DataTypeMappingSet`
37    pub fn data_type_maps(&self) -> impl Iterator<Item = DataTypeMap> + Send + 'static {
38        self.element()
39            .get_sub_element(ElementName::DataTypeMaps)
40            .into_iter()
41            .flat_map(|maps| maps.sub_elements())
42            .filter_map(|elem| DataTypeMap::try_from(elem).ok())
43    }
44}
45
46//#########################################################
47
48/// A `DataTypeMap` maps an `ImplementationDataType` to an `ApplicationDataType`
49#[derive(Debug, Clone, PartialEq, Eq, Hash)]
50pub struct DataTypeMap(Element);
51abstraction_element!(DataTypeMap, DataTypeMap);
52
53impl DataTypeMap {
54    /// Create a new `DataTypeMap`
55    fn new(
56        parent: &Element,
57        implementation_data_type: &ImplementationDataType,
58        application_data_type: &ApplicationDataType,
59    ) -> Result<Self, AutosarAbstractionError> {
60        let maps = parent.get_or_create_sub_element(ElementName::DataTypeMaps)?;
61        let data_type_map = maps.create_sub_element(ElementName::DataTypeMap)?;
62
63        data_type_map
64            .create_sub_element(ElementName::ApplicationDataTypeRef)?
65            .set_reference_target(application_data_type.element())?;
66        data_type_map
67            .create_sub_element(ElementName::ImplementationDataTypeRef)?
68            .set_reference_target(implementation_data_type.element())?;
69
70        Ok(Self(data_type_map))
71    }
72
73    /// Get the `ImplementationDataType` of the `DataTypeMap`
74    #[must_use]
75    pub fn implementation_data_type(&self) -> Option<ImplementationDataType> {
76        self.element()
77            .get_sub_element(ElementName::ImplementationDataTypeRef)?
78            .get_reference_target()
79            .ok()?
80            .try_into()
81            .ok()
82    }
83
84    /// Get the `ApplicationDataType` of the `DataTypeMap`
85    #[must_use]
86    pub fn application_data_type(&self) -> Option<ApplicationDataType> {
87        self.element()
88            .get_sub_element(ElementName::ApplicationDataTypeRef)?
89            .get_reference_target()
90            .ok()?
91            .try_into()
92            .ok()
93    }
94}
95
96//#########################################################
97
98#[cfg(test)]
99mod tests {
100    use super::*;
101    use crate::AutosarModelAbstraction;
102    use autosar_data::AutosarVersion;
103    use datatype::{
104        ApplicationPrimitiveCategory, ApplicationPrimitiveDataType, BaseTypeEncoding, ImplementationDataTypeSettings,
105        SwBaseType,
106    };
107
108    #[test]
109    fn test_data_type_mapping_set() {
110        let model = AutosarModelAbstraction::create("test.arxml", AutosarVersion::LATEST);
111        let package = model.get_or_create_package("/DataTypeMappingSets").unwrap();
112        let mapping_set = DataTypeMappingSet::new("MappingSet", &package).unwrap();
113
114        // create an implementation data type
115        let base_type =
116            SwBaseType::new("uint8", &package, 8, BaseTypeEncoding::None, None, None, Some("uint8")).unwrap();
117        let impl_data_type = ImplementationDataType::new(
118            &package,
119            &ImplementationDataTypeSettings::Value {
120                name: "ImplDataType".to_string(),
121                base_type: base_type.clone(),
122                compu_method: None,
123                data_constraint: None,
124            },
125        )
126        .unwrap();
127        // create an application data type
128        let app_data_type = ApplicationPrimitiveDataType::new(
129            "AppDataType",
130            &package,
131            ApplicationPrimitiveCategory::Value,
132            None,
133            None,
134            None,
135        )
136        .unwrap()
137        .into();
138
139        let data_type_map = mapping_set
140            .create_data_type_map(&impl_data_type, &app_data_type)
141            .unwrap();
142
143        assert_eq!(data_type_map.implementation_data_type().unwrap(), impl_data_type);
144        assert_eq!(data_type_map.application_data_type().unwrap(), app_data_type);
145
146        assert_eq!(mapping_set.data_type_maps().count(), 1);
147    }
148}