autosar_data_abstraction/software_component/interface/
senderreceiver.rs1use crate::{
2 AbstractionElement, ArPackage, AutosarAbstractionError, Element, IdentifiableAbstractionElement,
3 abstraction_element,
4 datatype::{AbstractAutosarDataType, AutosarDataType, ValueSpecification},
5 software_component::AbstractPortInterface,
6};
7use autosar_data::ElementName;
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
15pub struct SenderReceiverInterface(pub(crate) Element);
16abstraction_element!(SenderReceiverInterface, SenderReceiverInterface);
17impl IdentifiableAbstractionElement for SenderReceiverInterface {}
18impl AbstractPortInterface for SenderReceiverInterface {}
19
20impl SenderReceiverInterface {
21 pub(crate) fn new(name: &str, package: &ArPackage) -> Result<Self, AutosarAbstractionError> {
23 let elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
24 let sender_receiver_interface =
25 elements.create_named_sub_element(ElementName::SenderReceiverInterface, name)?;
26
27 Ok(Self(sender_receiver_interface))
28 }
29
30 pub fn create_data_element<T: AbstractAutosarDataType>(
32 &self,
33 name: &str,
34 data_type: &T,
35 ) -> Result<VariableDataPrototype, AutosarAbstractionError> {
36 let data_elements = self.element().get_or_create_sub_element(ElementName::DataElements)?;
37 VariableDataPrototype::new(name, &data_elements, data_type.element())
38 }
39
40 pub fn data_elements(&self) -> impl Iterator<Item = VariableDataPrototype> + Send + 'static {
42 self.element()
43 .get_sub_element(ElementName::DataElements)
44 .into_iter()
45 .flat_map(|data_elements| data_elements.sub_elements())
46 .filter_map(|elem| VariableDataPrototype::try_from(elem).ok())
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, Hash)]
54pub struct VariableDataPrototype(Element);
55abstraction_element!(VariableDataPrototype, VariableDataPrototype);
56impl IdentifiableAbstractionElement for VariableDataPrototype {}
57
58impl VariableDataPrototype {
59 fn new(name: &str, parent_element: &Element, data_type: &Element) -> Result<Self, AutosarAbstractionError> {
61 let vdp = parent_element.create_named_sub_element(ElementName::VariableDataPrototype, name)?;
62 vdp.create_sub_element(ElementName::TypeTref)?
63 .set_reference_target(data_type)?;
64
65 Ok(Self(vdp))
66 }
67
68 pub fn interface(&self) -> Result<SenderReceiverInterface, AutosarAbstractionError> {
70 let named_parent = self.element().named_parent()?.unwrap();
71 SenderReceiverInterface::try_from(named_parent)
72 }
73
74 pub fn set_data_type<T: AbstractAutosarDataType>(&self, data_type: &T) -> Result<(), AutosarAbstractionError> {
76 self.element()
77 .get_or_create_sub_element(ElementName::TypeTref)?
78 .set_reference_target(data_type.element())?;
79 Ok(())
80 }
81
82 #[must_use]
84 pub fn data_type(&self) -> Option<AutosarDataType> {
85 let type_tref = self.element().get_sub_element(ElementName::TypeTref)?;
86 AutosarDataType::try_from(type_tref.get_reference_target().ok()?).ok()
87 }
88
89 pub fn set_init_value<T: Into<ValueSpecification>>(
91 &self,
92 value_spec: Option<T>,
93 ) -> Result<(), AutosarAbstractionError> {
94 if let Some(value_spec) = value_spec {
95 let value_spec: ValueSpecification = value_spec.into();
96 let init_value_elem = self.element().get_or_create_sub_element(ElementName::InitValue)?;
97 value_spec.store(&init_value_elem)?;
98 } else {
99 let _ = self.element().remove_sub_element_kind(ElementName::InitValue);
100 }
101 Ok(())
102 }
103
104 #[must_use]
106 pub fn init_value(&self) -> Option<ValueSpecification> {
107 let init_value_elem = self
108 .element()
109 .get_sub_element(ElementName::InitValue)?
110 .get_sub_element_at(0)?;
111 ValueSpecification::load(&init_value_elem)
112 }
113}
114
115#[cfg(test)]
118mod test {
119 use crate::{
120 AutosarModelAbstraction,
121 datatype::{
122 AutosarDataType, BaseTypeEncoding, ImplementationDataTypeSettings, NumericalValueSpecification,
123 ValueSpecification,
124 },
125 software_component::AbstractPortInterface,
126 };
127 use autosar_data::AutosarVersion;
128
129 #[test]
130 fn sender_receiver_interface() {
131 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
132 let package = model.get_or_create_package("/package").unwrap();
133
134 let sr_interface = package
135 .create_sender_receiver_interface("SenderReceiverInterface")
136 .unwrap();
137
138 let base_type = package
139 .create_sw_base_type("base", 32, BaseTypeEncoding::None, None, None, None)
140 .unwrap();
141 let impl_settings = ImplementationDataTypeSettings::Value {
142 name: "ImplementationValue".to_string(),
143 base_type: base_type.clone(),
144 compu_method: None,
145 data_constraint: None,
146 };
147 let datatype = package.create_implementation_data_type(&impl_settings).unwrap();
148 let impl_settings2 = ImplementationDataTypeSettings::Value {
149 name: "ImplementationValue2".to_string(),
150 base_type,
151 compu_method: None,
152 data_constraint: None,
153 };
154 let datatype2 = package.create_implementation_data_type(&impl_settings2).unwrap();
155
156 let data_element = sr_interface.create_data_element("data_element", &datatype).unwrap();
157 assert_eq!(sr_interface.data_elements().count(), 1);
158 assert_eq!(data_element.interface().unwrap(), sr_interface);
159 assert_eq!(
160 data_element.data_type().unwrap(),
161 AutosarDataType::ImplementationDataType(datatype)
162 );
163 data_element.set_data_type(&datatype2).unwrap();
164 assert_eq!(
165 data_element.data_type().unwrap(),
166 AutosarDataType::ImplementationDataType(datatype2)
167 );
168
169 let value_spec = NumericalValueSpecification {
170 label: None,
171 value: 42.0,
172 };
173 data_element.set_init_value(Some(value_spec)).unwrap();
174 assert_eq!(
175 data_element.init_value().unwrap(),
176 NumericalValueSpecification {
177 label: None,
178 value: 42.0
179 }
180 .into()
181 );
182
183 data_element.set_init_value::<ValueSpecification>(None).unwrap();
184 assert!(data_element.init_value().is_none());
185
186 sr_interface.set_is_service(Some(false)).unwrap();
187 assert!(!sr_interface.is_service().unwrap());
188 sr_interface.set_is_service(Some(true)).unwrap();
189 assert!(sr_interface.is_service().unwrap());
190 sr_interface.set_is_service(None).unwrap();
191 assert_eq!(sr_interface.is_service(), None);
192 }
193}