autosar_data_abstraction/software_component/
port.rs1use crate::{
2 AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element,
3 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 port_interface(&self) -> Result<PortInterface, AutosarAbstractionError> {
33 let interface_elem = self
34 .element()
35 .get_sub_element(ElementName::RequiredInterfaceTref)
36 .and_then(|r| r.get_reference_target().ok())
37 .ok_or(AutosarAbstractionError::InvalidParameter(
38 "RPortPrototype is incomplete: RequiredInterfaceTref is missing".to_string(),
39 ))?;
40 PortInterface::try_from(interface_elem)
41 }
42
43 pub fn component_type(&self) -> Result<SwComponentType, AutosarAbstractionError> {
45 let component_type_elem = self.element().named_parent()?.unwrap();
46 SwComponentType::try_from(component_type_elem)
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, Hash)]
54pub struct PPortPrototype(Element);
55abstraction_element!(PPortPrototype, PPortPrototype);
56impl IdentifiableAbstractionElement for PPortPrototype {}
57
58impl PPortPrototype {
59 pub(crate) fn new<T: AbstractPortInterface>(
61 name: &str,
62 parent_element: &Element,
63 interface: &T,
64 ) -> Result<Self, AutosarAbstractionError> {
65 let p_port_prototype = parent_element.create_named_sub_element(ElementName::PPortPrototype, name)?;
66 p_port_prototype
67 .create_sub_element(ElementName::ProvidedInterfaceTref)?
68 .set_reference_target(interface.element())?;
69
70 Ok(Self(p_port_prototype))
71 }
72
73 pub fn port_interface(&self) -> Result<PortInterface, AutosarAbstractionError> {
75 let interface_elem = self
76 .element()
77 .get_sub_element(ElementName::ProvidedInterfaceTref)
78 .and_then(|r| r.get_reference_target().ok())
79 .ok_or(AutosarAbstractionError::InvalidParameter(
80 "PPortPrototype is incomplete: ProvidedInterfaceTref is missing".to_string(),
81 ))?;
82 PortInterface::try_from(interface_elem)
83 }
84
85 pub fn component_type(&self) -> Result<SwComponentType, AutosarAbstractionError> {
87 let component_type_elem = self.element().named_parent()?.unwrap();
88 SwComponentType::try_from(component_type_elem)
89 }
90}
91
92#[derive(Debug, Clone, PartialEq, Eq, Hash)]
96pub struct PRPortPrototype(Element);
97abstraction_element!(PRPortPrototype, PrPortPrototype);
98impl IdentifiableAbstractionElement for PRPortPrototype {}
99
100impl PRPortPrototype {
101 pub(crate) fn new<T: AbstractPortInterface>(
103 name: &str,
104 parent_element: &Element,
105 interface: &T,
106 ) -> Result<Self, AutosarAbstractionError> {
107 if interface.element().element_name() == ElementName::ParameterInterface {
108 return Err(AutosarAbstractionError::InvalidParameter(
109 "ParameterInterface is not allowed for PRPortPrototype".to_string(),
110 ));
111 }
112
113 let pr_port_prototype = parent_element.create_named_sub_element(ElementName::PrPortPrototype, name)?;
114 pr_port_prototype
115 .create_sub_element(ElementName::ProvidedRequiredInterfaceTref)?
116 .set_reference_target(interface.element())?;
117
118 Ok(Self(pr_port_prototype))
119 }
120
121 pub fn port_interface(&self) -> Result<PortInterface, AutosarAbstractionError> {
123 let interface_elem = self
124 .element()
125 .get_sub_element(ElementName::ProvidedRequiredInterfaceTref)
126 .and_then(|r| r.get_reference_target().ok())
127 .ok_or(AutosarAbstractionError::InvalidParameter(
128 "PRPortPrototype is incomplete: ProvidedRequiredInterfaceTref is missing".to_string(),
129 ))?;
130 PortInterface::try_from(interface_elem)
131 }
132
133 pub fn component_type(&self) -> Result<SwComponentType, AutosarAbstractionError> {
135 let component_type_elem = self.element().named_parent()?.unwrap();
136 SwComponentType::try_from(component_type_elem)
137 }
138}
139
140#[derive(Debug, Clone, PartialEq, Eq, Hash)]
144pub enum PortPrototype {
145 R(RPortPrototype),
147 P(PPortPrototype),
149 PR(PRPortPrototype),
151}
152
153impl AbstractionElement for PortPrototype {
154 fn element(&self) -> &Element {
155 match self {
156 PortPrototype::R(port) => port.element(),
157 PortPrototype::P(port) => port.element(),
158 PortPrototype::PR(port) => port.element(),
159 }
160 }
161}
162
163impl IdentifiableAbstractionElement for PortPrototype {}
164
165impl From<RPortPrototype> for PortPrototype {
166 fn from(port: RPortPrototype) -> Self {
167 PortPrototype::R(port)
168 }
169}
170
171impl From<PPortPrototype> for PortPrototype {
172 fn from(port: PPortPrototype) -> Self {
173 PortPrototype::P(port)
174 }
175}
176
177impl From<PRPortPrototype> for PortPrototype {
178 fn from(port: PRPortPrototype) -> Self {
179 PortPrototype::PR(port)
180 }
181}
182
183impl TryFrom<Element> for PortPrototype {
184 type Error = AutosarAbstractionError;
185
186 fn try_from(element: Element) -> Result<Self, Self::Error> {
187 match element.element_name() {
188 ElementName::RPortPrototype => Ok(PortPrototype::R(RPortPrototype(element))),
189 ElementName::PPortPrototype => Ok(PortPrototype::P(PPortPrototype(element))),
190 ElementName::PrPortPrototype => Ok(PortPrototype::PR(PRPortPrototype(element))),
191 _ => Err(AutosarAbstractionError::ConversionError {
192 element: element.clone(),
193 dest: "PortPrototype".to_string(),
194 }),
195 }
196 }
197}
198
199impl PortPrototype {
200 pub fn port_interface(&self) -> Result<PortInterface, AutosarAbstractionError> {
202 match self {
203 PortPrototype::R(port) => port.port_interface(),
204 PortPrototype::P(port) => port.port_interface(),
205 PortPrototype::PR(port) => port.port_interface(),
206 }
207 }
208
209 pub fn component_type(&self) -> Result<SwComponentType, AutosarAbstractionError> {
211 let component_type_elem = self.element().named_parent()?.unwrap();
212 SwComponentType::try_from(component_type_elem)
213 }
214}
215
216#[derive(Debug, Clone, PartialEq, Eq, Hash)]
220pub struct PortGroup(Element);
221abstraction_element!(PortGroup, PortGroup);
222impl IdentifiableAbstractionElement for PortGroup {}
223
224impl PortGroup {
225 pub(crate) fn new(name: &str, parent_element: &Element) -> Result<Self, AutosarAbstractionError> {
227 let port_group = parent_element.create_named_sub_element(ElementName::PortGroup, name)?;
228
229 Ok(Self(port_group))
230 }
231}
232
233#[cfg(test)]
236mod test {
237 use super::*;
238 use crate::AutosarModelAbstraction;
239 use autosar_data::AutosarVersion;
240 use software_component::AbstractSwComponentType;
241
242 #[test]
243 fn ports() {
244 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
245 let package = model.get_or_create_package("/package").unwrap();
246
247 let comp = package.create_composition_sw_component_type("comp").unwrap();
248
249 let port_interface = package.create_sender_receiver_interface("sr_interface").unwrap();
250 let r_port = comp.create_r_port("sr_r_port", &port_interface).unwrap();
251 let p_port = comp.create_p_port("sr_p_port", &port_interface).unwrap();
252 let pr_port = comp.create_pr_port("sr_pr_port", &port_interface).unwrap();
253
254 assert_eq!(comp.ports().count(), 3);
255 let ports: Vec<PortPrototype> = comp.ports().collect();
256 assert_eq!(ports[0], r_port.clone().into());
257 assert_eq!(ports[1], p_port.clone().into());
258 assert_eq!(ports[2], pr_port.clone().into());
259 assert_eq!(r_port.component_type().unwrap(), comp.clone().into());
260 assert_eq!(p_port.component_type().unwrap(), comp.clone().into());
261 assert_eq!(pr_port.component_type().unwrap(), comp.clone().into());
262 assert_eq!(ports[0].component_type().unwrap(), comp.clone().into());
263
264 let port_interface = package.create_client_server_interface("cs_interface").unwrap();
265 let r_port = comp.create_r_port("cs_r_port", &port_interface).unwrap();
266 let p_port = comp.create_p_port("cs_p_port", &port_interface).unwrap();
267 let pr_port = comp.create_pr_port("cs_pr_port", &port_interface).unwrap();
268
269 assert_eq!(comp.ports().count(), 6);
270 let ports: Vec<PortPrototype> = comp.ports().collect();
271 assert_eq!(ports[3], r_port.into());
272 assert_eq!(ports[4], p_port.into());
273 assert_eq!(ports[5], pr_port.into());
274
275 let port_interface = package.create_mode_switch_interface("ms_interface").unwrap();
276 let r_port = comp.create_r_port("ms_r_port", &port_interface).unwrap();
277 let p_port = comp.create_p_port("ms_p_port", &port_interface).unwrap();
278 let pr_port = comp.create_pr_port("ms_pr_port", &port_interface).unwrap();
279
280 assert_eq!(comp.ports().count(), 9);
281 let ports: Vec<PortPrototype> = comp.ports().collect();
282 assert_eq!(ports[6], r_port.into());
283 assert_eq!(ports[7], p_port.into());
284 assert_eq!(ports[8], pr_port.into());
285
286 let port_interface = package.create_nv_data_interface("nv_interface").unwrap();
287 let r_port = comp.create_r_port("nv_r_port", &port_interface).unwrap();
288 let p_port = comp.create_p_port("nv_p_port", &port_interface).unwrap();
289 let pr_port = comp.create_pr_port("nv_pr_port", &port_interface).unwrap();
290
291 assert_eq!(comp.ports().count(), 12);
292 let ports: Vec<PortPrototype> = comp.ports().collect();
293 assert_eq!(ports[9], r_port.into());
294 assert_eq!(ports[10], p_port.into());
295 assert_eq!(ports[11], pr_port.into());
296
297 let port_interface = package.create_parameter_interface("param_interface").unwrap();
298 let r_port = comp.create_r_port("param_r_port", &port_interface).unwrap();
299 let p_port = comp.create_p_port("param_p_port", &port_interface).unwrap();
300 let pr_port_result = comp.create_pr_port("param_pr_port", &port_interface);
301 assert!(pr_port_result.is_err());
302
303 assert_eq!(comp.ports().count(), 14);
304 let ports: Vec<PortPrototype> = comp.ports().collect();
305 assert_eq!(ports[12], r_port.into());
306 assert_eq!(ports[13], p_port.into());
307
308 let port_interface = package.create_trigger_interface("trigger_interface").unwrap();
309 let r_port = comp.create_r_port("trigger_r_port", &port_interface).unwrap();
310 let p_port = comp.create_p_port("trigger_p_port", &port_interface).unwrap();
311 let pr_port = comp.create_pr_port("trigger_pr_port", &port_interface).unwrap();
312
313 assert_eq!(comp.ports().count(), 17);
314 let ports: Vec<PortPrototype> = comp.ports().collect();
315 assert_eq!(ports[14], r_port.into());
316 assert_eq!(ports[15], p_port.into());
317 assert_eq!(ports[16], pr_port.into());
318 }
319}