autosar_data_abstraction/software_component/interface/
senderreceiver.rs1use crate::{
2 AbstractionElement, ArPackage, AutosarAbstractionError, Element, IdentifiableAbstractionElement,
3 SenderReceiverToSignalMapping, abstraction_element,
4 datatype::{AbstractAutosarDataType, AutosarDataType, ValueSpecification},
5 get_reference_parents,
6 software_component::{AbstractPortInterface, DataReceivedEvent, PortPrototype},
7};
8use autosar_data::ElementName;
9
10#[derive(Debug, Clone, PartialEq, Eq, Hash)]
16pub struct SenderReceiverInterface(pub(crate) Element);
17abstraction_element!(SenderReceiverInterface, SenderReceiverInterface);
18impl IdentifiableAbstractionElement for SenderReceiverInterface {}
19impl AbstractPortInterface for SenderReceiverInterface {}
20
21impl SenderReceiverInterface {
22 pub(crate) fn new(name: &str, package: &ArPackage) -> Result<Self, AutosarAbstractionError> {
24 let elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
25 let sender_receiver_interface =
26 elements.create_named_sub_element(ElementName::SenderReceiverInterface, name)?;
27
28 Ok(Self(sender_receiver_interface))
29 }
30
31 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
33 for data_element in self.data_elements() {
34 data_element.remove(true)?;
35 }
36
37 let ref_parents = get_reference_parents(self.element())?;
38
39 AbstractionElement::remove(self, deep)?;
40
41 for (named_parent, _parent) in ref_parents {
42 match named_parent.element_name() {
43 ElementName::PPortPrototype | ElementName::RPortPrototype | ElementName::PrPortPrototype => {
44 if let Ok(port) = PortPrototype::try_from(named_parent) {
45 port.remove(deep)?;
46 }
47 }
48 _ => {}
49 }
50 }
51
52 Ok(())
53 }
54
55 pub fn create_data_element<T: AbstractAutosarDataType>(
57 &self,
58 name: &str,
59 data_type: &T,
60 ) -> Result<VariableDataPrototype, AutosarAbstractionError> {
61 let data_elements = self.element().get_or_create_sub_element(ElementName::DataElements)?;
62 VariableDataPrototype::new(name, &data_elements, data_type.element())
63 }
64
65 pub fn data_elements(&self) -> impl Iterator<Item = VariableDataPrototype> + Send + use<> {
67 self.element()
68 .get_sub_element(ElementName::DataElements)
69 .into_iter()
70 .flat_map(|data_elements| data_elements.sub_elements())
71 .filter_map(|elem| VariableDataPrototype::try_from(elem).ok())
72 }
73}
74
75#[derive(Debug, Clone, PartialEq, Eq, Hash)]
79pub struct VariableDataPrototype(Element);
80abstraction_element!(VariableDataPrototype, VariableDataPrototype);
81impl IdentifiableAbstractionElement for VariableDataPrototype {}
82
83impl VariableDataPrototype {
84 fn new(name: &str, parent_element: &Element, data_type: &Element) -> Result<Self, AutosarAbstractionError> {
86 let vdp = parent_element.create_named_sub_element(ElementName::VariableDataPrototype, name)?;
87 vdp.create_sub_element(ElementName::TypeTref)?
88 .set_reference_target(data_type)?;
89
90 Ok(Self(vdp))
91 }
92
93 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
95 let ref_parents = get_reference_parents(self.element())?;
96 AbstractionElement::remove(self, deep)?;
97
98 for (named_parent, parent) in ref_parents {
99 if named_parent.element_name() == ElementName::DataReceivedEvent {
100 if let Ok(event) = DataReceivedEvent::try_from(named_parent) {
101 event.remove(deep)?;
102 }
103 } else if named_parent.element_name() == ElementName::SystemMapping
104 && parent.element_name() == ElementName::DataElementIref
105 && let Ok(Some(parent_parent)) = parent.parent()
106 && let Ok(mapping) = SenderReceiverToSignalMapping::try_from(parent_parent)
107 {
108 mapping.remove(deep)?;
109 }
110 }
111
112 Ok(())
113 }
114
115 pub fn interface(&self) -> Result<SenderReceiverInterface, AutosarAbstractionError> {
117 let named_parent = self.element().named_parent()?.unwrap();
118 SenderReceiverInterface::try_from(named_parent)
119 }
120
121 pub fn set_data_type<T: AbstractAutosarDataType>(&self, data_type: &T) -> Result<(), AutosarAbstractionError> {
123 self.element()
124 .get_or_create_sub_element(ElementName::TypeTref)?
125 .set_reference_target(data_type.element())?;
126 Ok(())
127 }
128
129 #[must_use]
131 pub fn data_type(&self) -> Option<AutosarDataType> {
132 let type_tref = self.element().get_sub_element(ElementName::TypeTref)?;
133 AutosarDataType::try_from(type_tref.get_reference_target().ok()?).ok()
134 }
135
136 pub fn set_init_value<T: Into<ValueSpecification>>(
138 &self,
139 value_spec: Option<T>,
140 ) -> Result<(), AutosarAbstractionError> {
141 if let Some(value_spec) = value_spec {
142 let value_spec: ValueSpecification = value_spec.into();
143 let init_value_elem = self.element().get_or_create_sub_element(ElementName::InitValue)?;
144 value_spec.store(&init_value_elem)?;
145 } else {
146 let _ = self.element().remove_sub_element_kind(ElementName::InitValue);
147 }
148 Ok(())
149 }
150
151 #[must_use]
153 pub fn init_value(&self) -> Option<ValueSpecification> {
154 let init_value_elem = self
155 .element()
156 .get_sub_element(ElementName::InitValue)?
157 .get_sub_element_at(0)?;
158 ValueSpecification::load(&init_value_elem)
159 }
160}
161
162#[cfg(test)]
165mod test {
166 use crate::{
167 AutosarModelAbstraction,
168 datatype::{
169 AutosarDataType, BaseTypeEncoding, ImplementationDataTypeSettings, NumericalValueSpecification,
170 ValueSpecification,
171 },
172 software_component::{AbstractPortInterface, AbstractSwComponentType},
173 };
174 use autosar_data::AutosarVersion;
175
176 #[test]
177 fn sender_receiver_interface() {
178 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
179 let package = model.get_or_create_package("/package").unwrap();
180
181 let sr_interface = package
182 .create_sender_receiver_interface("SenderReceiverInterface")
183 .unwrap();
184
185 let base_type = package
186 .create_sw_base_type("base", 32, BaseTypeEncoding::None, None, None, None)
187 .unwrap();
188 let impl_settings = ImplementationDataTypeSettings::Value {
189 name: "ImplementationValue".to_string(),
190 base_type: base_type.clone(),
191 compu_method: None,
192 data_constraint: None,
193 };
194 let datatype = package.create_implementation_data_type(&impl_settings).unwrap();
195 let impl_settings2 = ImplementationDataTypeSettings::Value {
196 name: "ImplementationValue2".to_string(),
197 base_type,
198 compu_method: None,
199 data_constraint: None,
200 };
201 let datatype2 = package.create_implementation_data_type(&impl_settings2).unwrap();
202
203 let data_element = sr_interface.create_data_element("data_element", &datatype).unwrap();
204 assert_eq!(sr_interface.data_elements().count(), 1);
205 assert_eq!(data_element.interface().unwrap(), sr_interface);
206 assert_eq!(
207 data_element.data_type().unwrap(),
208 AutosarDataType::ImplementationDataType(datatype)
209 );
210 data_element.set_data_type(&datatype2).unwrap();
211 assert_eq!(
212 data_element.data_type().unwrap(),
213 AutosarDataType::ImplementationDataType(datatype2)
214 );
215
216 let value_spec = NumericalValueSpecification {
217 label: None,
218 value: 42.0,
219 };
220 data_element.set_init_value(Some(value_spec)).unwrap();
221 assert_eq!(
222 data_element.init_value().unwrap(),
223 NumericalValueSpecification {
224 label: None,
225 value: 42.0
226 }
227 .into()
228 );
229
230 data_element.set_init_value::<ValueSpecification>(None).unwrap();
231 assert!(data_element.init_value().is_none());
232
233 sr_interface.set_is_service(Some(false)).unwrap();
234 assert!(!sr_interface.is_service().unwrap());
235 sr_interface.set_is_service(Some(true)).unwrap();
236 assert!(sr_interface.is_service().unwrap());
237 sr_interface.set_is_service(None).unwrap();
238 assert_eq!(sr_interface.is_service(), None);
239 }
240
241 #[test]
242 fn remove() {
243 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
244 let package = model.get_or_create_package("/package").unwrap();
245 let sender_receiver_interface = package.create_sender_receiver_interface("TestInterface").unwrap();
246
247 let composition_type = package.create_composition_sw_component_type("comp_parent").unwrap();
248 let _composition_r_port = composition_type
249 .create_r_port("port_r", &sender_receiver_interface)
250 .unwrap();
251
252 assert_eq!(composition_type.ports().count(), 1);
253 sender_receiver_interface.remove(true).unwrap();
254 assert_eq!(composition_type.ports().count(), 0);
255 }
256}