autosar_data_abstraction/software_component/
port.rs1use crate::{
2 AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element,
3 get_reference_parents, is_used, software_component,
4};
5use autosar_data::{Element, ElementName};
6use software_component::{AbstractPortInterface, PortInterface, SwComponentType};
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub struct RPortPrototype(Element);
13abstraction_element!(RPortPrototype, RPortPrototype);
14impl IdentifiableAbstractionElement for RPortPrototype {}
15
16impl RPortPrototype {
17 pub(crate) fn new<T: AbstractPortInterface>(
19 name: &str,
20 parent_element: &Element,
21 interface: &T,
22 ) -> Result<Self, AutosarAbstractionError> {
23 let r_port_prototype = parent_element.create_named_sub_element(ElementName::RPortPrototype, name)?;
24 r_port_prototype
25 .create_sub_element(ElementName::RequiredInterfaceTref)?
26 .set_reference_target(interface.element())?;
27
28 Ok(Self(r_port_prototype))
29 }
30
31 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
33 let opt_port_interface = self.port_interface();
34 let ref_parents = get_reference_parents(self.element())?;
35
36 AbstractionElement::remove(self, deep)?;
37
38 if deep
39 && let Some(port_interface) = opt_port_interface
40 && !is_used(port_interface.element())
41 {
42 port_interface.remove(true)?;
43 }
44
45 for (named_parent, _parent) in ref_parents {
46 match named_parent.element_name() {
47 ElementName::DelegationSwConnector
48 | ElementName::AssemblySwConnector
49 | ElementName::PassThroughSwConnector => {
50 if let Ok(connector) = software_component::SwConnector::try_from(named_parent) {
51 connector.remove(deep)?;
52 };
53 }
54 _ => {}
55 }
56 }
57
58 Ok(())
59 }
60
61 pub fn port_interface(&self) -> Option<PortInterface> {
63 let interface_elem = self
64 .element()
65 .get_sub_element(ElementName::RequiredInterfaceTref)
66 .and_then(|r| r.get_reference_target().ok())?;
67 PortInterface::try_from(interface_elem).ok()
68 }
69
70 pub fn component_type(&self) -> Result<SwComponentType, AutosarAbstractionError> {
72 let component_type_elem = self.element().named_parent()?.unwrap();
73 SwComponentType::try_from(component_type_elem)
74 }
75}
76
77#[derive(Debug, Clone, PartialEq, Eq, Hash)]
81pub struct PPortPrototype(Element);
82abstraction_element!(PPortPrototype, PPortPrototype);
83impl IdentifiableAbstractionElement for PPortPrototype {}
84
85impl PPortPrototype {
86 pub(crate) fn new<T: AbstractPortInterface>(
88 name: &str,
89 parent_element: &Element,
90 interface: &T,
91 ) -> Result<Self, AutosarAbstractionError> {
92 let p_port_prototype = parent_element.create_named_sub_element(ElementName::PPortPrototype, name)?;
93 p_port_prototype
94 .create_sub_element(ElementName::ProvidedInterfaceTref)?
95 .set_reference_target(interface.element())?;
96
97 Ok(Self(p_port_prototype))
98 }
99
100 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
102 let opt_port_interface = self.port_interface();
103 let ref_parents = get_reference_parents(self.element())?;
104
105 AbstractionElement::remove(self, deep)?;
106
107 if deep
108 && let Some(port_interface) = opt_port_interface
109 && !is_used(port_interface.element())
110 {
111 port_interface.remove(true)?;
112 }
113
114 for (named_parent, _parent) in ref_parents {
115 match named_parent.element_name() {
116 ElementName::DelegationSwConnector
117 | ElementName::AssemblySwConnector
118 | ElementName::PassThroughSwConnector => {
119 if let Ok(connector) = software_component::SwConnector::try_from(named_parent) {
120 connector.remove(deep)?;
121 };
122 }
123 _ => {}
124 }
125 }
126
127 Ok(())
128 }
129
130 pub fn port_interface(&self) -> Option<PortInterface> {
132 let interface_elem = self
133 .element()
134 .get_sub_element(ElementName::ProvidedInterfaceTref)
135 .and_then(|r| r.get_reference_target().ok())?;
136 PortInterface::try_from(interface_elem).ok()
137 }
138
139 pub fn component_type(&self) -> Result<SwComponentType, AutosarAbstractionError> {
141 let component_type_elem = self.element().named_parent()?.unwrap();
142 SwComponentType::try_from(component_type_elem)
143 }
144}
145
146#[derive(Debug, Clone, PartialEq, Eq, Hash)]
150pub struct PRPortPrototype(Element);
151abstraction_element!(PRPortPrototype, PrPortPrototype);
152impl IdentifiableAbstractionElement for PRPortPrototype {}
153
154impl PRPortPrototype {
155 pub(crate) fn new<T: AbstractPortInterface>(
157 name: &str,
158 parent_element: &Element,
159 interface: &T,
160 ) -> Result<Self, AutosarAbstractionError> {
161 if interface.element().element_name() == ElementName::ParameterInterface {
162 return Err(AutosarAbstractionError::InvalidParameter(
163 "ParameterInterface is not allowed for PRPortPrototype".to_string(),
164 ));
165 }
166
167 let pr_port_prototype = parent_element.create_named_sub_element(ElementName::PrPortPrototype, name)?;
168 pr_port_prototype
169 .create_sub_element(ElementName::ProvidedRequiredInterfaceTref)?
170 .set_reference_target(interface.element())?;
171
172 Ok(Self(pr_port_prototype))
173 }
174
175 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
177 let opt_port_interface = self.port_interface();
178 let ref_parents = get_reference_parents(self.element())?;
179
180 AbstractionElement::remove(self, deep)?;
181
182 if deep
183 && let Some(port_interface) = opt_port_interface
184 && !is_used(port_interface.element())
185 {
186 port_interface.remove(true)?;
187 }
188
189 for (named_parent, _parent) in ref_parents {
190 match named_parent.element_name() {
191 ElementName::DelegationSwConnector
192 | ElementName::AssemblySwConnector
193 | ElementName::PassThroughSwConnector => {
194 if let Ok(connector) = software_component::SwConnector::try_from(named_parent) {
195 connector.remove(deep)?;
196 };
197 }
198 _ => {}
199 }
200 }
201
202 Ok(())
203 }
204
205 pub fn port_interface(&self) -> Option<PortInterface> {
207 let interface_elem = self
208 .element()
209 .get_sub_element(ElementName::ProvidedRequiredInterfaceTref)
210 .and_then(|r| r.get_reference_target().ok())?;
211 PortInterface::try_from(interface_elem).ok()
212 }
213
214 pub fn component_type(&self) -> Result<SwComponentType, AutosarAbstractionError> {
216 let component_type_elem = self.element().named_parent()?.unwrap();
217 SwComponentType::try_from(component_type_elem)
218 }
219}
220
221#[derive(Debug, Clone, PartialEq, Eq, Hash)]
225pub enum PortPrototype {
226 R(RPortPrototype),
228 P(PPortPrototype),
230 PR(PRPortPrototype),
232}
233
234impl AbstractionElement for PortPrototype {
235 fn element(&self) -> &Element {
236 match self {
237 PortPrototype::R(port) => port.element(),
238 PortPrototype::P(port) => port.element(),
239 PortPrototype::PR(port) => port.element(),
240 }
241 }
242}
243
244impl IdentifiableAbstractionElement for PortPrototype {}
245
246impl From<RPortPrototype> for PortPrototype {
247 fn from(port: RPortPrototype) -> Self {
248 PortPrototype::R(port)
249 }
250}
251
252impl From<PPortPrototype> for PortPrototype {
253 fn from(port: PPortPrototype) -> Self {
254 PortPrototype::P(port)
255 }
256}
257
258impl From<PRPortPrototype> for PortPrototype {
259 fn from(port: PRPortPrototype) -> Self {
260 PortPrototype::PR(port)
261 }
262}
263
264impl TryFrom<Element> for PortPrototype {
265 type Error = AutosarAbstractionError;
266
267 fn try_from(element: Element) -> Result<Self, Self::Error> {
268 match element.element_name() {
269 ElementName::RPortPrototype => Ok(PortPrototype::R(RPortPrototype(element))),
270 ElementName::PPortPrototype => Ok(PortPrototype::P(PPortPrototype(element))),
271 ElementName::PrPortPrototype => Ok(PortPrototype::PR(PRPortPrototype(element))),
272 _ => Err(AutosarAbstractionError::ConversionError {
273 element: element.clone(),
274 dest: "PortPrototype".to_string(),
275 }),
276 }
277 }
278}
279
280impl PortPrototype {
281 pub fn port_interface(&self) -> Option<PortInterface> {
283 match self {
284 PortPrototype::R(port) => port.port_interface(),
285 PortPrototype::P(port) => port.port_interface(),
286 PortPrototype::PR(port) => port.port_interface(),
287 }
288 }
289
290 pub fn component_type(&self) -> Result<SwComponentType, AutosarAbstractionError> {
292 let component_type_elem = self.element().named_parent()?.unwrap();
293 SwComponentType::try_from(component_type_elem)
294 }
295
296 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
298 match self {
299 PortPrototype::R(port) => port.remove(deep),
300 PortPrototype::P(port) => port.remove(deep),
301 PortPrototype::PR(port) => port.remove(deep),
302 }
303 }
304}
305
306#[derive(Debug, Clone, PartialEq, Eq, Hash)]
310pub struct PortGroup(Element);
311abstraction_element!(PortGroup, PortGroup);
312impl IdentifiableAbstractionElement for PortGroup {}
313
314impl PortGroup {
315 pub(crate) fn new(name: &str, parent_element: &Element) -> Result<Self, AutosarAbstractionError> {
317 let port_group = parent_element.create_named_sub_element(ElementName::PortGroup, name)?;
318
319 Ok(Self(port_group))
320 }
321}
322
323#[cfg(test)]
326mod test {
327 use super::*;
328 use crate::AutosarModelAbstraction;
329 use autosar_data::AutosarVersion;
330 use software_component::AbstractSwComponentType;
331
332 #[test]
333 fn ports() {
334 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
335 let package = model.get_or_create_package("/package").unwrap();
336
337 let comp = package.create_composition_sw_component_type("comp").unwrap();
338
339 let port_interface = package.create_sender_receiver_interface("sr_interface").unwrap();
340 let r_port = comp.create_r_port("sr_r_port", &port_interface).unwrap();
341 let p_port = comp.create_p_port("sr_p_port", &port_interface).unwrap();
342 let pr_port = comp.create_pr_port("sr_pr_port", &port_interface).unwrap();
343
344 assert_eq!(comp.ports().count(), 3);
345 let ports: Vec<PortPrototype> = comp.ports().collect();
346 assert_eq!(ports[0], r_port.clone().into());
347 assert_eq!(ports[1], p_port.clone().into());
348 assert_eq!(ports[2], pr_port.clone().into());
349 assert_eq!(r_port.component_type().unwrap(), comp.clone().into());
350 assert_eq!(p_port.component_type().unwrap(), comp.clone().into());
351 assert_eq!(pr_port.component_type().unwrap(), comp.clone().into());
352 assert_eq!(ports[0].component_type().unwrap(), comp.clone().into());
353
354 let port_interface = package.create_client_server_interface("cs_interface").unwrap();
355 let r_port = comp.create_r_port("cs_r_port", &port_interface).unwrap();
356 let p_port = comp.create_p_port("cs_p_port", &port_interface).unwrap();
357 let pr_port = comp.create_pr_port("cs_pr_port", &port_interface).unwrap();
358
359 assert_eq!(comp.ports().count(), 6);
360 let ports: Vec<PortPrototype> = comp.ports().collect();
361 assert_eq!(ports[3], r_port.into());
362 assert_eq!(ports[4], p_port.into());
363 assert_eq!(ports[5], pr_port.into());
364
365 let port_interface = package.create_mode_switch_interface("ms_interface").unwrap();
366 let r_port = comp.create_r_port("ms_r_port", &port_interface).unwrap();
367 let p_port = comp.create_p_port("ms_p_port", &port_interface).unwrap();
368 let pr_port = comp.create_pr_port("ms_pr_port", &port_interface).unwrap();
369
370 assert_eq!(comp.ports().count(), 9);
371 let ports: Vec<PortPrototype> = comp.ports().collect();
372 assert_eq!(ports[6], r_port.into());
373 assert_eq!(ports[7], p_port.into());
374 assert_eq!(ports[8], pr_port.into());
375
376 let port_interface = package.create_nv_data_interface("nv_interface").unwrap();
377 let r_port = comp.create_r_port("nv_r_port", &port_interface).unwrap();
378 let p_port = comp.create_p_port("nv_p_port", &port_interface).unwrap();
379 let pr_port = comp.create_pr_port("nv_pr_port", &port_interface).unwrap();
380
381 assert_eq!(comp.ports().count(), 12);
382 let ports: Vec<PortPrototype> = comp.ports().collect();
383 assert_eq!(ports[9], r_port.into());
384 assert_eq!(ports[10], p_port.into());
385 assert_eq!(ports[11], pr_port.into());
386
387 let port_interface = package.create_parameter_interface("param_interface").unwrap();
388 let r_port = comp.create_r_port("param_r_port", &port_interface).unwrap();
389 let p_port = comp.create_p_port("param_p_port", &port_interface).unwrap();
390 let pr_port_result = comp.create_pr_port("param_pr_port", &port_interface);
391 assert!(pr_port_result.is_err());
392
393 assert_eq!(comp.ports().count(), 14);
394 let ports: Vec<PortPrototype> = comp.ports().collect();
395 assert_eq!(ports[12], r_port.into());
396 assert_eq!(ports[13], p_port.into());
397
398 let port_interface = package.create_trigger_interface("trigger_interface").unwrap();
399 let r_port = comp.create_r_port("trigger_r_port", &port_interface).unwrap();
400 let p_port = comp.create_p_port("trigger_p_port", &port_interface).unwrap();
401 let pr_port = comp.create_pr_port("trigger_pr_port", &port_interface).unwrap();
402
403 assert_eq!(comp.ports().count(), 17);
404 let ports: Vec<PortPrototype> = comp.ports().collect();
405 assert_eq!(ports[14], r_port.into());
406 assert_eq!(ports[15], p_port.into());
407 assert_eq!(ports[16], pr_port.into());
408 }
409
410 #[test]
411 fn remove_port() {
412 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
413 let package = model.get_or_create_package("/package").unwrap();
414 let sender_receiver_interface = package.create_sender_receiver_interface("TestInterface").unwrap();
415
416 let composition_type = package.create_composition_sw_component_type("comp_parent").unwrap();
417 let r_port = composition_type
418 .create_r_port("port_r", &sender_receiver_interface)
419 .unwrap();
420 let p_port = composition_type
421 .create_p_port("port_p", &sender_receiver_interface)
422 .unwrap();
423 let pr_port = composition_type
424 .create_pr_port("port_pr", &sender_receiver_interface)
425 .unwrap();
426
427 let app_swc_type = package.create_application_sw_component_type("app_swc").unwrap();
429 let app_r_port = app_swc_type
430 .create_r_port("app_port_r", &sender_receiver_interface)
431 .unwrap();
432 let app_prototype = composition_type.create_component("app_proto", &app_swc_type).unwrap();
433 composition_type
435 .create_delegation_connector("delegation_connector", &app_r_port, &app_prototype, &r_port)
436 .unwrap();
437 assert_eq!(composition_type.connectors().count(), 1);
438
439 assert_eq!(composition_type.ports().count(), 3);
440 r_port.remove(true).unwrap();
441 assert_eq!(composition_type.connectors().count(), 0);
442 assert_eq!(composition_type.ports().count(), 2);
443 p_port.remove(true).unwrap();
444 assert_eq!(composition_type.ports().count(), 1);
445 pr_port.remove(true).unwrap();
446 assert_eq!(composition_type.ports().count(), 0);
447 }
448}