1use crate::{
2 AbstractionElement, ArPackage, AutosarAbstractionError, ByteOrder, IdentifiableAbstractionElement,
3 abstraction_element, get_reference_parents, is_used,
4};
5use autosar_data::{AutosarVersion, Element, ElementName, EnumItem};
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
11pub struct DataTransformationSet(Element);
12abstraction_element!(DataTransformationSet, DataTransformationSet);
13impl IdentifiableAbstractionElement for DataTransformationSet {}
14
15impl DataTransformationSet {
16 pub(crate) fn new(name: &str, package: &ArPackage) -> Result<Self, AutosarAbstractionError> {
18 let elements = package.element().get_or_create_sub_element(ElementName::Elements)?;
19 let transformation_set = elements.create_named_sub_element(ElementName::DataTransformationSet, name)?;
20
21 Ok(Self(transformation_set))
22 }
23
24 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
26 for transformation_tech in self.transformation_technologies() {
27 transformation_tech.remove(deep)?;
28 }
29
30 for data_transformation in self.data_transformations() {
31 data_transformation.remove(deep)?;
32 }
33
34 AbstractionElement::remove(self, deep)
35 }
36
37 pub fn create_data_transformation(
39 &self,
40 name: &str,
41 transformations: &[&TransformationTechnology],
42 execute_despite_data_unavailability: bool,
43 ) -> Result<DataTransformation, AutosarAbstractionError> {
44 let data_transformations = self
45 .element()
46 .get_or_create_sub_element(ElementName::DataTransformations)?;
47 let transformation = DataTransformation::new(
48 &data_transformations,
49 name,
50 transformations,
51 execute_despite_data_unavailability,
52 )?;
53 Ok(transformation)
54 }
55
56 pub fn data_transformations(&self) -> impl Iterator<Item = DataTransformation> + Send + use<> {
58 self.element()
59 .get_sub_element(ElementName::DataTransformations)
60 .into_iter()
61 .flat_map(|container| container.sub_elements())
62 .filter_map(|elem| elem.try_into().ok())
63 }
64
65 pub fn create_transformation_technology(
67 &self,
68 name: &str,
69 config: &TransformationTechnologyConfig,
70 ) -> Result<TransformationTechnology, AutosarAbstractionError> {
71 let transtechs = self
72 .element()
73 .get_or_create_sub_element(ElementName::TransformationTechnologys)?;
74 TransformationTechnology::new(&transtechs, name, config)
75 }
76
77 pub fn transformation_technologies(&self) -> impl Iterator<Item = TransformationTechnology> + Send + use<> {
79 self.element()
80 .get_sub_element(ElementName::TransformationTechnologys)
81 .into_iter()
82 .flat_map(|container| container.sub_elements())
83 .filter_map(|elem| elem.try_into().ok())
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq, Hash)]
91pub struct DataTransformation(Element);
92abstraction_element!(DataTransformation, DataTransformation);
93impl IdentifiableAbstractionElement for DataTransformation {}
94
95impl DataTransformation {
96 fn new(
98 parent: &Element,
99 name: &str,
100 transformations: &[&TransformationTechnology],
101 execute_despite_data_unavailability: bool,
102 ) -> Result<Self, AutosarAbstractionError> {
103 if transformations.is_empty() {
105 return Err(AutosarAbstractionError::InvalidParameter(
106 "A DataTransformation must contain at least one TransformationTechnology".to_string(),
107 ));
108 }
109
110 for transformation in &transformations[1..] {
112 if transformation.transformer_class() == Some(EnumItem::Serializer) {
113 return Err(AutosarAbstractionError::InvalidParameter(
114 "A DataTransformation may only contain a TransformationTechnology with TransformerClass 'Serializer' at the start of the chain".to_string(),
115 ));
116 }
117 }
118
119 let dts = parent
121 .named_parent()?
122 .and_then(|dts| DataTransformationSet::try_from(dts).ok());
123 if !transformations
124 .iter()
125 .all(|ttech| ttech.data_transformation_set() == dts)
126 {
127 return Err(AutosarAbstractionError::InvalidParameter(
128 "All TransformationTechnologies in a DataTransformation must be part of the same DataTransformationSet"
129 .to_string(),
130 ));
131 }
132
133 if transformations
135 .iter()
136 .any(|ttech| ttech.protocol().as_deref() == Some("E2E"))
137 && !execute_despite_data_unavailability
138 {
139 return Err(AutosarAbstractionError::InvalidParameter(
140 "If a DataTransformation contains an E2E transformation, executeDespiteDataUnavailability must be true"
141 .to_string(),
142 ));
143 }
144
145 let transformation = parent.create_named_sub_element(ElementName::DataTransformation, name)?;
146 transformation
147 .create_sub_element(ElementName::ExecuteDespiteDataUnavailability)?
148 .set_character_data(execute_despite_data_unavailability)?;
149 let chain_refs = transformation.create_sub_element(ElementName::TransformerChainRefs)?;
150 for transformation in transformations {
151 chain_refs
152 .create_sub_element(ElementName::TransformerChainRef)?
153 .set_reference_target(transformation.element())?;
154 }
155
156 Ok(Self(transformation))
157 }
158
159 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
161 let transformation_technologies: Vec<_> = self.transformation_technologies().collect();
162 let opt_data_transformation_set = self.data_transformation_set();
163
164 AbstractionElement::remove(self, deep)?;
165
166 if deep {
167 if let Some(dts) = opt_data_transformation_set
169 && dts.data_transformations().count() == 0
170 {
171 dts.remove(true)?;
172 }
173
174 for ttech in transformation_technologies {
175 if !is_used(ttech.element()) {
176 ttech.remove(true)?;
178 }
179 }
180 }
181
182 Ok(())
183 }
184
185 #[must_use]
187 pub fn data_transformation_set(&self) -> Option<DataTransformationSet> {
188 self.element()
189 .named_parent()
190 .ok()?
191 .and_then(|dts| DataTransformationSet::try_from(dts).ok())
192 }
193
194 pub fn transformation_technologies(&self) -> impl Iterator<Item = TransformationTechnology> + Send + use<> {
213 self.0
214 .get_sub_element(ElementName::TransformerChainRefs)
215 .into_iter()
216 .flat_map(|container| container.sub_elements())
217 .filter_map(|elem| {
218 elem.get_reference_target()
219 .ok()
220 .and_then(|ttech| TransformationTechnology::try_from(ttech).ok())
221 })
222 }
223}
224
225#[derive(Debug, Clone, PartialEq, Eq, Hash)]
229pub struct TransformationTechnology(Element);
230abstraction_element!(TransformationTechnology, TransformationTechnology);
231impl IdentifiableAbstractionElement for TransformationTechnology {}
232
233impl TransformationTechnology {
234 fn new(
236 parent: &Element,
237 name: &str,
238 config: &TransformationTechnologyConfig,
239 ) -> Result<Self, AutosarAbstractionError> {
240 let ttech_elem = parent.create_named_sub_element(ElementName::TransformationTechnology, name)?;
241 let ttech = Self(ttech_elem);
242 ttech.set_config(config)?;
243
244 Ok(ttech)
245 }
246
247 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
249 let opt_data_transformation_set = self.data_transformation_set();
250 let ref_parents = get_reference_parents(self.element())?;
251
252 AbstractionElement::remove(self, deep)?;
253
254 for (named_parent, _parent) in ref_parents {
255 match named_parent.element_name() {
256 ElementName::EndToEndTransformationISignalProps | ElementName::SomeipTransformationISignalProps => {
257 if let Ok(component) = TransformationISignalProps::try_from(named_parent) {
258 component.remove(deep)?;
259 }
260 }
261 _ => {}
262 }
263 }
264
265 if deep {
266 if let Some(dts) = opt_data_transformation_set
268 && !is_used(dts.element())
269 {
270 dts.remove(true)?;
271 }
272 }
273
274 Ok(())
275 }
276
277 pub fn set_config(&self, config: &TransformationTechnologyConfig) -> Result<(), AutosarAbstractionError> {
279 let ttech = self.element();
280 let version = ttech.min_version()?;
281 let buffer_props = ttech.get_or_create_sub_element(ElementName::BufferProperties)?;
282
283 match config {
284 TransformationTechnologyConfig::Generic(generic_config) => {
285 ttech
286 .get_or_create_sub_element(ElementName::Protocol)?
287 .set_character_data(generic_config.protocol_name.as_str())?;
288 ttech
289 .get_or_create_sub_element(ElementName::Version)?
290 .set_character_data(generic_config.protocol_version.as_str())?;
291 ttech
292 .get_or_create_sub_element(ElementName::TransformerClass)?
293 .set_character_data(EnumItem::Custom)?;
294 buffer_props
295 .get_or_create_sub_element(ElementName::HeaderLength)?
296 .set_character_data(u64::from(generic_config.header_length))?;
297 buffer_props
298 .get_or_create_sub_element(ElementName::InPlace)?
299 .set_character_data(generic_config.in_place)?;
300
301 let _ = ttech.remove_sub_element_kind(ElementName::TransformationDescriptions);
303 let _ = buffer_props.remove_sub_element_kind(ElementName::BufferComputation);
305 let _ = ttech.remove_sub_element_kind(ElementName::NeedsOriginalData);
307 }
308 TransformationTechnologyConfig::Com(com_config) => {
309 ttech
310 .get_or_create_sub_element(ElementName::Protocol)?
311 .set_character_data("COMBased")?;
312 ttech
313 .get_or_create_sub_element(ElementName::Version)?
314 .set_character_data("1")?;
315 ttech
316 .get_or_create_sub_element(ElementName::TransformerClass)?
317 .set_character_data(EnumItem::Serializer)?;
318
319 buffer_props
321 .get_or_create_sub_element(ElementName::HeaderLength)?
322 .set_character_data(0)?;
323 buffer_props
325 .get_or_create_sub_element(ElementName::InPlace)?
326 .set_character_data("false")?;
327
328 if version <= AutosarVersion::Autosar_00049 {
329 let _ = buffer_props.remove_sub_element_kind(ElementName::BufferComputation);
330 let bufcomp_compu = buffer_props
332 .create_sub_element(ElementName::BufferComputation)?
333 .create_sub_element(ElementName::CompuRationalCoeffs)?;
334 let numerator = bufcomp_compu.create_sub_element(ElementName::CompuNumerator)?;
335 numerator
336 .create_sub_element(ElementName::V)?
337 .set_character_data(u64::from(com_config.isignal_ipdu_length))?;
338 numerator.create_sub_element(ElementName::V)?.set_character_data(1)?;
339 bufcomp_compu
340 .create_sub_element(ElementName::CompuDenominator)?
341 .create_sub_element(ElementName::V)?
342 .set_character_data(1)?;
343 }
344
345 let _ = ttech.remove_sub_element_kind(ElementName::TransformationDescriptions);
347 let _ = ttech.remove_sub_element_kind(ElementName::NeedsOriginalData);
349 }
350 TransformationTechnologyConfig::E2E(e2e_config) => {
351 ttech
352 .get_or_create_sub_element(ElementName::Protocol)?
353 .set_character_data("E2E")?;
354 ttech
355 .get_or_create_sub_element(ElementName::Version)?
356 .set_character_data("1.0.0")?;
357 ttech
358 .get_or_create_sub_element(ElementName::TransformerClass)?
359 .set_character_data(EnumItem::Safety)?;
360 if version >= AutosarVersion::Autosar_4_3_0 {
361 ttech
362 .get_or_create_sub_element(ElementName::HasInternalState)?
363 .set_character_data("true")?;
364 }
365 ttech
366 .get_or_create_sub_element(ElementName::NeedsOriginalData)?
367 .set_character_data("false")?;
368
369 let (profile_name, header_length) = match e2e_config.profile {
371 E2EProfile::P01 => ("PROFILE_01", 16),
372 E2EProfile::P02 => ("PROFILE_02", 16),
373 E2EProfile::P04 => ("PROFILE_04", 96),
374 E2EProfile::P04m => ("PROFILE_04m", 128),
375 E2EProfile::P05 => ("PROFILE_05", 24),
376 E2EProfile::P06 => ("PROFILE_06", 40),
377 E2EProfile::P07 => ("PROFILE_07", 160),
378 E2EProfile::P07m => ("PROFILE_07m", 192),
379 E2EProfile::P08 => ("PROFILE_08", 128),
380 E2EProfile::P08m => ("PROFILE_08m", 160),
381 E2EProfile::P11 => ("PROFILE_11", 16),
382 E2EProfile::P22 => ("PROFILE_22", 16),
383 E2EProfile::P44 => ("PROFILE_44", 96),
384 E2EProfile::P44m => ("PROFILE_44m", 128),
385 };
386
387 let real_header_length = if e2e_config.zero_header_length {
390 0u32
391 } else {
392 header_length
393 };
394
395 buffer_props
396 .get_or_create_sub_element(ElementName::HeaderLength)?
397 .set_character_data(u64::from(real_header_length))?;
398 buffer_props
399 .get_or_create_sub_element(ElementName::InPlace)?
400 .set_character_data(e2e_config.transform_in_place)?;
401
402 let trans_desc = ttech.get_or_create_sub_element(ElementName::TransformationDescriptions)?;
403 let _ = trans_desc.remove_sub_element_kind(ElementName::SomeipTransformationDescription);
404 let e2e_desc = trans_desc.get_or_create_sub_element(ElementName::EndToEndTransformationDescription)?;
405
406 e2e_desc
408 .get_or_create_sub_element(ElementName::ProfileName)?
409 .set_character_data(profile_name)?;
410 e2e_desc
411 .get_or_create_sub_element(ElementName::UpperHeaderBitsToShift)?
412 .set_character_data(u64::from(e2e_config.offset))?;
413 e2e_desc
414 .get_or_create_sub_element(ElementName::MaxDeltaCounter)?
415 .set_character_data(u64::from(e2e_config.max_delta_counter))?;
416 e2e_desc
417 .get_or_create_sub_element(ElementName::MaxErrorStateInit)?
418 .set_character_data(u64::from(e2e_config.max_error_state_init))?;
419 e2e_desc
420 .get_or_create_sub_element(ElementName::MaxErrorStateInvalid)?
421 .set_character_data(u64::from(e2e_config.max_error_state_invalid))?;
422 e2e_desc
423 .get_or_create_sub_element(ElementName::MaxErrorStateValid)?
424 .set_character_data(u64::from(e2e_config.max_error_state_valid))?;
425 e2e_desc
426 .get_or_create_sub_element(ElementName::MaxNoNewOrRepeatedData)?
427 .set_character_data(u64::from(e2e_config.max_no_new_or_repeated_data))?;
428 e2e_desc
429 .get_or_create_sub_element(ElementName::MinOkStateInit)?
430 .set_character_data(u64::from(e2e_config.min_ok_state_init))?;
431 e2e_desc
432 .get_or_create_sub_element(ElementName::MinOkStateInvalid)?
433 .set_character_data(u64::from(e2e_config.min_ok_state_invalid))?;
434 e2e_desc
435 .get_or_create_sub_element(ElementName::MinOkStateValid)?
436 .set_character_data(u64::from(e2e_config.min_ok_state_valid))?;
437
438 if version <= AutosarVersion::Autosar_00047 {
440 e2e_desc
442 .get_or_create_sub_element(ElementName::WindowSize)?
443 .set_character_data(u64::from(e2e_config.window_size))?;
444 } else {
445 e2e_desc
447 .get_or_create_sub_element(ElementName::WindowSizeInit)?
448 .set_character_data(u64::from(e2e_config.window_size_init.unwrap_or(e2e_config.window_size)))?;
449 e2e_desc
450 .get_or_create_sub_element(ElementName::WindowSizeInvalid)?
451 .set_character_data(u64::from(
452 e2e_config.window_size_invalid.unwrap_or(e2e_config.window_size),
453 ))?;
454 e2e_desc
455 .get_or_create_sub_element(ElementName::WindowSizeValid)?
456 .set_character_data(u64::from(
457 e2e_config.window_size_valid.unwrap_or(e2e_config.window_size),
458 ))?;
459 }
460
461 if matches!(e2e_config.profile, E2EProfile::P01 | E2EProfile::P11) {
463 let Some(data_id_mode) = e2e_config.data_id_mode else {
465 return Err(AutosarAbstractionError::InvalidParameter(
466 "Data ID mode is required for E2E profiles 01 and 11".to_string(),
467 ));
468 };
469 e2e_desc
470 .get_or_create_sub_element(ElementName::DataIdMode)?
471 .set_character_data::<EnumItem>(data_id_mode.into())?;
472
473 let Some(counter_offset) = e2e_config.counter_offset else {
475 return Err(AutosarAbstractionError::InvalidParameter(
476 "Counter offset is required for E2E profiles 01 and 11".to_string(),
477 ));
478 };
479 e2e_desc
480 .get_or_create_sub_element(ElementName::CounterOffset)?
481 .set_character_data(u64::from(counter_offset))?;
482
483 let Some(crc_offset) = e2e_config.crc_offset else {
485 return Err(AutosarAbstractionError::InvalidParameter(
486 "CRC offset is required for E2E profiles 01 and 11".to_string(),
487 ));
488 };
489 e2e_desc
490 .get_or_create_sub_element(ElementName::CrcOffset)?
491 .set_character_data(u64::from(crc_offset))?;
492
493 if data_id_mode == DataIdMode::Lower12Bit {
495 let Some(data_id_nibble_offset) = e2e_config.data_id_nibble_offset else {
496 return Err(AutosarAbstractionError::InvalidParameter(
497 "Data ID nibble offset is required for E2E profiles 01 and 11 with DataIdMode::Lower12Bit".to_string(),
498 ));
499 };
500 e2e_desc
501 .get_or_create_sub_element(ElementName::DataIdNibbleOffset)?
502 .set_character_data(u64::from(data_id_nibble_offset))?;
503 }
504
505 let _ = e2e_desc.remove_sub_element_kind(ElementName::Offset);
507 } else {
508 e2e_desc
510 .get_or_create_sub_element(ElementName::Offset)?
511 .set_character_data(u64::from(e2e_config.offset))?;
512
513 let _ = e2e_desc.remove_sub_element_kind(ElementName::DataIdMode);
515 let _ = e2e_desc.remove_sub_element_kind(ElementName::CounterOffset);
516 let _ = e2e_desc.remove_sub_element_kind(ElementName::CrcOffset);
517 let _ = e2e_desc.remove_sub_element_kind(ElementName::DataIdNibbleOffset);
518 }
519
520 if let Some(profile_behavior) = e2e_config.profile_behavior {
523 e2e_desc
524 .get_or_create_sub_element(ElementName::ProfileBehavior)?
525 .set_character_data::<EnumItem>(profile_behavior.into())?;
526 }
527
528 if let Some(sync_counter_init) = e2e_config.sync_counter_init {
530 e2e_desc
531 .get_or_create_sub_element(ElementName::SyncCounterInit)?
532 .set_character_data(u64::from(sync_counter_init))?;
533 }
534
535 let _ = buffer_props.remove_sub_element_kind(ElementName::BufferComputation);
537 }
538 TransformationTechnologyConfig::SomeIp(someip_config) => {
539 ttech
540 .get_or_create_sub_element(ElementName::Protocol)?
541 .set_character_data("SOMEIP")?;
542 ttech
543 .get_or_create_sub_element(ElementName::TransformerClass)?
544 .set_character_data(EnumItem::Serializer)?;
545
546 buffer_props
548 .get_or_create_sub_element(ElementName::HeaderLength)?
549 .set_character_data(64)?;
550 buffer_props
552 .get_or_create_sub_element(ElementName::InPlace)?
553 .set_character_data("false")?;
554
555 let trans_desc = ttech.get_or_create_sub_element(ElementName::TransformationDescriptions)?;
556 let _ = trans_desc.remove_sub_element_kind(ElementName::EndToEndTransformationDescription);
557 let someip_desc = trans_desc.get_or_create_sub_element(ElementName::SomeipTransformationDescription)?;
558 someip_desc
559 .get_or_create_sub_element(ElementName::Alignment)?
560 .set_character_data(u64::from(someip_config.alignment))?;
561 someip_desc
562 .get_or_create_sub_element(ElementName::ByteOrder)?
563 .set_character_data::<EnumItem>(someip_config.byte_order.into())?;
564 someip_desc
565 .get_or_create_sub_element(ElementName::InterfaceVersion)?
566 .set_character_data(u64::from(someip_config.interface_version))?;
567
568 ttech
570 .get_or_create_sub_element(ElementName::Version)?
571 .set_character_data("1.0.0")?;
572
573 let _ = buffer_props.remove_sub_element_kind(ElementName::BufferComputation);
575 let _ = ttech.remove_sub_element_kind(ElementName::NeedsOriginalData);
577 }
578 }
579
580 Ok(())
581 }
582
583 #[must_use]
585 pub fn protocol(&self) -> Option<String> {
586 self.element()
587 .get_sub_element(ElementName::Protocol)?
588 .character_data()?
589 .string_value()
590 }
591
592 #[must_use]
594 pub fn transformer_class(&self) -> Option<EnumItem> {
595 self.element()
596 .get_sub_element(ElementName::TransformerClass)?
597 .character_data()?
598 .enum_value()
599 }
600
601 #[must_use]
603 pub fn data_transformation_set(&self) -> Option<DataTransformationSet> {
604 self.element()
605 .named_parent()
606 .ok()?
607 .and_then(|dts| DataTransformationSet::try_from(dts).ok())
608 }
609
610 #[must_use]
612 pub fn config(&self) -> Option<TransformationTechnologyConfig> {
613 let protocol = self
614 .element()
615 .get_sub_element(ElementName::Protocol)?
616 .character_data()?
617 .string_value()?;
618
619 let opt_e2e_desc = self
620 .element()
621 .get_sub_element(ElementName::TransformationDescriptions)
622 .and_then(|tdesc| tdesc.get_sub_element(ElementName::EndToEndTransformationDescription));
623 let opt_someip_desc = self
624 .element()
625 .get_sub_element(ElementName::TransformationDescriptions)
626 .and_then(|tdesc| tdesc.get_sub_element(ElementName::SomeipTransformationDescription));
627
628 if let Some(e2e_desc) = opt_e2e_desc {
629 let profile_name = e2e_desc
631 .get_sub_element(ElementName::ProfileName)?
632 .character_data()?
633 .string_value()?;
634 let profile = match profile_name.as_str() {
635 "PROFILE_01" => E2EProfile::P01,
636 "PROFILE_02" => E2EProfile::P02,
637 "PROFILE_04" => E2EProfile::P04,
638 "PROFILE_04m" => E2EProfile::P04m,
639 "PROFILE_05" => E2EProfile::P05,
640 "PROFILE_06" => E2EProfile::P06,
641 "PROFILE_07" => E2EProfile::P07,
642 "PROFILE_07m" => E2EProfile::P07m,
643 "PROFILE_08" => E2EProfile::P08,
644 "PROFILE_08m" => E2EProfile::P08m,
645 "PROFILE_11" => E2EProfile::P11,
646 "PROFILE_22" => E2EProfile::P22,
647 "PROFILE_44" => E2EProfile::P44,
648 "PROFILE_44m" => E2EProfile::P44m,
649 _ => return None,
650 };
651
652 let buffer_props = self.element().get_sub_element(ElementName::BufferProperties)?;
653 let in_place = buffer_props
654 .get_sub_element(ElementName::InPlace)?
655 .character_data()?
656 .parse_bool()?;
657 let buffer_header_length = buffer_props
658 .get_sub_element(ElementName::HeaderLength)?
659 .character_data()?
660 .parse_integer::<u32>()?;
661
662 let opt_window_size_init = e2e_desc
663 .get_sub_element(ElementName::WindowSizeInit)
664 .and_then(|elem| elem.character_data())
665 .and_then(|cdata| cdata.parse_integer::<u32>());
666 let opt_window_size_invalid = e2e_desc
667 .get_sub_element(ElementName::WindowSizeInvalid)
668 .and_then(|elem| elem.character_data())
669 .and_then(|cdata| cdata.parse_integer::<u32>());
670 let opt_window_size_valid = e2e_desc
671 .get_sub_element(ElementName::WindowSizeValid)
672 .and_then(|elem| elem.character_data())
673 .and_then(|cdata| cdata.parse_integer::<u32>());
674 let opt_window_size = e2e_desc
677 .get_sub_element(ElementName::WindowSize)
678 .and_then(|elem| elem.character_data())
679 .and_then(|cdata| cdata.parse_integer())
680 .or(opt_window_size_init)
681 .or(opt_window_size_invalid)
682 .or(opt_window_size_valid);
683
684 let config = E2ETransformationTechnologyConfig {
685 profile,
686 zero_header_length: buffer_header_length == 0,
687 transform_in_place: in_place,
688 offset: 0,
689 max_delta_counter: e2e_desc
690 .get_sub_element(ElementName::MaxDeltaCounter)?
691 .character_data()?
692 .parse_integer()?,
693 max_error_state_init: e2e_desc
694 .get_sub_element(ElementName::MaxErrorStateInit)?
695 .character_data()?
696 .parse_integer()?,
697 max_error_state_invalid: e2e_desc
698 .get_sub_element(ElementName::MaxErrorStateInvalid)?
699 .character_data()?
700 .parse_integer()?,
701 max_error_state_valid: e2e_desc
702 .get_sub_element(ElementName::MaxErrorStateValid)?
703 .character_data()?
704 .parse_integer()?,
705 max_no_new_or_repeated_data: e2e_desc
706 .get_sub_element(ElementName::MaxNoNewOrRepeatedData)?
707 .character_data()?
708 .parse_integer()?,
709 min_ok_state_init: e2e_desc
710 .get_sub_element(ElementName::MinOkStateInit)?
711 .character_data()?
712 .parse_integer()?,
713 min_ok_state_invalid: e2e_desc
714 .get_sub_element(ElementName::MinOkStateInvalid)?
715 .character_data()?
716 .parse_integer()?,
717 min_ok_state_valid: e2e_desc
718 .get_sub_element(ElementName::MinOkStateValid)?
719 .character_data()?
720 .parse_integer()?,
721 window_size: opt_window_size?,
722 window_size_init: e2e_desc
723 .get_sub_element(ElementName::WindowSizeInit)
724 .and_then(|elem| elem.character_data())
725 .and_then(|cd| cd.parse_integer()),
726 window_size_invalid: e2e_desc
727 .get_sub_element(ElementName::WindowSizeInvalid)
728 .and_then(|elem| elem.character_data())
729 .and_then(|cd| cd.parse_integer()),
730 window_size_valid: e2e_desc
731 .get_sub_element(ElementName::WindowSizeValid)
732 .and_then(|elem| elem.character_data())
733 .and_then(|cd| cd.parse_integer()),
734 profile_behavior: e2e_desc
735 .get_sub_element(ElementName::ProfileBehavior)
736 .and_then(|elem| elem.character_data())
737 .and_then(|cd| cd.enum_value())
738 .and_then(|enumitem| enumitem.try_into().ok()),
739 sync_counter_init: e2e_desc
740 .get_sub_element(ElementName::SyncCounterInit)
741 .and_then(|elem| elem.character_data())
742 .and_then(|cd| cd.parse_integer()),
743 data_id_mode: e2e_desc
744 .get_sub_element(ElementName::DataIdMode)
745 .and_then(|elem| elem.character_data())
746 .and_then(|cd| cd.enum_value())
747 .and_then(|enumitem| enumitem.try_into().ok()),
748 data_id_nibble_offset: e2e_desc
749 .get_sub_element(ElementName::DataIdNibbleOffset)
750 .and_then(|elem| elem.character_data())
751 .and_then(|cd| cd.parse_integer()),
752 crc_offset: e2e_desc
753 .get_sub_element(ElementName::CrcOffset)
754 .and_then(|elem| elem.character_data())
755 .and_then(|cd| cd.parse_integer()),
756 counter_offset: e2e_desc
757 .get_sub_element(ElementName::CounterOffset)
758 .and_then(|elem| elem.character_data())
759 .and_then(|cd| cd.parse_integer()),
760 };
761
762 Some(TransformationTechnologyConfig::E2E(config))
763 } else if let Some(someip_desc) = opt_someip_desc {
764 let someip_config = SomeIpTransformationTechnologyConfig {
766 alignment: someip_desc
767 .get_sub_element(ElementName::Alignment)?
768 .character_data()?
769 .parse_integer()?,
770 byte_order: someip_desc
771 .get_sub_element(ElementName::ByteOrder)?
772 .character_data()?
773 .enum_value()
774 .and_then(|enumitem| enumitem.try_into().ok())?,
775 interface_version: someip_desc
776 .get_sub_element(ElementName::InterfaceVersion)?
777 .character_data()?
778 .parse_integer()?,
779 };
780 Some(TransformationTechnologyConfig::SomeIp(someip_config))
781 } else if protocol == "COMBased" || protocol == "ComBased" {
782 let com_config = ComTransformationTechnologyConfig {
784 isignal_ipdu_length: self
785 .element()
786 .get_sub_element(ElementName::BufferProperties)?
787 .get_sub_element(ElementName::BufferComputation)?
788 .get_sub_element(ElementName::CompuRationalCoeffs)?
789 .get_sub_element(ElementName::CompuNumerator)?
790 .get_sub_element(ElementName::V)?
791 .character_data()?
792 .parse_integer()?,
793 };
794 Some(TransformationTechnologyConfig::Com(com_config))
795 } else {
796 let buffer_props = self.element().get_sub_element(ElementName::BufferProperties)?;
798 let in_place = buffer_props
799 .get_sub_element(ElementName::InPlace)?
800 .character_data()?
801 .parse_bool()?;
802
803 let generic_config = GenericTransformationTechnologyConfig {
804 protocol_name: self
805 .element()
806 .get_sub_element(ElementName::Protocol)?
807 .character_data()?
808 .string_value()?,
809 protocol_version: self
810 .element()
811 .get_sub_element(ElementName::Version)?
812 .character_data()?
813 .string_value()?,
814 header_length: buffer_props
815 .get_sub_element(ElementName::HeaderLength)?
816 .character_data()?
817 .parse_integer()?,
818 in_place,
819 };
820 Some(TransformationTechnologyConfig::Generic(generic_config))
821 }
822 }
823}
824
825#[derive(Debug, Clone, PartialEq, Eq)]
829pub enum TransformationTechnologyConfig {
830 Generic(GenericTransformationTechnologyConfig),
832 Com(ComTransformationTechnologyConfig),
834 E2E(E2ETransformationTechnologyConfig),
836 SomeIp(SomeIpTransformationTechnologyConfig),
838}
839
840#[derive(Debug, Clone, PartialEq, Eq)]
845pub struct GenericTransformationTechnologyConfig {
846 pub protocol_name: String,
848 pub protocol_version: String,
850 pub header_length: u32,
852 pub in_place: bool,
854}
855
856#[derive(Debug, Clone, PartialEq, Eq)]
860pub struct ComTransformationTechnologyConfig {
861 pub isignal_ipdu_length: u32,
864}
865
866#[derive(Debug, Clone, PartialEq, Eq)]
870pub struct E2ETransformationTechnologyConfig {
871 pub profile: E2EProfile,
873 pub zero_header_length: bool,
877 pub transform_in_place: bool,
879 pub offset: u32,
882 pub max_delta_counter: u32,
884 pub max_error_state_init: u32,
886 pub max_error_state_invalid: u32,
888 pub max_error_state_valid: u32,
890 pub max_no_new_or_repeated_data: u32,
892 pub min_ok_state_init: u32,
894 pub min_ok_state_invalid: u32,
896 pub min_ok_state_valid: u32,
898 pub window_size: u32,
902 pub window_size_init: Option<u32>,
904 pub window_size_invalid: Option<u32>,
906 pub window_size_valid: Option<u32>,
908 pub profile_behavior: Option<E2EProfileBehavior>,
910 pub sync_counter_init: Option<u32>,
912 pub data_id_mode: Option<DataIdMode>,
914 pub data_id_nibble_offset: Option<u32>,
916 pub crc_offset: Option<u32>,
918 pub counter_offset: Option<u32>,
920}
921
922#[derive(Debug, Clone, PartialEq, Eq)]
926pub struct SomeIpTransformationTechnologyConfig {
927 pub alignment: u32,
929 pub byte_order: ByteOrder,
931 pub interface_version: u32,
933}
934
935#[derive(Debug, Clone, Copy, PartialEq, Eq)]
939pub enum E2EProfile {
940 P01,
942 P02,
944 P04,
946 P04m,
948 P05,
950 P06,
952 P07,
954 P07m,
956 P08,
958 P08m,
960 P11,
962 P22,
964 P44,
966 P44m,
968}
969
970#[derive(Debug, Clone, Copy, PartialEq, Eq)]
974pub enum E2EProfileBehavior {
975 PreR4_2,
977 R4_2,
979}
980
981impl From<E2EProfileBehavior> for EnumItem {
982 fn from(e2e_profile_behavior: E2EProfileBehavior) -> EnumItem {
983 match e2e_profile_behavior {
984 E2EProfileBehavior::PreR4_2 => EnumItem::PreR4_2,
985 E2EProfileBehavior::R4_2 => EnumItem::R4_2,
986 }
987 }
988}
989
990impl TryFrom<EnumItem> for E2EProfileBehavior {
991 type Error = AutosarAbstractionError;
992
993 fn try_from(value: EnumItem) -> Result<E2EProfileBehavior, AutosarAbstractionError> {
994 match value {
995 EnumItem::PreR4_2 => Ok(E2EProfileBehavior::PreR4_2),
996 EnumItem::R4_2 => Ok(E2EProfileBehavior::R4_2),
997 _ => Err(AutosarAbstractionError::ValueConversionError {
998 value: value.to_string(),
999 dest: "E2EProfileBehavior".to_string(),
1000 }),
1001 }
1002 }
1003}
1004
1005#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1009pub enum DataIdMode {
1010 All16Bit,
1012 Alternating8Bit,
1014 Lower12Bit,
1016 Lower8Bit,
1018}
1019
1020impl From<DataIdMode> for EnumItem {
1021 fn from(data_id_mode: DataIdMode) -> EnumItem {
1022 match data_id_mode {
1023 DataIdMode::All16Bit => EnumItem::All16Bit,
1024 DataIdMode::Alternating8Bit => EnumItem::Alternating8Bit,
1025 DataIdMode::Lower12Bit => EnumItem::Lower12Bit,
1026 DataIdMode::Lower8Bit => EnumItem::Lower8Bit,
1027 }
1028 }
1029}
1030
1031impl TryFrom<EnumItem> for DataIdMode {
1032 type Error = AutosarAbstractionError;
1033
1034 fn try_from(value: EnumItem) -> Result<DataIdMode, AutosarAbstractionError> {
1035 match value {
1036 EnumItem::All16Bit => Ok(DataIdMode::All16Bit),
1037 EnumItem::Alternating8Bit => Ok(DataIdMode::Alternating8Bit),
1038 EnumItem::Lower12Bit => Ok(DataIdMode::Lower12Bit),
1039 EnumItem::Lower8Bit => Ok(DataIdMode::Lower8Bit),
1040 _ => Err(AutosarAbstractionError::ValueConversionError {
1041 value: value.to_string(),
1042 dest: "DataIdMode".to_string(),
1043 }),
1044 }
1045 }
1046}
1047
1048#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1052pub enum SomeIpMessageType {
1053 Notification,
1055 Request,
1057 RequestNoReturn,
1059 Response,
1061}
1062
1063impl From<SomeIpMessageType> for EnumItem {
1064 fn from(someip_msg_type: SomeIpMessageType) -> EnumItem {
1065 match someip_msg_type {
1066 SomeIpMessageType::Notification => EnumItem::Notification,
1067 SomeIpMessageType::Request => EnumItem::Request,
1068 SomeIpMessageType::RequestNoReturn => EnumItem::RequestNoReturn,
1069 SomeIpMessageType::Response => EnumItem::Response,
1070 }
1071 }
1072}
1073
1074impl TryFrom<EnumItem> for SomeIpMessageType {
1075 type Error = AutosarAbstractionError;
1076
1077 fn try_from(value: EnumItem) -> Result<SomeIpMessageType, AutosarAbstractionError> {
1078 match value {
1079 EnumItem::Notification => Ok(SomeIpMessageType::Notification),
1080 EnumItem::Request => Ok(SomeIpMessageType::Request),
1081 EnumItem::RequestNoReturn => Ok(SomeIpMessageType::RequestNoReturn),
1082 EnumItem::Response => Ok(SomeIpMessageType::Response),
1083 _ => Err(AutosarAbstractionError::ValueConversionError {
1084 value: value.to_string(),
1085 dest: "SomeIpMessageType".to_string(),
1086 }),
1087 }
1088 }
1089}
1090
1091#[derive(Debug, Clone, PartialEq, Eq)]
1095pub struct EndToEndTransformationISignalProps(Element);
1096abstraction_element!(EndToEndTransformationISignalProps, EndToEndTransformationISignalProps);
1097
1098impl EndToEndTransformationISignalProps {
1099 pub(crate) fn new(
1100 parent_element: Element,
1101 transformer: &TransformationTechnology,
1102 ) -> Result<Self, AutosarAbstractionError> {
1103 if transformer.protocol().as_deref() != Some("E2E") {
1104 return Err(AutosarAbstractionError::InvalidParameter(
1105 "EndToEndTransformationISignalProps must reference a E2E transformer".to_string(),
1106 ));
1107 }
1108 let e2e_props_elem = parent_element.create_sub_element(ElementName::EndToEndTransformationISignalProps)?;
1109
1110 let e2e_props = Self(e2e_props_elem);
1111 e2e_props.set_transformer(transformer)?;
1112
1113 Ok(e2e_props)
1114 }
1115
1116 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
1118 let opt_transformer = self.transformer();
1119
1120 AbstractionElement::remove(self, deep)?;
1121
1122 if deep
1123 && let Some(transformer) = opt_transformer
1124 && !is_used(transformer.element())
1125 {
1126 transformer.remove(true)?;
1127 }
1128
1129 Ok(())
1130 }
1131
1132 fn inner_element(&self) -> Option<Element> {
1133 self.0
1134 .get_sub_element(ElementName::EndToEndTransformationISignalPropsVariants)?
1135 .get_sub_element(ElementName::EndToEndTransformationISignalPropsConditional)
1136 }
1137
1138 fn create_inner_element(&self) -> Result<Element, AutosarAbstractionError> {
1139 let e2e_props_elem = self
1140 .element()
1141 .get_or_create_sub_element(ElementName::EndToEndTransformationISignalPropsVariants)?
1142 .get_or_create_sub_element(ElementName::EndToEndTransformationISignalPropsConditional)?;
1143 Ok(e2e_props_elem)
1144 }
1145
1146 pub fn set_transformer(&self, transformer: &TransformationTechnology) -> Result<(), AutosarAbstractionError> {
1148 if transformer.protocol().as_deref() != Some("E2E") {
1149 return Err(AutosarAbstractionError::InvalidParameter(
1150 "EndToEndTransformationISignalProps must reference a E2E transformer".to_string(),
1151 ));
1152 }
1153 self.create_inner_element()?
1154 .get_or_create_sub_element(ElementName::TransformerRef)?
1155 .set_reference_target(transformer.element())?;
1156 Ok(())
1157 }
1158
1159 #[must_use]
1161 pub fn transformer(&self) -> Option<TransformationTechnology> {
1162 let t_elem = self
1163 .inner_element()?
1164 .get_sub_element(ElementName::TransformerRef)?
1165 .get_reference_target()
1166 .ok()?;
1167 TransformationTechnology::try_from(t_elem).ok()
1168 }
1169
1170 pub fn set_data_ids(&self, data_ids: &[u32]) -> Result<(), AutosarAbstractionError> {
1172 if data_ids.is_empty() {
1173 let _ = self
1174 .inner_element()
1175 .and_then(|inner| inner.remove_sub_element_kind(ElementName::DataIds).ok());
1176 } else {
1177 let data_ids_elem = self.create_inner_element()?.create_sub_element(ElementName::DataIds)?;
1178 for data_id in data_ids {
1179 data_ids_elem
1180 .create_sub_element(ElementName::DataId)?
1181 .set_character_data(u64::from(*data_id))?;
1182 }
1183 }
1184 Ok(())
1185 }
1186
1187 #[must_use]
1189 pub fn data_ids(&self) -> Vec<u32> {
1190 self.inner_element()
1191 .and_then(|inner_elem| inner_elem.get_sub_element(ElementName::DataIds))
1192 .map(|elem| {
1193 elem.sub_elements()
1194 .filter_map(|elem| elem.character_data().and_then(|cdata| cdata.parse_integer()))
1195 .collect()
1196 })
1197 .unwrap_or_default()
1198 }
1199
1200 pub fn set_data_length(&self, data_length: Option<u32>) -> Result<(), AutosarAbstractionError> {
1202 if let Some(data_length) = data_length {
1203 self.create_inner_element()?
1204 .get_or_create_sub_element(ElementName::DataLength)?
1205 .set_character_data(data_length.to_string())?;
1206 } else {
1207 let _ = self
1208 .inner_element()
1209 .and_then(|inner| inner.remove_sub_element_kind(ElementName::DataLength).ok());
1210 }
1211 Ok(())
1212 }
1213
1214 #[must_use]
1216 pub fn data_length(&self) -> Option<u32> {
1217 self.inner_element()?
1218 .get_sub_element(ElementName::DataLength)?
1219 .character_data()?
1220 .parse_integer()
1221 }
1222
1223 pub fn set_max_data_length(&self, max_data_length: Option<u32>) -> Result<(), AutosarAbstractionError> {
1225 if let Some(max_data_length) = max_data_length {
1226 self.create_inner_element()?
1227 .get_or_create_sub_element(ElementName::MaxDataLength)?
1228 .set_character_data(max_data_length.to_string())?;
1229 } else {
1230 let _ = self
1231 .inner_element()
1232 .and_then(|inner| inner.remove_sub_element_kind(ElementName::MaxDataLength).ok());
1233 }
1234 Ok(())
1235 }
1236
1237 #[must_use]
1239 pub fn max_data_length(&self) -> Option<u32> {
1240 self.inner_element()?
1241 .get_sub_element(ElementName::MaxDataLength)
1242 .and_then(|elem| elem.character_data())
1243 .and_then(|cdata| cdata.parse_integer())
1244 }
1245
1246 pub fn set_min_data_length(&self, min_data_length: Option<u32>) -> Result<(), AutosarAbstractionError> {
1248 if let Some(min_data_length) = min_data_length {
1249 self.create_inner_element()?
1250 .get_or_create_sub_element(ElementName::MinDataLength)?
1251 .set_character_data(min_data_length.to_string())?;
1252 } else {
1253 let _ = self
1254 .inner_element()
1255 .and_then(|inner| inner.remove_sub_element_kind(ElementName::MinDataLength).ok());
1256 }
1257 Ok(())
1258 }
1259
1260 #[must_use]
1262 pub fn min_data_length(&self) -> Option<u32> {
1263 self.inner_element()?
1264 .get_sub_element(ElementName::MinDataLength)?
1265 .character_data()?
1266 .parse_integer()
1267 }
1268
1269 pub fn set_source_id(&self, source_id: Option<u32>) -> Result<(), AutosarAbstractionError> {
1271 if let Some(source_id) = source_id {
1272 self.create_inner_element()?
1273 .get_or_create_sub_element(ElementName::SourceId)?
1274 .set_character_data(source_id.to_string())?;
1275 } else {
1276 let _ = self
1277 .inner_element()
1278 .and_then(|inner| inner.remove_sub_element_kind(ElementName::SourceId).ok());
1279 }
1280 Ok(())
1281 }
1282
1283 #[must_use]
1285 pub fn source_id(&self) -> Option<u32> {
1286 self.inner_element()?
1287 .get_sub_element(ElementName::SourceId)?
1288 .character_data()?
1289 .parse_integer()
1290 }
1291}
1292
1293#[derive(Debug, Clone, PartialEq, Eq)]
1297pub struct SomeIpTransformationISignalProps(Element);
1298abstraction_element!(SomeIpTransformationISignalProps, SomeipTransformationISignalProps);
1299
1300impl SomeIpTransformationISignalProps {
1301 pub(crate) fn new(
1302 parent_element: Element,
1303 transformer: &TransformationTechnology,
1304 ) -> Result<Self, AutosarAbstractionError> {
1305 if transformer.protocol().as_deref() != Some("SOMEIP") {
1306 return Err(AutosarAbstractionError::InvalidParameter(
1307 "SOMEIPTransformationISignalProps must reference a SOMEIP transformer".to_string(),
1308 ));
1309 }
1310 let someip_props_elem = parent_element.create_sub_element(ElementName::SomeipTransformationISignalProps)?;
1311 let someip_props = Self(someip_props_elem);
1312 someip_props.set_transformer(transformer)?;
1313
1314 Ok(someip_props)
1315 }
1316
1317 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
1319 let opt_transformer = self.transformer();
1320
1321 AbstractionElement::remove(self, deep)?;
1322
1323 if deep
1324 && let Some(transformer) = opt_transformer
1325 && !is_used(transformer.element())
1326 {
1327 transformer.remove(true)?;
1328 }
1329
1330 Ok(())
1331 }
1332
1333 fn inner_element(&self) -> Option<Element> {
1334 self.0
1335 .get_sub_element(ElementName::SomeipTransformationISignalPropsVariants)?
1336 .get_sub_element(ElementName::SomeipTransformationISignalPropsConditional)
1337 }
1338
1339 fn create_inner_element(&self) -> Result<Element, AutosarAbstractionError> {
1340 let e2e_props_elem = self
1341 .element()
1342 .get_or_create_sub_element(ElementName::SomeipTransformationISignalPropsVariants)?
1343 .get_or_create_sub_element(ElementName::SomeipTransformationISignalPropsConditional)?;
1344 Ok(e2e_props_elem)
1345 }
1346
1347 pub fn set_transformer(&self, transformer: &TransformationTechnology) -> Result<(), AutosarAbstractionError> {
1349 if transformer.protocol().as_deref() != Some("SOMEIP") {
1350 return Err(AutosarAbstractionError::InvalidParameter(
1351 "SOMEIPTransformationISignalProps must reference a SOMEIP transformer".to_string(),
1352 ));
1353 }
1354 self.create_inner_element()?
1355 .get_or_create_sub_element(ElementName::TransformerRef)?
1356 .set_reference_target(transformer.element())?;
1357 Ok(())
1358 }
1359
1360 #[must_use]
1362 pub fn transformer(&self) -> Option<TransformationTechnology> {
1363 let t_elem = self
1364 .inner_element()?
1365 .get_sub_element(ElementName::TransformerRef)?
1366 .get_reference_target()
1367 .ok()?;
1368 TransformationTechnology::try_from(t_elem).ok()
1369 }
1370
1371 pub fn set_legacy_strings(&self, legacy_strings: Option<bool>) -> Result<(), AutosarAbstractionError> {
1373 if let Some(legacy_strings) = legacy_strings {
1374 self.create_inner_element()?
1375 .get_or_create_sub_element(ElementName::ImplementsLegacyStringSerialization)?
1376 .set_character_data(legacy_strings.to_string())?;
1377 } else {
1378 let _ = self.inner_element().and_then(|inner| {
1379 inner
1380 .remove_sub_element_kind(ElementName::ImplementsLegacyStringSerialization)
1381 .ok()
1382 });
1383 }
1384 Ok(())
1385 }
1386
1387 #[must_use]
1389 pub fn legacy_strings(&self) -> Option<bool> {
1390 self.inner_element()?
1391 .get_sub_element(ElementName::ImplementsLegacyStringSerialization)?
1392 .character_data()?
1393 .parse_bool()
1394 }
1395
1396 pub fn set_interface_version(&self, interface_version: Option<u32>) -> Result<(), AutosarAbstractionError> {
1398 if let Some(interface_version) = interface_version {
1399 self.create_inner_element()?
1400 .get_or_create_sub_element(ElementName::InterfaceVersion)?
1401 .set_character_data(interface_version.to_string())?;
1402 } else {
1403 let _ = self
1404 .inner_element()
1405 .and_then(|inner| inner.remove_sub_element_kind(ElementName::InterfaceVersion).ok());
1406 }
1407 Ok(())
1408 }
1409
1410 #[must_use]
1412 pub fn interface_version(&self) -> Option<u32> {
1413 self.inner_element()?
1414 .get_sub_element(ElementName::InterfaceVersion)?
1415 .character_data()?
1416 .parse_integer()
1417 }
1418
1419 pub fn set_dynamic_length(&self, dynamic_length: Option<bool>) -> Result<(), AutosarAbstractionError> {
1421 if let Some(dynamic_length) = dynamic_length {
1422 self.create_inner_element()?
1423 .get_or_create_sub_element(ElementName::IsDynamicLengthFieldSize)?
1424 .set_character_data(dynamic_length.to_string())?;
1425 } else {
1426 let _ = self.inner_element().and_then(|inner| {
1427 inner
1428 .remove_sub_element_kind(ElementName::IsDynamicLengthFieldSize)
1429 .ok()
1430 });
1431 }
1432 Ok(())
1433 }
1434
1435 #[must_use]
1437 pub fn dynamic_length(&self) -> Option<bool> {
1438 self.inner_element()?
1439 .get_sub_element(ElementName::IsDynamicLengthFieldSize)?
1440 .character_data()?
1441 .parse_bool()
1442 }
1443
1444 pub fn set_message_type(&self, message_type: Option<SomeIpMessageType>) -> Result<(), AutosarAbstractionError> {
1446 if let Some(message_type) = message_type {
1447 self.create_inner_element()?
1448 .get_or_create_sub_element(ElementName::MessageType)?
1449 .set_character_data::<EnumItem>(message_type.into())?;
1450 } else {
1451 let _ = self
1452 .inner_element()
1453 .and_then(|inner| inner.remove_sub_element_kind(ElementName::MessageType).ok());
1454 }
1455 Ok(())
1456 }
1457
1458 #[must_use]
1460 pub fn message_type(&self) -> Option<SomeIpMessageType> {
1461 self.inner_element()?
1462 .get_sub_element(ElementName::MessageType)?
1463 .character_data()?
1464 .enum_value()?
1465 .try_into()
1466 .ok()
1467 }
1468
1469 pub fn set_size_of_array_length(&self, size_of_array_length: Option<u32>) -> Result<(), AutosarAbstractionError> {
1471 if let Some(size_of_array_length) = size_of_array_length {
1472 self.create_inner_element()?
1473 .get_or_create_sub_element(ElementName::SizeOfArrayLengthFields)?
1474 .set_character_data(size_of_array_length.to_string())?;
1475 } else {
1476 let _ = self
1477 .inner_element()
1478 .and_then(|inner| inner.remove_sub_element_kind(ElementName::SizeOfArrayLengthFields).ok());
1479 }
1480 Ok(())
1481 }
1482
1483 #[must_use]
1485 pub fn size_of_array_length(&self) -> Option<u32> {
1486 self.inner_element()?
1487 .get_sub_element(ElementName::SizeOfArrayLengthFields)?
1488 .character_data()?
1489 .parse_integer()
1490 }
1491
1492 pub fn set_size_of_string_length(&self, size_of_string_length: Option<u32>) -> Result<(), AutosarAbstractionError> {
1494 if let Some(size_of_string_length) = size_of_string_length {
1495 self.create_inner_element()?
1496 .get_or_create_sub_element(ElementName::SizeOfStringLengthFields)?
1497 .set_character_data(size_of_string_length.to_string())?;
1498 } else {
1499 let _ = self.inner_element().and_then(|inner| {
1500 inner
1501 .remove_sub_element_kind(ElementName::SizeOfStringLengthFields)
1502 .ok()
1503 });
1504 }
1505 Ok(())
1506 }
1507
1508 #[must_use]
1510 pub fn size_of_string_length(&self) -> Option<u32> {
1511 self.inner_element()?
1512 .get_sub_element(ElementName::SizeOfStringLengthFields)?
1513 .character_data()?
1514 .parse_integer()
1515 }
1516
1517 pub fn set_size_of_struct_length(&self, size_of_struct_length: Option<u32>) -> Result<(), AutosarAbstractionError> {
1519 if let Some(size_of_struct_length) = size_of_struct_length {
1520 self.create_inner_element()?
1521 .get_or_create_sub_element(ElementName::SizeOfStructLengthFields)?
1522 .set_character_data(size_of_struct_length.to_string())?;
1523 } else {
1524 let _ = self.inner_element().and_then(|inner| {
1525 inner
1526 .remove_sub_element_kind(ElementName::SizeOfStructLengthFields)
1527 .ok()
1528 });
1529 }
1530 Ok(())
1531 }
1532
1533 #[must_use]
1535 pub fn size_of_struct_length(&self) -> Option<u32> {
1536 self.inner_element()?
1537 .get_sub_element(ElementName::SizeOfStructLengthFields)?
1538 .character_data()?
1539 .parse_integer()
1540 }
1541
1542 pub fn set_size_of_union_length(&self, size_of_union_length: Option<u32>) -> Result<(), AutosarAbstractionError> {
1544 if let Some(size_of_union_length) = size_of_union_length {
1545 self.create_inner_element()?
1546 .get_or_create_sub_element(ElementName::SizeOfUnionLengthFields)?
1547 .set_character_data(size_of_union_length.to_string())?;
1548 } else {
1549 let _ = self
1550 .inner_element()
1551 .and_then(|inner| inner.remove_sub_element_kind(ElementName::SizeOfUnionLengthFields).ok());
1552 }
1553 Ok(())
1554 }
1555
1556 #[must_use]
1558 pub fn size_of_union_length(&self) -> Option<u32> {
1559 self.inner_element()?
1560 .get_sub_element(ElementName::SizeOfUnionLengthFields)?
1561 .character_data()?
1562 .parse_integer()
1563 }
1564}
1565
1566#[derive(Debug, Clone, PartialEq, Eq)]
1570pub enum TransformationISignalProps {
1571 E2E(EndToEndTransformationISignalProps),
1573 SomeIp(SomeIpTransformationISignalProps),
1575}
1576
1577impl AbstractionElement for TransformationISignalProps {
1578 fn element(&self) -> &Element {
1579 match self {
1580 TransformationISignalProps::E2E(e2e_props) => e2e_props.element(),
1581 TransformationISignalProps::SomeIp(someip_props) => someip_props.element(),
1582 }
1583 }
1584}
1585
1586impl TryFrom<Element> for TransformationISignalProps {
1587 type Error = AutosarAbstractionError;
1588
1589 fn try_from(element: Element) -> Result<Self, Self::Error> {
1590 match element.element_name() {
1591 ElementName::EndToEndTransformationISignalProps => {
1592 EndToEndTransformationISignalProps::try_from(element).map(TransformationISignalProps::E2E)
1593 }
1594 ElementName::SomeipTransformationISignalProps => {
1595 SomeIpTransformationISignalProps::try_from(element).map(TransformationISignalProps::SomeIp)
1596 }
1597 _ => Err(AutosarAbstractionError::ConversionError {
1598 element,
1599 dest: "TransformationISignalProps".to_string(),
1600 }),
1601 }
1602 }
1603}
1604
1605impl TransformationISignalProps {
1606 pub fn remove(self, deep: bool) -> Result<(), AutosarAbstractionError> {
1608 match self {
1609 TransformationISignalProps::E2E(e2e_props) => e2e_props.remove(deep),
1610 TransformationISignalProps::SomeIp(someip_props) => someip_props.remove(deep),
1611 }
1612 }
1613}
1614
1615#[cfg(test)]
1618mod test {
1619 use super::*;
1620 use crate::{
1621 AutosarModelAbstraction,
1622 communication::{ISignal, SystemSignal},
1623 datatype::{BaseTypeEncoding, SwBaseType},
1624 };
1625
1626 #[test]
1627 fn transformation_technologies() {
1628 let versions = vec![
1631 AutosarVersion::Autosar_4_2_1,
1632 AutosarVersion::Autosar_4_3_0,
1633 AutosarVersion::Autosar_00044,
1634 AutosarVersion::Autosar_00046,
1635 AutosarVersion::Autosar_00047,
1636 AutosarVersion::Autosar_00048,
1637 AutosarVersion::Autosar_00049,
1638 AutosarVersion::Autosar_00050,
1639 AutosarVersion::Autosar_00051,
1640 AutosarVersion::Autosar_00052,
1641 ];
1642 for version in versions {
1643 create_transformation_technologies(version);
1644 }
1645 }
1646
1647 fn create_transformation_technologies(file_version: AutosarVersion) {
1648 let model = AutosarModelAbstraction::create("test", file_version);
1649 let package = model.get_or_create_package("/package").unwrap();
1650 let dts = DataTransformationSet::new("test", &package).unwrap();
1651
1652 let config = TransformationTechnologyConfig::Generic(GenericTransformationTechnologyConfig {
1654 protocol_name: "test".to_string(),
1655 protocol_version: "1.0.0".to_string(),
1656 header_length: 16,
1657 in_place: true,
1658 });
1659 let ttech = dts.create_transformation_technology("generic", &config).unwrap();
1660 let config2 = ttech.config().unwrap();
1661 assert_eq!(config, config2);
1662
1663 let config = TransformationTechnologyConfig::Com(ComTransformationTechnologyConfig { isignal_ipdu_length: 8 });
1665 dts.create_transformation_technology("com", &config).unwrap();
1666
1667 for profile in &[
1669 E2EProfile::P01,
1670 E2EProfile::P02,
1671 E2EProfile::P04,
1672 E2EProfile::P04m,
1673 E2EProfile::P05,
1674 E2EProfile::P06,
1675 E2EProfile::P07,
1676 E2EProfile::P07m,
1677 E2EProfile::P08,
1678 E2EProfile::P08m,
1679 E2EProfile::P11,
1680 E2EProfile::P22,
1681 E2EProfile::P44,
1682 E2EProfile::P44m,
1683 ] {
1684 let e2e_config = E2ETransformationTechnologyConfig {
1685 profile: *profile,
1686 zero_header_length: false,
1687 transform_in_place: true,
1688 offset: 0,
1689 max_delta_counter: 0,
1690 max_error_state_init: 0,
1691 max_error_state_invalid: 0,
1692 max_error_state_valid: 0,
1693 max_no_new_or_repeated_data: 0,
1694 min_ok_state_init: 0,
1695 min_ok_state_invalid: 0,
1696 min_ok_state_valid: 0,
1697 window_size: 10,
1698 window_size_init: Some(11),
1699 window_size_invalid: Some(12),
1700 window_size_valid: Some(13),
1701 profile_behavior: Some(E2EProfileBehavior::R4_2),
1702 sync_counter_init: Some(0),
1703 data_id_mode: Some(DataIdMode::Lower12Bit),
1704 data_id_nibble_offset: Some(1),
1705 crc_offset: Some(2),
1706 counter_offset: Some(3),
1707 };
1708 let config = TransformationTechnologyConfig::E2E(e2e_config.clone());
1709 let ttech = dts
1710 .create_transformation_technology(&format!("{profile:?}"), &config)
1711 .unwrap();
1712 let config2 = ttech.config().unwrap();
1713 let TransformationTechnologyConfig::E2E(e2e_config2) = config2 else {
1714 panic!("Expected E2E transformation technology");
1715 };
1716 assert_eq!(e2e_config.profile, e2e_config2.profile);
1717 assert_eq!(e2e_config.zero_header_length, e2e_config2.zero_header_length);
1718 assert_eq!(e2e_config.transform_in_place, e2e_config2.transform_in_place);
1719 assert_eq!(e2e_config.offset, e2e_config2.offset);
1720 assert_eq!(e2e_config.max_delta_counter, e2e_config2.max_delta_counter);
1721 assert_eq!(e2e_config.max_error_state_init, e2e_config2.max_error_state_init);
1722 assert_eq!(e2e_config.max_error_state_invalid, e2e_config2.max_error_state_invalid);
1723 assert_eq!(e2e_config.max_error_state_valid, e2e_config2.max_error_state_valid);
1724 assert_eq!(
1725 e2e_config.max_no_new_or_repeated_data,
1726 e2e_config2.max_no_new_or_repeated_data
1727 );
1728 assert_eq!(e2e_config.min_ok_state_init, e2e_config2.min_ok_state_init);
1729 assert_eq!(e2e_config.min_ok_state_invalid, e2e_config2.min_ok_state_invalid);
1730 assert_eq!(e2e_config.min_ok_state_valid, e2e_config2.min_ok_state_valid);
1731 if *profile == E2EProfile::P01 || *profile == E2EProfile::P11 {
1732 assert_eq!(e2e_config.data_id_mode, e2e_config2.data_id_mode);
1733 assert_eq!(e2e_config.data_id_nibble_offset, e2e_config2.data_id_nibble_offset);
1734 }
1735 }
1736
1737 let config = TransformationTechnologyConfig::SomeIp(SomeIpTransformationTechnologyConfig {
1739 alignment: 8,
1740 byte_order: ByteOrder::MostSignificantByteFirst,
1741 interface_version: 1,
1742 });
1743 let ttech = dts.create_transformation_technology("someip", &config).unwrap();
1744 let config2 = ttech.config().unwrap();
1745 assert_eq!(config, config2);
1746
1747 let mut ttechs_iter = dts.transformation_technologies();
1749 assert_eq!(ttechs_iter.next().unwrap().name().unwrap(), "generic");
1750 assert_eq!(ttechs_iter.next().unwrap().name().unwrap(), "com");
1751 }
1752
1753 #[test]
1754 fn data_transformation() {
1755 let model = AutosarModelAbstraction::create("test", AutosarVersion::Autosar_00049);
1756 let package = model.get_or_create_package("/package").unwrap();
1757 let dts = DataTransformationSet::new("test_dts", &package).unwrap();
1758
1759 let e2e_transformation_config = TransformationTechnologyConfig::E2E(E2ETransformationTechnologyConfig {
1760 profile: E2EProfile::P01,
1761 zero_header_length: false,
1762 transform_in_place: true,
1763 offset: 0,
1764 max_delta_counter: 0,
1765 max_error_state_init: 0,
1766 max_error_state_invalid: 0,
1767 max_error_state_valid: 0,
1768 max_no_new_or_repeated_data: 0,
1769 min_ok_state_init: 0,
1770 min_ok_state_invalid: 0,
1771 min_ok_state_valid: 0,
1772 window_size: 11,
1773 window_size_init: Some(11),
1774 window_size_invalid: Some(12),
1775 window_size_valid: Some(13),
1776 profile_behavior: Some(E2EProfileBehavior::R4_2),
1777 sync_counter_init: Some(0),
1778 data_id_mode: Some(DataIdMode::All16Bit),
1779 data_id_nibble_offset: None,
1780 crc_offset: Some(2),
1781 counter_offset: Some(3),
1782 });
1783 let e2e_transformation = dts
1784 .create_transformation_technology("e2e", &e2e_transformation_config)
1785 .unwrap();
1786 assert_eq!(e2e_transformation.config().unwrap(), e2e_transformation_config);
1787
1788 let com_transformation_config =
1789 TransformationTechnologyConfig::Com(ComTransformationTechnologyConfig { isignal_ipdu_length: 8 });
1790 let com_transformation = dts
1791 .create_transformation_technology("com", &com_transformation_config)
1792 .unwrap();
1793 assert_eq!(com_transformation.config().unwrap(), com_transformation_config);
1794
1795 let someip_transformation_config =
1796 TransformationTechnologyConfig::SomeIp(SomeIpTransformationTechnologyConfig {
1797 alignment: 8,
1798 byte_order: ByteOrder::MostSignificantByteFirst,
1799 interface_version: 1,
1800 });
1801 let someip_transformation = dts
1802 .create_transformation_technology("someip", &someip_transformation_config)
1803 .unwrap();
1804 assert_eq!(someip_transformation.config().unwrap(), someip_transformation_config);
1805
1806 let generic_transformation_config =
1807 TransformationTechnologyConfig::Generic(GenericTransformationTechnologyConfig {
1808 protocol_name: "test".to_string(),
1809 protocol_version: "1.0.0".to_string(),
1810 header_length: 16,
1811 in_place: true,
1812 });
1813 let generic_transformation = dts
1814 .create_transformation_technology("generic", &generic_transformation_config)
1815 .unwrap();
1816 assert_eq!(someip_transformation.config().unwrap(), someip_transformation_config);
1817
1818 let result = dts.create_data_transformation("test1", &[], true);
1820 assert!(result.is_err());
1821
1822 let result = dts.create_data_transformation("test2", &[&com_transformation, &someip_transformation], true);
1824 assert!(result.is_err());
1825
1826 let result = dts.create_data_transformation("test3", &[&com_transformation], true);
1828 assert!(result.is_ok());
1829
1830 let result = dts.create_data_transformation("test4", &[&e2e_transformation], true);
1832 assert!(result.is_ok());
1833
1834 let result = dts.create_data_transformation("test5", &[&someip_transformation], true);
1836 assert!(result.is_ok());
1837
1838 let result = dts.create_data_transformation("test6", &[&generic_transformation], true);
1840 assert!(result.is_ok());
1841
1842 let result = dts.create_data_transformation("test7", &[&com_transformation, &e2e_transformation], true);
1844 assert!(result.is_ok());
1845
1846 let result = dts.create_data_transformation("test8", &[&someip_transformation, &e2e_transformation], true);
1848 assert!(result.is_ok());
1849
1850 let result = dts.create_data_transformation("test9", &[&generic_transformation, &e2e_transformation], true);
1852 assert!(result.is_ok());
1853 let dt = result.unwrap();
1854 assert_eq!(dt.data_transformation_set().unwrap(), dts);
1855
1856 let dts2 = package.create_data_transformation_set("test_dts2").unwrap();
1857
1858 let result = dts2.create_data_transformation("test10", &[&e2e_transformation], true);
1860 assert!(result.is_err());
1861
1862 let mut dts_iter = dts.data_transformations();
1864 assert_eq!(dts_iter.next().unwrap().name().unwrap(), "test3");
1865 assert_eq!(dts_iter.next().unwrap().name().unwrap(), "test4");
1866 assert_eq!(dts_iter.next().unwrap().name().unwrap(), "test5");
1867 assert_eq!(dts_iter.next().unwrap().name().unwrap(), "test6");
1868 assert_eq!(dts_iter.next().unwrap().name().unwrap(), "test7");
1869 assert_eq!(dts_iter.next().unwrap().name().unwrap(), "test8");
1870 assert_eq!(dts_iter.next().unwrap().name().unwrap(), "test9");
1871 assert_eq!(dts_iter.next(), None);
1872 }
1873
1874 #[test]
1875 fn transformation_technology() {
1876 let model = AutosarModelAbstraction::create("test", AutosarVersion::Autosar_4_2_1);
1877 let package = model.get_or_create_package("/package").unwrap();
1878 let dts = DataTransformationSet::new("test_dts", &package).unwrap();
1879
1880 let e2e_config_p01 = TransformationTechnologyConfig::E2E(E2ETransformationTechnologyConfig {
1881 profile: E2EProfile::P01,
1882 zero_header_length: false,
1883 transform_in_place: true,
1884 offset: 0,
1885 max_delta_counter: 0,
1886 max_error_state_init: 0,
1887 max_error_state_invalid: 0,
1888 max_error_state_valid: 0,
1889 max_no_new_or_repeated_data: 0,
1890 min_ok_state_init: 0,
1891 min_ok_state_invalid: 0,
1892 min_ok_state_valid: 0,
1893 window_size: 10,
1894 window_size_init: Some(11),
1895 window_size_invalid: Some(12),
1896 window_size_valid: Some(13),
1897 profile_behavior: Some(E2EProfileBehavior::R4_2),
1898 sync_counter_init: Some(0),
1899 data_id_mode: Some(DataIdMode::Lower12Bit),
1900 data_id_nibble_offset: Some(1),
1901 crc_offset: Some(2),
1902 counter_offset: Some(3),
1903 });
1904 let e2e_config_p04 = TransformationTechnologyConfig::E2E(E2ETransformationTechnologyConfig {
1905 profile: E2EProfile::P04,
1906 zero_header_length: false,
1907 transform_in_place: true,
1908 offset: 0,
1909 max_delta_counter: 0,
1910 max_error_state_init: 0,
1911 max_error_state_invalid: 0,
1912 max_error_state_valid: 0,
1913 max_no_new_or_repeated_data: 0,
1914 min_ok_state_init: 0,
1915 min_ok_state_invalid: 0,
1916 min_ok_state_valid: 0,
1917 window_size: 10,
1918 window_size_init: Some(11),
1919 window_size_invalid: Some(12),
1920 window_size_valid: Some(13),
1921 profile_behavior: Some(E2EProfileBehavior::R4_2),
1922 sync_counter_init: Some(0),
1923 data_id_mode: None,
1924 data_id_nibble_offset: None,
1925 crc_offset: None,
1926 counter_offset: None,
1927 });
1928 let com_config =
1929 TransformationTechnologyConfig::Com(ComTransformationTechnologyConfig { isignal_ipdu_length: 8 });
1930 let someip_config = TransformationTechnologyConfig::SomeIp(SomeIpTransformationTechnologyConfig {
1931 alignment: 8,
1932 byte_order: ByteOrder::MostSignificantByteFirst,
1933 interface_version: 1,
1934 });
1935 let generic_config = TransformationTechnologyConfig::Generic(GenericTransformationTechnologyConfig {
1936 protocol_name: "test".to_string(),
1937 protocol_version: "1.0.0".to_string(),
1938 header_length: 16,
1939 in_place: true,
1940 });
1941
1942 let transformation = dts.create_transformation_technology("t", &e2e_config_p01).unwrap();
1944 let e2e_p01_transformation_orig = transformation.element().serialize();
1945 dts.element()
1946 .remove_sub_element_kind(ElementName::TransformationTechnologys)
1947 .unwrap();
1948
1949 let transformation = dts.create_transformation_technology("t", &e2e_config_p04).unwrap();
1950 let e2e_p04_transformation_orig = transformation.element().serialize();
1951 dts.element()
1952 .remove_sub_element_kind(ElementName::TransformationTechnologys)
1953 .unwrap();
1954
1955 let transformation = dts.create_transformation_technology("t", &com_config).unwrap();
1956 let com_transformation_orig = transformation.element().serialize();
1957 dts.element()
1958 .remove_sub_element_kind(ElementName::TransformationTechnologys)
1959 .unwrap();
1960
1961 let transformation = dts.create_transformation_technology("t", &someip_config).unwrap();
1962 let someip_transformation_orig = transformation.element().serialize();
1963 dts.element()
1964 .remove_sub_element_kind(ElementName::TransformationTechnologys)
1965 .unwrap();
1966
1967 let transformation = dts.create_transformation_technology("t", &generic_config).unwrap();
1968 let generic_transformation_orig = transformation.element().serialize();
1969 dts.element()
1970 .remove_sub_element_kind(ElementName::TransformationTechnologys)
1971 .unwrap();
1972
1973 let transformation = dts.create_transformation_technology("t", &generic_config).unwrap();
1975 transformation.set_config(&e2e_config_p01).unwrap();
1976 assert_eq!(transformation.element().serialize(), e2e_p01_transformation_orig);
1977 transformation.set_config(&e2e_config_p04).unwrap();
1978 assert_eq!(transformation.element().serialize(), e2e_p04_transformation_orig);
1979 transformation.set_config(&com_config).unwrap();
1980 assert_eq!(transformation.element().serialize(), com_transformation_orig);
1981 transformation.set_config(&someip_config).unwrap();
1982 assert_eq!(transformation.element().serialize(), someip_transformation_orig);
1983 transformation.set_config(&generic_config).unwrap();
1984 assert_eq!(transformation.element().serialize(), generic_transformation_orig);
1985 }
1986
1987 #[test]
1988 fn data_transformation_chain_iter() {
1989 let model = AutosarModelAbstraction::create("test", AutosarVersion::Autosar_4_2_1);
1990 let package = model.get_or_create_package("/package").unwrap();
1991 let dts = DataTransformationSet::new("test_dts", &package).unwrap();
1992
1993 let com_transformation = dts
1994 .create_transformation_technology(
1995 "com",
1996 &TransformationTechnologyConfig::Com(ComTransformationTechnologyConfig { isignal_ipdu_length: 8 }),
1997 )
1998 .unwrap();
1999
2000 let dt = dts
2001 .create_data_transformation("test", &[&com_transformation], false)
2002 .unwrap();
2003 assert_eq!(dt.transformation_technologies().count(), 1);
2004 let com_transformation2 = dt.transformation_technologies().next().unwrap();
2005 assert_eq!(com_transformation, com_transformation2);
2006 }
2007
2008 #[test]
2009 fn transformation_isignal_props() {
2010 let model = AutosarModelAbstraction::create("test", AutosarVersion::Autosar_00049);
2011 let package = model.get_or_create_package("/package").unwrap();
2012 let dts = DataTransformationSet::new("test_dts", &package).unwrap();
2013
2014 let e2e_transformation = dts
2015 .create_transformation_technology(
2016 "e2e",
2017 &TransformationTechnologyConfig::E2E(E2ETransformationTechnologyConfig {
2018 profile: E2EProfile::P01,
2019 zero_header_length: false,
2020 transform_in_place: true,
2021 offset: 0,
2022 max_delta_counter: 0,
2023 max_error_state_init: 0,
2024 max_error_state_invalid: 0,
2025 max_error_state_valid: 0,
2026 max_no_new_or_repeated_data: 0,
2027 min_ok_state_init: 0,
2028 min_ok_state_invalid: 0,
2029 min_ok_state_valid: 0,
2030 window_size: 10,
2031 window_size_init: Some(11),
2032 window_size_invalid: Some(12),
2033 window_size_valid: Some(13),
2034 profile_behavior: Some(E2EProfileBehavior::R4_2),
2035 sync_counter_init: Some(0),
2036 data_id_mode: Some(DataIdMode::Lower12Bit),
2037 data_id_nibble_offset: Some(1),
2038 crc_offset: Some(2),
2039 counter_offset: Some(3),
2040 }),
2041 )
2042 .unwrap();
2043 let someip_transformation = dts
2044 .create_transformation_technology(
2045 "someip",
2046 &TransformationTechnologyConfig::SomeIp(SomeIpTransformationTechnologyConfig {
2047 alignment: 8,
2048 byte_order: ByteOrder::MostSignificantByteFirst,
2049 interface_version: 1,
2050 }),
2051 )
2052 .unwrap();
2053
2054 let sw_base_type =
2055 SwBaseType::new("sw_base_type", &package, 8, BaseTypeEncoding::None, None, None, None).unwrap();
2056 let signal = ISignal::new(
2057 "signal",
2058 &package,
2059 8,
2060 &SystemSignal::new("sys_signal", &package).unwrap(),
2061 Some(&sw_base_type),
2062 )
2063 .unwrap();
2064
2065 let e2e_props = signal
2066 .create_e2e_transformation_isignal_props(&e2e_transformation)
2067 .unwrap();
2068 assert_eq!(e2e_props.transformer().unwrap(), e2e_transformation);
2069 e2e_props.set_data_ids(&[1, 2, 3]).unwrap();
2070 e2e_props.set_data_length(Some(8)).unwrap();
2071 e2e_props.set_max_data_length(Some(16)).unwrap();
2072 e2e_props.set_min_data_length(Some(4)).unwrap();
2073 e2e_props.set_source_id(Some(0)).unwrap();
2074 assert_eq!(e2e_props.data_ids(), vec![1, 2, 3]);
2075 assert_eq!(e2e_props.data_length().unwrap(), 8);
2076 assert_eq!(e2e_props.max_data_length().unwrap(), 16);
2077 assert_eq!(e2e_props.min_data_length().unwrap(), 4);
2078 assert_eq!(e2e_props.source_id().unwrap(), 0);
2079 e2e_props.set_data_ids(&[]).unwrap();
2080 e2e_props.set_data_length(None).unwrap();
2081 e2e_props.set_max_data_length(None).unwrap();
2082 e2e_props.set_min_data_length(None).unwrap();
2083 e2e_props.set_source_id(None).unwrap();
2084 assert_eq!(e2e_props.data_ids(), vec![]);
2085 assert_eq!(e2e_props.data_length(), None);
2086 assert_eq!(e2e_props.max_data_length(), None);
2087 assert_eq!(e2e_props.min_data_length(), None);
2088 assert_eq!(e2e_props.source_id(), None);
2089
2090 assert!(EndToEndTransformationISignalProps::try_from(e2e_props.element().clone()).is_ok());
2091
2092 let someip_props = signal
2093 .create_someip_transformation_isignal_props(&someip_transformation)
2094 .unwrap();
2095 assert_eq!(someip_props.transformer().unwrap(), someip_transformation);
2096 someip_props.set_legacy_strings(Some(true)).unwrap();
2097 someip_props.set_interface_version(Some(1)).unwrap();
2098 someip_props.set_dynamic_length(Some(true)).unwrap();
2099 someip_props.set_message_type(Some(SomeIpMessageType::Request)).unwrap();
2100 someip_props.set_size_of_array_length(Some(8)).unwrap();
2101 someip_props.set_size_of_string_length(Some(16)).unwrap();
2102 someip_props.set_size_of_struct_length(Some(32)).unwrap();
2103 someip_props.set_size_of_union_length(Some(64)).unwrap();
2104 assert!(someip_props.legacy_strings().unwrap());
2105 assert_eq!(someip_props.interface_version().unwrap(), 1);
2106 assert!(someip_props.dynamic_length().unwrap());
2107 assert_eq!(someip_props.message_type().unwrap(), SomeIpMessageType::Request);
2108 assert_eq!(someip_props.size_of_array_length().unwrap(), 8);
2109 assert_eq!(someip_props.size_of_string_length().unwrap(), 16);
2110 assert_eq!(someip_props.size_of_struct_length().unwrap(), 32);
2111 assert_eq!(someip_props.size_of_union_length().unwrap(), 64);
2112 someip_props.set_legacy_strings(None).unwrap();
2113 someip_props.set_interface_version(None).unwrap();
2114 someip_props.set_dynamic_length(None).unwrap();
2115 someip_props.set_message_type(None).unwrap();
2116 someip_props.set_size_of_array_length(None).unwrap();
2117 someip_props.set_size_of_string_length(None).unwrap();
2118 someip_props.set_size_of_struct_length(None).unwrap();
2119 someip_props.set_size_of_union_length(None).unwrap();
2120 assert_eq!(someip_props.legacy_strings(), None);
2121 assert_eq!(someip_props.interface_version(), None);
2122 assert_eq!(someip_props.dynamic_length(), None);
2123 assert_eq!(someip_props.message_type(), None);
2124 assert_eq!(someip_props.size_of_array_length(), None);
2125 assert_eq!(someip_props.size_of_string_length(), None);
2126 assert_eq!(someip_props.size_of_struct_length(), None);
2127 assert_eq!(someip_props.size_of_union_length(), None);
2128
2129 assert!(SomeIpTransformationISignalProps::try_from(someip_props.element().clone()).is_ok());
2130
2131 assert_eq!(signal.transformation_isignal_props().count(), 2);
2132 let mut props_iter = signal.transformation_isignal_props();
2133 assert_eq!(props_iter.next().unwrap().element(), e2e_props.element());
2134 assert_eq!(props_iter.next().unwrap().element(), someip_props.element());
2135 }
2136}