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 remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
39 if let Some(channel) = self.physical_channel() {
41 channel.remove(deep)?;
42 }
43
44 AbstractionElement::remove(self, deep)?;
46
47 Ok(())
48 }
49
50 pub fn create_physical_channel(&self, channel_name: &str) -> Result<LinPhysicalChannel, AutosarAbstractionError> {
74 let phys_channels = self
75 .0
76 .get_or_create_sub_element(ElementName::LinClusterVariants)?
77 .get_or_create_sub_element(ElementName::LinClusterConditional)?
78 .get_or_create_sub_element(ElementName::PhysicalChannels)?;
79
80 if phys_channels.sub_elements().count() != 0 {
81 return Err(AutosarAbstractionError::ItemAlreadyExists);
82 }
83
84 let channel = phys_channels.create_named_sub_element(ElementName::LinPhysicalChannel, channel_name)?;
85
86 LinPhysicalChannel::try_from(channel)
87 }
88
89 #[must_use]
109 pub fn physical_channel(&self) -> Option<LinPhysicalChannel> {
110 let channel = self
111 .0
112 .get_sub_element(ElementName::LinClusterVariants)?
113 .get_sub_element(ElementName::LinClusterConditional)?
114 .get_sub_element(ElementName::PhysicalChannels)?
115 .get_sub_element(ElementName::LinPhysicalChannel)?;
116 LinPhysicalChannel::try_from(channel).ok()
117 }
118}
119
120impl AbstractCluster for LinCluster {}
121
122#[cfg(test)]
125mod test {
126 use crate::{AutosarModelAbstraction, SystemCategory, communication::AbstractCluster};
127 use autosar_data::AutosarVersion;
128
129 #[test]
130 fn cluster() {
131 let model = AutosarModelAbstraction::create("filename", AutosarVersion::Autosar_00051);
132 let pkg = model.get_or_create_package("/test").unwrap();
133 let system = pkg.create_system("System", SystemCategory::SystemDescription).unwrap();
134
135 let pkg2 = model.get_or_create_package("/lin").unwrap();
136 let result = system.create_lin_cluster("LinCluster", &pkg2);
138 assert!(result.is_ok());
139 let cluster = result.unwrap();
140 let result = system.create_lin_cluster("LinCluster", &pkg2);
142 assert!(result.is_err());
143
144 let linked_system = cluster.system().unwrap();
146 assert_eq!(linked_system, system);
147
148 let result = cluster.create_physical_channel("Channel1");
150 assert!(result.is_ok());
151 let result = cluster.create_physical_channel("Channel2");
153 assert!(result.is_err());
154
155 let pc = cluster.physical_channel();
156 assert!(pc.is_some());
157 }
158}