autosar_data_abstraction/communication/cluster/
lin.rs1use crate::communication::{AbstractCluster, LinPhysicalChannel};
2use crate::{
3 AbstractionElement, ArPackage, AutosarAbstractionError, IdentifiableAbstractionElement, abstraction_element,
4};
5use autosar_data::{Element, ElementName};
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub struct LinCluster(Element);
13abstraction_element!(LinCluster, LinCluster);
14impl IdentifiableAbstractionElement for LinCluster {}
15
16impl LinCluster {
17 pub(crate) fn new(cluster_name: &str, package: &ArPackage) -> Result<Self, AutosarAbstractionError> {
19 let elem_pkg_elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
20 let elem_cluster = elem_pkg_elements.create_named_sub_element(ElementName::LinCluster, cluster_name)?;
21 if let Ok(cluster_content) = elem_cluster
22 .create_sub_element(ElementName::LinClusterVariants)
23 .and_then(|ccv| ccv.create_sub_element(ElementName::LinClusterConditional))
24 {
25 let _ = cluster_content
26 .create_sub_element(ElementName::ProtocolName)
27 .and_then(|pn| pn.set_character_data("CAN"));
28
29 let _ = cluster_content.create_sub_element(ElementName::PhysicalChannels);
30 }
31
32 let lin_cluster = LinCluster(elem_cluster);
33
34 Ok(lin_cluster)
35 }
36
37 pub fn create_physical_channel(&self, channel_name: &str) -> Result<LinPhysicalChannel, AutosarAbstractionError> {
61 let phys_channels = self
62 .0
63 .get_or_create_sub_element(ElementName::LinClusterVariants)?
64 .get_or_create_sub_element(ElementName::LinClusterConditional)?
65 .get_or_create_sub_element(ElementName::PhysicalChannels)?;
66
67 if phys_channels.sub_elements().count() != 0 {
68 return Err(AutosarAbstractionError::ItemAlreadyExists);
69 }
70
71 let channel = phys_channels.create_named_sub_element(ElementName::LinPhysicalChannel, channel_name)?;
72
73 LinPhysicalChannel::try_from(channel)
74 }
75
76 #[must_use]
96 pub fn physical_channel(&self) -> Option<LinPhysicalChannel> {
97 let channel = self
98 .0
99 .get_sub_element(ElementName::LinClusterVariants)?
100 .get_sub_element(ElementName::LinClusterConditional)?
101 .get_sub_element(ElementName::PhysicalChannels)?
102 .get_sub_element(ElementName::LinPhysicalChannel)?;
103 LinPhysicalChannel::try_from(channel).ok()
104 }
105}
106
107impl AbstractCluster for LinCluster {}
108
109#[cfg(test)]
112mod test {
113 use crate::{AutosarModelAbstraction, SystemCategory, communication::AbstractCluster};
114 use autosar_data::AutosarVersion;
115
116 #[test]
117 fn cluster() {
118 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00051);
119 let pkg = model.get_or_create_package("/test").unwrap();
120 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
121
122 let pkg2 = model.get_or_create_package("/lin").unwrap();
123 let result = system.create_lin_cluster("LinCluster", &pkg2);
125 assert!(result.is_ok());
126 let cluster = result.unwrap();
127 let result = system.create_lin_cluster("LinCluster", &pkg2);
129 assert!(result.is_err());
130
131 let linked_system = cluster.system().unwrap();
133 assert_eq!(linked_system, system);
134
135 let result = cluster.create_physical_channel("Channel1");
137 assert!(result.is_ok());
138 let result = cluster.create_physical_channel("Channel2");
140 assert!(result.is_err());
141
142 let pc = cluster.physical_channel();
143 assert!(pc.is_some());
144 }
145}