autosar_data_abstraction/communication/cluster/
mod.rs1use crate::{AbstractionElement, AutosarAbstractionError, IdentifiableAbstractionElement, System};
2use autosar_data::{Element, ElementName};
3
4mod can;
5mod ethernet;
6mod flexray;
7
8pub use can::*;
9pub use ethernet::*;
10pub use flexray::*;
11
12pub trait AbstractCluster: AbstractionElement {
16 fn system(&self) -> Option<System> {
18 if let Ok(model) = self.element().model() {
19 let path = self.element().path().ok()?;
20 let refs = model.get_references_to(&path);
21
22 if let Some(system) = refs
23 .iter()
24 .filter_map(autosar_data::WeakElement::upgrade)
25 .filter(|elem| elem.element_name() == ElementName::FibexElementRef)
26 .filter_map(|elem| elem.named_parent().ok().flatten())
27 .find_map(|parent| System::try_from(parent).ok())
28 {
29 return Some(system);
30 }
31 }
32 None
33 }
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
41#[non_exhaustive]
42pub enum Cluster {
43 Can(CanCluster),
45 Ethernet(EthernetCluster),
47 FlexRay(FlexrayCluster),
49 }
51
52impl AbstractionElement for Cluster {
53 fn element(&self) -> &autosar_data::Element {
54 match self {
55 Cluster::Can(cancluster) => cancluster.element(),
56 Cluster::Ethernet(ethcluster) => ethcluster.element(),
57 Cluster::FlexRay(flxcluster) => flxcluster.element(),
58 }
59 }
60}
61
62impl IdentifiableAbstractionElement for Cluster {}
63impl AbstractCluster for Cluster {}
64
65impl TryFrom<Element> for Cluster {
66 type Error = AutosarAbstractionError;
67
68 fn try_from(element: Element) -> Result<Self, Self::Error> {
69 match element.element_name() {
70 ElementName::CanCluster => Ok(CanCluster::try_from(element)?.into()),
71 ElementName::EthernetCluster => Ok(EthernetCluster::try_from(element)?.into()),
72 ElementName::FlexrayCluster => Ok(FlexrayCluster::try_from(element)?.into()),
73 _ => Err(AutosarAbstractionError::ConversionError {
74 element,
75 dest: "Cluster".to_string(),
76 }),
77 }
78 }
79}
80
81impl From<CanCluster> for Cluster {
82 fn from(value: CanCluster) -> Self {
83 Cluster::Can(value)
84 }
85}
86
87impl From<EthernetCluster> for Cluster {
88 fn from(value: EthernetCluster) -> Self {
89 Cluster::Ethernet(value)
90 }
91}
92
93impl From<FlexrayCluster> for Cluster {
94 fn from(value: FlexrayCluster) -> Self {
95 Cluster::FlexRay(value)
96 }
97}
98
99#[cfg(test)]
102mod tests {
103 use super::*;
104 use crate::AutosarModelAbstraction;
105 use autosar_data::AutosarVersion;
106
107 #[test]
108 fn cluster_system() {
109 let model = AutosarModelAbstraction::create("test.arxml", AutosarVersion::LATEST);
110 let package = model.get_or_create_package("/Test").unwrap();
111 let system = package
112 .create_system("System", crate::SystemCategory::EcuExtract)
113 .unwrap();
114 let can_cluster = CanCluster::new("CanCluster", &package, None).unwrap();
115
116 assert!(can_cluster.system().is_none());
117 system.create_fibex_element_ref(can_cluster.element()).unwrap();
118 assert_eq!(can_cluster.system().unwrap(), system);
119 }
120
121 #[test]
122 fn cluster_conversion() {
123 let model = AutosarModelAbstraction::create("test.arxml", AutosarVersion::LATEST);
124 let package = model.get_or_create_package("/Test").unwrap();
125 let can_cluster = CanCluster::new("CanCluster", &package, None).unwrap();
126 let ethernet_cluster = EthernetCluster::new("EthernetCluster", &package).unwrap();
127 let flexray_settings = FlexrayClusterSettings::default();
128 let flexray_cluster = FlexrayCluster::new("FlexrayCluster", &package, &flexray_settings).unwrap();
129
130 let can: Cluster = can_cluster.into();
131 let ethernet: Cluster = ethernet_cluster.into();
132 let flexray: Cluster = flexray_cluster.into();
133
134 assert_eq!(can.element().item_name().unwrap(), "CanCluster");
135 assert_eq!(ethernet.element().item_name().unwrap(), "EthernetCluster");
136 assert_eq!(flexray.element().item_name().unwrap(), "FlexrayCluster");
137 }
138}