autosar_data_abstraction/datatype/
basetype.rs1use crate::{
2 AbstractionElement, ArPackage, AutosarAbstractionError, ByteOrder, Element, EnumItem,
3 IdentifiableAbstractionElement, abstraction_element,
4};
5use autosar_data::ElementName;
6use std::fmt::Display;
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
30pub struct SwBaseType(Element);
31abstraction_element!(SwBaseType, SwBaseType);
32impl IdentifiableAbstractionElement for SwBaseType {}
33
34impl SwBaseType {
35 pub(crate) fn new(
37 name: &str,
38 package: &ArPackage,
39 bit_length: u32,
40 base_type_encoding: BaseTypeEncoding,
41 byte_order: Option<ByteOrder>,
42 mem_alignment: Option<u32>,
43 native_declaration: Option<&str>,
44 ) -> Result<Self, AutosarAbstractionError> {
45 let elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
46 let sw_base_type = Self(elements.create_named_sub_element(ElementName::SwBaseType, name)?);
47 sw_base_type
48 .element()
49 .create_sub_element(ElementName::Category)?
50 .set_character_data("FIXED_LENGTH")?;
51 sw_base_type.set_base_type_encoding(base_type_encoding)?;
52 sw_base_type.set_bit_length(bit_length)?;
53 if let Some(byte_order) = byte_order {
54 sw_base_type.set_byte_order(byte_order)?;
55 }
56 if let Some(mem_alignment) = mem_alignment {
57 sw_base_type.set_mem_alignment(mem_alignment)?;
58 }
59 if let Some(native_declaration) = native_declaration {
60 sw_base_type.set_native_declaration(native_declaration)?;
61 }
62
63 Ok(sw_base_type)
64 }
65
66 pub fn set_bit_length(&self, bit_length: u32) -> Result<(), AutosarAbstractionError> {
68 self.element()
69 .get_or_create_sub_element(ElementName::BaseTypeSize)?
70 .set_character_data(bit_length.to_string())?;
71 Ok(())
72 }
73
74 #[must_use]
76 pub fn bit_length(&self) -> Option<u32> {
77 self.element()
78 .get_sub_element(ElementName::BaseTypeSize)?
79 .character_data()?
80 .parse_integer()
81 }
82
83 pub fn set_base_type_encoding(&self, base_type_encoding: BaseTypeEncoding) -> Result<(), AutosarAbstractionError> {
85 self.element()
86 .get_or_create_sub_element(ElementName::BaseTypeEncoding)?
87 .set_character_data(base_type_encoding.to_string())?;
88 Ok(())
89 }
90
91 #[must_use]
93 pub fn base_type_encoding(&self) -> Option<BaseTypeEncoding> {
94 let encoding_text = self
95 .element()
96 .get_sub_element(ElementName::BaseTypeEncoding)?
97 .character_data()?
98 .string_value()?;
99 BaseTypeEncoding::try_from(&*encoding_text).ok()
100 }
101
102 pub fn set_byte_order(&self, byte_order: ByteOrder) -> Result<(), AutosarAbstractionError> {
106 self.element()
107 .get_or_create_sub_element(ElementName::ByteOrder)?
108 .set_character_data::<EnumItem>(byte_order.into())?;
109 Ok(())
110 }
111
112 #[must_use]
114 pub fn byte_order(&self) -> Option<ByteOrder> {
115 self.element()
116 .get_sub_element(ElementName::ByteOrder)?
117 .character_data()?
118 .enum_value()?
119 .try_into()
120 .ok()
121 }
122
123 pub fn set_mem_alignment(&self, mem_alignment: u32) -> Result<(), AutosarAbstractionError> {
128 self.element()
129 .get_or_create_sub_element(ElementName::MemAlignment)?
130 .set_character_data(mem_alignment.to_string())?;
131 Ok(())
132 }
133
134 #[must_use]
136 pub fn mem_alignment(&self) -> Option<u32> {
137 self.element()
138 .get_sub_element(ElementName::MemAlignment)?
139 .character_data()?
140 .parse_integer()
141 }
142
143 pub fn set_native_declaration(&self, native_declaration: &str) -> Result<(), AutosarAbstractionError> {
147 self.element()
148 .get_or_create_sub_element(ElementName::NativeDeclaration)?
149 .set_character_data(native_declaration)?;
150 Ok(())
151 }
152
153 #[must_use]
155 pub fn native_declaration(&self) -> Option<String> {
156 self.element()
157 .get_sub_element(ElementName::NativeDeclaration)?
158 .character_data()?
159 .string_value()
160 }
161}
162
163#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
167pub enum BaseTypeEncoding {
168 OnesComplement,
170 TwosComplement,
172 SignMagnitude,
174 BcdPacked,
176 BcdUnpacked,
178 DspFractional,
180 Ieee754,
182 Iso8859_1,
184 Iso8859_2,
186 Windows1252,
188 Utf8,
190 Utf16,
192 Ucs2,
194 Boolean,
196 Void,
198 None,
200}
201
202impl Display for BaseTypeEncoding {
203 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
204 match self {
205 BaseTypeEncoding::OnesComplement => f.write_str("1C"),
206 BaseTypeEncoding::TwosComplement => f.write_str("2C"),
207 BaseTypeEncoding::SignMagnitude => f.write_str("SM"),
208 BaseTypeEncoding::BcdPacked => f.write_str("BCD-P"),
209 BaseTypeEncoding::BcdUnpacked => f.write_str("BCD-UP"),
210 BaseTypeEncoding::DspFractional => f.write_str("DSP-FRACTIONAL"),
211 BaseTypeEncoding::Ieee754 => f.write_str("IEEE754"),
212 BaseTypeEncoding::Iso8859_1 => f.write_str("ISO-8859-1"),
213 BaseTypeEncoding::Iso8859_2 => f.write_str("ISO-8859-2"),
214 BaseTypeEncoding::Windows1252 => f.write_str("WINDOWS-1252"),
215 BaseTypeEncoding::Utf8 => f.write_str("UTF-8"),
216 BaseTypeEncoding::Utf16 => f.write_str("UTF-16"),
217 BaseTypeEncoding::Ucs2 => f.write_str("UCS-2"),
218 BaseTypeEncoding::Boolean => f.write_str("BOOLEAN"),
219 BaseTypeEncoding::Void => f.write_str("VOID"),
220 BaseTypeEncoding::None => f.write_str("NONE"),
221 }
222 }
223}
224
225impl TryFrom<&str> for BaseTypeEncoding {
226 type Error = AutosarAbstractionError;
227
228 fn try_from(value: &str) -> Result<Self, Self::Error> {
229 match value {
230 "1C" => Ok(BaseTypeEncoding::OnesComplement),
231 "2C" => Ok(BaseTypeEncoding::TwosComplement),
232 "SM" => Ok(BaseTypeEncoding::SignMagnitude),
233 "BCD-P" => Ok(BaseTypeEncoding::BcdPacked),
234 "BCD-UP" => Ok(BaseTypeEncoding::BcdUnpacked),
235 "DSP-FRACTIONAL" => Ok(BaseTypeEncoding::DspFractional),
236 "IEEE754" => Ok(BaseTypeEncoding::Ieee754),
237 "ISO-8859-1" => Ok(BaseTypeEncoding::Iso8859_1),
238 "ISO-8859-2" => Ok(BaseTypeEncoding::Iso8859_2),
239 "WINDOWS-1252" => Ok(BaseTypeEncoding::Windows1252),
240 "UTF-8" => Ok(BaseTypeEncoding::Utf8),
241 "UTF-16" => Ok(BaseTypeEncoding::Utf16),
242 "UCS-2" => Ok(BaseTypeEncoding::Ucs2),
243 "BOOLEAN" => Ok(BaseTypeEncoding::Boolean),
244 "VOID" => Ok(BaseTypeEncoding::Void),
245 "NONE" => Ok(BaseTypeEncoding::None),
246 _ => Err(AutosarAbstractionError::ValueConversionError {
247 value: value.to_string(),
248 dest: "BaseTypeEncoding".to_string(),
249 }),
250 }
251 }
252}
253
254#[cfg(test)]
257mod tests {
258 use crate::AutosarModelAbstraction;
259
260 use super::*;
261 use autosar_data::AutosarVersion;
262
263 #[test]
264 fn test_base_type_encoding() {
265 let encoding = BaseTypeEncoding::OnesComplement;
266 assert_eq!(encoding.to_string(), "1C");
267 assert_eq!(BaseTypeEncoding::try_from("1C").unwrap(), encoding);
268 }
269
270 #[test]
271 fn test_sw_base_type() {
272 let model = AutosarModelAbstraction::create("filename", AutosarVersion::LATEST);
273 let package = model.get_or_create_package("/BaseTypes").unwrap();
274
275 let sw_base_type = SwBaseType::new(
276 "TestType",
277 &package,
278 32,
279 BaseTypeEncoding::None,
280 Some(ByteOrder::MostSignificantByteFirst),
281 Some(8),
282 Some("uint32"),
283 )
284 .unwrap();
285 assert_eq!(sw_base_type.bit_length(), Some(32));
286 assert_eq!(sw_base_type.base_type_encoding(), Some(BaseTypeEncoding::None));
287 assert_eq!(sw_base_type.byte_order(), Some(ByteOrder::MostSignificantByteFirst));
288 assert_eq!(sw_base_type.mem_alignment(), Some(8));
289 assert_eq!(sw_base_type.native_declaration(), Some("uint32".to_string()));
290 }
291}