autosar_data_abstraction/communication/controller/
mod.rs1use crate::{AbstractionElement, AutosarAbstractionError, EcuInstance, IdentifiableAbstractionElement};
2use autosar_data::{AutosarDataError, Element, ElementName};
3
4mod can;
5mod ethernet;
6mod flexray;
7
8pub use can::*;
9pub use ethernet::*;
10pub use flexray::*;
11
12#[derive(Debug, Clone, PartialEq, Eq)]
16#[non_exhaustive]
17pub enum CommunicationController {
18 Can(CanCommunicationController),
20 Ethernet(EthernetCommunicationController),
22 Flexray(FlexrayCommunicationController),
24}
25
26impl AbstractionElement for CommunicationController {
27 fn element(&self) -> &autosar_data::Element {
28 match self {
29 CommunicationController::Can(ccc) => ccc.element(),
30 CommunicationController::Ethernet(ecc) => ecc.element(),
31 CommunicationController::Flexray(fcc) => fcc.element(),
32 }
33 }
34}
35
36impl TryFrom<Element> for CommunicationController {
37 type Error = AutosarAbstractionError;
38
39 fn try_from(element: Element) -> Result<Self, Self::Error> {
40 match element.element_name() {
41 ElementName::CanCommunicationController => Ok(Self::Can(CanCommunicationController::try_from(element)?)),
42 ElementName::EthernetCommunicationController => {
43 Ok(Self::Ethernet(EthernetCommunicationController::try_from(element)?))
44 }
45 ElementName::FlexrayCommunicationController => {
46 Ok(Self::Flexray(FlexrayCommunicationController::try_from(element)?))
47 }
48 _ => Err(AutosarAbstractionError::ConversionError {
49 element,
50 dest: "CommunicationController".to_string(),
51 }),
52 }
53 }
54}
55
56impl IdentifiableAbstractionElement for CommunicationController {}
57impl AbstractCommunicationController for CommunicationController {}
58
59impl From<CanCommunicationController> for CommunicationController {
60 fn from(value: CanCommunicationController) -> Self {
61 CommunicationController::Can(value)
62 }
63}
64
65impl From<EthernetCommunicationController> for CommunicationController {
66 fn from(value: EthernetCommunicationController) -> Self {
67 CommunicationController::Ethernet(value)
68 }
69}
70
71impl From<FlexrayCommunicationController> for CommunicationController {
72 fn from(value: FlexrayCommunicationController) -> Self {
73 CommunicationController::Flexray(value)
74 }
75}
76
77pub trait AbstractCommunicationController: AbstractionElement {
81 fn ecu_instance(&self) -> Result<EcuInstance, AutosarAbstractionError> {
102 self.element().named_parent()?.unwrap().try_into()
106 }
107}
108
109pub trait AbstractCommunicationConnector: AbstractionElement {
113 type CommunicationControllerType: AbstractCommunicationController;
115
116 fn ecu_instance(&self) -> Result<EcuInstance, AutosarAbstractionError> {
118 self.element().named_parent()?.unwrap().try_into()
122 }
123
124 fn controller(&self) -> Result<Self::CommunicationControllerType, AutosarAbstractionError>;
126}
127
128#[derive(Debug, Clone, PartialEq, Eq)]
132pub enum CommunicationConnector {
133 Can(CanCommunicationConnector),
135 Ethernet(EthernetCommunicationConnector),
137 Flexray(FlexrayCommunicationConnector),
139}
140
141impl AbstractionElement for CommunicationConnector {
142 fn element(&self) -> &autosar_data::Element {
143 match self {
144 CommunicationConnector::Can(cc) => cc.element(),
145 CommunicationConnector::Ethernet(ec) => ec.element(),
146 CommunicationConnector::Flexray(fc) => fc.element(),
147 }
148 }
149}
150
151impl TryFrom<Element> for CommunicationConnector {
152 type Error = AutosarAbstractionError;
153
154 fn try_from(element: Element) -> Result<Self, Self::Error> {
155 match element.element_name() {
156 ElementName::CanCommunicationConnector => Ok(Self::Can(CanCommunicationConnector::try_from(element)?)),
157 ElementName::EthernetCommunicationConnector => {
158 Ok(Self::Ethernet(EthernetCommunicationConnector::try_from(element)?))
159 }
160 ElementName::FlexrayCommunicationConnector => {
161 Ok(Self::Flexray(FlexrayCommunicationConnector::try_from(element)?))
162 }
163 _ => Err(AutosarAbstractionError::ConversionError {
164 element,
165 dest: "CommunicationConnector".to_string(),
166 }),
167 }
168 }
169}
170
171impl IdentifiableAbstractionElement for CommunicationConnector {}
172
173impl AbstractCommunicationConnector for CommunicationConnector {
174 type CommunicationControllerType = CommunicationController;
175
176 fn controller(&self) -> Result<Self::CommunicationControllerType, AutosarAbstractionError> {
177 let Some(controller_ref) = self.element().get_sub_element(ElementName::CommControllerRef) else {
178 return Err(AutosarAbstractionError::ModelError(AutosarDataError::ElementNotFound {
179 target: ElementName::CommControllerRef,
180 parent: self.element().element_name(),
181 }));
182 };
183 let controller = controller_ref.get_reference_target()?;
184 Self::CommunicationControllerType::try_from(controller)
185 }
186}
187
188#[cfg(test)]
191mod tests {
192 use super::*;
193 use crate::{
194 AutosarModelAbstraction, SystemCategory,
195 communication::{FlexrayChannelName, FlexrayClusterSettings},
196 };
197 use autosar_data::AutosarVersion;
198
199 #[test]
200 fn test_communication_controller() {
201 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
202 let package = model.get_or_create_package("/test").unwrap();
203 let system = package.create_system("System", SystemCategory::SystemExtract).unwrap();
204
205 let ecu = system.create_ecu_instance("ecu", &package).unwrap();
206 let can_ctrl = ecu.create_can_communication_controller("can").unwrap();
207 let ethernet_ctrl = ecu.create_ethernet_communication_controller("ethernet", None).unwrap();
208 let flexray_ctrl = ecu.create_flexray_communication_controller("flexray").unwrap();
209
210 let can_cc: CommunicationController = can_ctrl.clone().into();
211 let ethernet_cc: CommunicationController = ethernet_ctrl.clone().into();
212 let flexray_cc: CommunicationController = flexray_ctrl.clone().into();
213
214 let can_cluster = system.create_can_cluster("can_cluster", &package, None).unwrap();
215 let ethernet_cluster = system.create_ethernet_cluster("ethernet_cluster", &package).unwrap();
216 let flexray_cluster = system
217 .create_flexray_cluster("flexray_cluster", &package, &FlexrayClusterSettings::default())
218 .unwrap();
219
220 let can_channel = can_cluster.create_physical_channel("can_channel").unwrap();
221 let ethernet_channel = ethernet_cluster
222 .create_physical_channel("ethernet_channel", None)
223 .unwrap();
224 let flexray_channel = flexray_cluster
225 .create_physical_channel("flexray_channel", FlexrayChannelName::A)
226 .unwrap();
227
228 let can_connector = can_ctrl
229 .connect_physical_channel("can_connector", &can_channel)
230 .unwrap();
231 let ethernet_connector = ethernet_ctrl
232 .connect_physical_channel("ethernet_connector", ðernet_channel)
233 .unwrap();
234 let flexray_connector = flexray_ctrl
235 .connect_physical_channel("flexray_connector", &flexray_channel)
236 .unwrap();
237
238 let connector: CommunicationConnector = CommunicationConnector::Can(can_connector.clone());
239 assert_eq!(connector.controller().unwrap(), can_cc);
240 let connector = CommunicationConnector::Ethernet(ethernet_connector.clone());
241 assert_eq!(connector.controller().unwrap(), ethernet_cc);
242 let connector = CommunicationConnector::Flexray(flexray_connector.clone());
243 assert_eq!(connector.controller().unwrap(), flexray_cc);
244
245 assert_eq!(can_cc.element().item_name().unwrap(), "can");
246 assert_eq!(ethernet_cc.element().item_name().unwrap(), "ethernet");
247 assert_eq!(flexray_cc.element().item_name().unwrap(), "flexray");
248 }
249}