1use std::marker::PhantomData;
2
3#[cfg(test)]
4use byteorder::{BigEndian, LittleEndian};
5use byteorder::{ByteOrder, ReadBytesExt};
6#[allow(unused_imports)]
7use log::{debug, error, info, trace, warn};
8use pastey::paste;
9#[cfg(test)]
10use serde::de::DeserializeOwned;
11use serde::de::{
12 self, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, Visitor,
13};
14
15pub use super::error::{Error, Result};
16
17pub struct CdrDeserializer<'i, BO> {
22 phantom: PhantomData<BO>, input: &'i [u8], serialized_data_count: usize, }
27
28impl<'de, BO> CdrDeserializer<'de, BO>
29where
30 BO: ByteOrder,
31{
32 pub fn new(input: &'de [u8]) -> CdrDeserializer<'de, BO> {
33 CdrDeserializer::<BO> {
34 phantom: PhantomData,
35 input,
36 serialized_data_count: 0,
37 }
38 }
39
40 pub fn bytes_consumed(&self) -> usize {
42 self.serialized_data_count
43 }
44
45 fn next_bytes(&mut self, count: usize) -> Result<&'de [u8]> {
47 if count <= self.input.len() {
48 let (head, tail) = self.input.split_at(count);
49 self.input = tail;
50 self.serialized_data_count += count;
51 Ok(head)
52 } else {
53 Err(Error::Eof)
54 }
55 }
56
57 fn remove_bytes_from_input(&mut self, count: usize) -> Result<()> {
59 let _pad = self.next_bytes(count)?;
60 Ok(())
61 }
62
63 fn calculate_padding_count_from_written_bytes_and_remove(
64 &mut self,
65 type_octet_alignment: usize,
66 ) -> Result<()> {
67 let modulo = self.serialized_data_count % type_octet_alignment;
68 if modulo == 0 {
69 Ok(())
70 } else {
71 let padding = type_octet_alignment - modulo;
72 self.remove_bytes_from_input(padding)
73 }
74 }
75}
76
77pub fn from_bytes<'de, T, BO>(input_bytes: &'de [u8]) -> Result<(T, usize)>
82where
83 T: serde::Deserialize<'de>,
84 BO: ByteOrder,
85{
86 from_bytes_with::<PhantomData<T>, BO>(input_bytes, PhantomData)
87}
88
89pub fn from_bytes_with<'de, S, BO>(input_bytes: &'de [u8], decoder: S) -> Result<(S::Value, usize)>
93where
94 S: DeserializeSeed<'de>,
95 BO: ByteOrder,
96{
97 let mut deserializer = CdrDeserializer::<BO>::new(input_bytes);
98 let t = decoder.deserialize(&mut deserializer)?;
99 Ok((t, deserializer.serialized_data_count))
100}
101
102#[cfg(test)]
103pub fn deserialize_from_little_endian<T>(s: &[u8]) -> Result<T>
104where
105 T: DeserializeOwned,
106{
107 let mut deserializer = CdrDeserializer::<LittleEndian>::new(s);
108 T::deserialize(&mut deserializer)
109}
110
111#[cfg(test)]
112pub fn deserialize_from_big_endian<T>(s: &[u8]) -> Result<T>
113where
114 T: DeserializeOwned,
115{
116 let mut deserializer = CdrDeserializer::<BigEndian>::new(s);
117 T::deserialize(&mut deserializer)
118}
119
120macro_rules! deserialize_multibyte_number {
123 ($num_type:ident) => {
124 paste! {
125 fn [<deserialize_ $num_type>]<V>(self, visitor: V) -> Result<V::Value>
126 where
127 V: Visitor<'de>,
128 {
129 const SIZE :usize = std::mem::size_of::<$num_type>();
130 static_assertions::const_assert!(SIZE > 1); self.calculate_padding_count_from_written_bytes_and_remove(SIZE)?;
132 visitor.[<visit_ $num_type>](
133 self.next_bytes(SIZE)?.[<read_ $num_type>]::<BO>().unwrap() )
134 }
135 }
136 };
137}
138
139impl<'de, 'a, 'c, BO> de::Deserializer<'de> for &'a mut CdrDeserializer<'c, BO>
140where
141 'c: 'de,
142 BO: ByteOrder,
143{
144 type Error = Error;
145
146 fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
150 where
151 V: Visitor<'de>,
152 {
153 Err(Error::NotSelfDescribingFormat(
154 "CDR cannot deserialize \"any\" type. ".to_string(),
155 ))
156 }
157
158 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
162 where
163 V: Visitor<'de>,
164 {
165 match self.next_bytes(1)?.first().unwrap() {
166 0 => visitor.visit_bool(false),
167 1 => visitor.visit_bool(true),
168 x => Err(Error::BadBoolean(*x)),
169 }
170 }
171
172 deserialize_multibyte_number!(i16);
173 deserialize_multibyte_number!(i32);
174 deserialize_multibyte_number!(i64);
175
176 deserialize_multibyte_number!(u16);
177 deserialize_multibyte_number!(u32);
178 deserialize_multibyte_number!(u64);
179
180 deserialize_multibyte_number!(f32);
181 deserialize_multibyte_number!(f64);
182
183 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
185 where
186 V: Visitor<'de>,
187 {
188 visitor.visit_i8(self.next_bytes(1)?.read_i8().unwrap())
189 }
190
191 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
192 where
193 V: Visitor<'de>,
194 {
195 visitor.visit_u8(self.next_bytes(1)?.read_u8().unwrap())
196 }
197
198 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
200 where
201 V: Visitor<'de>,
202 {
203 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
204 let codepoint = self.next_bytes(4)?.read_u32::<BO>().unwrap();
205 match char::from_u32(codepoint) {
206 Some(c) => visitor.visit_char(c),
207 None => Err(Error::BadChar(codepoint)),
208 }
209 }
210
211 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
212 where
213 V: Visitor<'de>,
214 {
215 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
217 let bytes_len = self.next_bytes(4)?.read_u32::<BO>().unwrap() as usize;
218
219 let bytes = self.next_bytes(bytes_len)?; let bytes_without_null = match bytes.split_last() {
223 None => {
224 info!("deserialize_str: Received string with not even a null terminator.");
227 bytes
228 }
229 Some((null_char, contents)) => {
230 if *null_char != 0 {
231 warn!(
232 "deserialize_str: Expected string null terminator, got {:#x} instead.",
233 null_char
234 );
235 }
236 contents
237 }
238 };
239
240 std::str::from_utf8(bytes_without_null)
242 .map_err(Error::BadUTF8)
243 .and_then(|s| visitor.visit_str(s))
244
245 }
250
251 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
252 where
253 V: Visitor<'de>,
254 {
255 self.deserialize_str(visitor)
256 }
257
258 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
261 where
262 V: Visitor<'de>,
263 {
264 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
265 let len = self.next_bytes(4)?.read_u32::<BO>().unwrap() as usize;
266 let bytes = self.next_bytes(len)?;
267 visitor.visit_borrowed_bytes(bytes)
268 }
269
270 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
271 where
272 V: Visitor<'de>,
273 {
274 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
276 let len = self.next_bytes(4)?.read_u32::<BO>().unwrap() as usize;
278 let buf = self.next_bytes(len)?.to_vec();
280
281 visitor.visit_byte_buf(buf)
282
283 }
284
285 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
286 where
287 V: Visitor<'de>,
288 {
289 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
290 let enum_tag = self.next_bytes(4)?.read_u32::<BO>().unwrap();
291 match enum_tag {
292 0 => visitor.visit_none(),
293 1 => visitor.visit_some(self),
294 wtf => Err(Error::BadOption(wtf)),
295 }
296 }
297
298 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
299 where
300 V: Visitor<'de>,
301 {
302 visitor.visit_unit()
304 }
305
306 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
307 where
308 V: Visitor<'de>,
309 {
310 self.deserialize_unit(visitor) }
313
314 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
315 where
316 V: Visitor<'de>,
317 {
318 visitor.visit_newtype_struct(self)
319 }
320
321 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
327 where
328 V: Visitor<'de>,
329 {
330 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
331 let element_count = self.next_bytes(4)?.read_u32::<BO>().unwrap() as usize;
332 visitor.visit_seq(SequenceHelper::new(self, element_count))
333 }
334
335 fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
337 where
338 V: Visitor<'de>,
339 {
340 visitor.visit_seq(SequenceHelper::new(self, len))
341 }
342
343 fn deserialize_tuple_struct<V>(
344 self,
345 _name: &'static str,
346 len: usize,
347 visitor: V,
348 ) -> Result<V::Value>
349 where
350 V: Visitor<'de>,
351 {
352 visitor.visit_seq(SequenceHelper::new(self, len))
353 }
354
355 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
356 where
357 V: Visitor<'de>,
358 {
359 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
360 let element_count = self.next_bytes(4)?.read_u32::<BO>().unwrap() as usize;
361 visitor.visit_map(SequenceHelper::new(self, element_count))
362 }
363
364 fn deserialize_struct<V>(
365 self,
366 _name: &'static str,
367 fields: &'static [&'static str],
368 visitor: V,
369 ) -> Result<V::Value>
370 where
371 V: Visitor<'de>,
372 {
373 visitor.visit_seq(SequenceHelper::new(self, fields.len()))
374 }
375
376 fn deserialize_enum<V>(
383 self,
384 _name: &'static str,
385 _variants: &'static [&'static str],
386 visitor: V,
387 ) -> Result<V::Value>
388 where
389 V: Visitor<'de>,
390 {
391 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
392 visitor.visit_enum(EnumerationHelper::<BO>::new(self))
393 }
394
395 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
400 where
401 V: Visitor<'de>,
402 {
403 self.deserialize_u32(visitor)
404 }
405
406 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
407 where
408 V: Visitor<'de>,
409 {
410 self.deserialize_any(visitor)
411 }
412
413 fn is_human_readable(&self) -> bool {
414 false
415 }
416}
417
418struct EnumerationHelper<'a, 'i: 'a, BO> {
421 de: &'a mut CdrDeserializer<'i, BO>,
422}
423
424impl<'a, 'i, BO> EnumerationHelper<'a, 'i, BO>
425where
426 BO: ByteOrder,
427{
428 fn new(de: &'a mut CdrDeserializer<'i, BO>) -> Self {
429 EnumerationHelper::<BO> { de }
430 }
431}
432
433impl<'de, 'a, 'i, BO> EnumAccess<'de> for EnumerationHelper<'a, 'i, BO>
434where
435 'i: 'de,
436 BO: ByteOrder,
437{
438 type Error = Error;
439 type Variant = Self;
440
441 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
442 where
443 V: DeserializeSeed<'de>,
444 {
445 let enum_tag = self.de.next_bytes(4)?.read_u32::<BO>().unwrap();
447 let val: Result<_> = seed.deserialize(enum_tag.into_deserializer());
448 Ok((val?, self))
449 }
450}
451
452impl<'de, 'a, 'i, BO> VariantAccess<'de> for EnumerationHelper<'a, 'i, BO>
455where
456 'i: 'de,
457 BO: ByteOrder,
458{
459 type Error = Error;
460
461 fn unit_variant(self) -> Result<()> {
462 Ok(())
463 }
464
465 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
466 where
467 T: DeserializeSeed<'de>,
468 {
469 seed.deserialize(self.de)
470 }
471
472 fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value>
473 where
474 V: Visitor<'de>,
475 {
476 de::Deserializer::deserialize_tuple(self.de, len, visitor)
477 }
478
479 fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
480 where
481 V: Visitor<'de>,
482 {
483 de::Deserializer::deserialize_tuple(self.de, fields.len(), visitor)
484 }
485}
486
487struct SequenceHelper<'a, 'i: 'a, BO> {
490 de: &'a mut CdrDeserializer<'i, BO>,
491 element_counter: usize,
492 expected_count: usize,
493}
494
495impl<'a, 'i, BO> SequenceHelper<'a, 'i, BO> {
496 fn new(de: &'a mut CdrDeserializer<'i, BO>, expected_count: usize) -> Self {
497 SequenceHelper {
498 de,
499 element_counter: 0,
500 expected_count,
501 }
502 }
503}
504
505impl<'a, 'de, 'i, BO> SeqAccess<'de> for SequenceHelper<'a, 'i, BO>
508where
509 'i: 'de,
510 BO: ByteOrder,
511{
512 type Error = Error;
513
514 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
515 where
516 T: DeserializeSeed<'de>,
517 {
518 if self.element_counter == self.expected_count {
519 Ok(None)
520 } else {
521 self.element_counter += 1;
522 seed.deserialize(&mut *self.de).map(Some)
523 }
524 }
525}
526
527impl<'de, 'a, 'i, BO> MapAccess<'de> for SequenceHelper<'a, 'i, BO>
530where
531 'i: 'de,
532 BO: ByteOrder,
533{
534 type Error = Error;
535
536 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
537 where
538 K: DeserializeSeed<'de>,
539 {
540 if self.element_counter == self.expected_count {
541 Ok(None)
542 } else {
543 self.element_counter += 1;
544 seed.deserialize(&mut *self.de).map(Some)
545 }
546 }
547
548 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
549 where
550 V: DeserializeSeed<'de>,
551 {
552 seed.deserialize(&mut *self.de)
554 }
555}
556
557#[cfg(test)]
558#[allow(clippy::needless_pass_by_value)]
559mod tests {
560 use byteorder::{BigEndian, LittleEndian};
561 use log::info;
562 use serde::{Deserialize, Serialize};
563 use serde_repr::{Deserialize_repr, Serialize_repr};
564 use test_case::test_case;
565
566 use crate::{
567 cdr_deserializer::{deserialize_from_big_endian, deserialize_from_little_endian},
568 cdr_serializer::to_vec,
569 from_bytes,
570 };
571
572 #[test]
573 fn cdr_deserialization_struct() {
574 #[derive(Serialize, Deserialize, Debug, PartialEq)]
612 struct MyType {
613 first_value: u8,
614 second_value: i8,
615 third_value: i32,
616 fourth_value: u64,
617 fifth: bool,
618 sixth: f32,
619 seventh: bool,
620 eighth: Vec<i32>,
621 ninth: Vec<u8>,
622 tenth: Vec<i16>,
623 eleventh: Vec<i64>,
624 twelve: [u16; 3],
625 thirteen: String,
626 }
627
628 let micky_mouse = MyType {
629 first_value: 1,
630 second_value: -3,
631 third_value: -5000,
632 fourth_value: 1234u64,
633 fifth: true,
634 sixth: -6.6f32,
635 seventh: true,
636 eighth: vec![1, 2],
637 ninth: vec![1],
638 tenth: vec![5, -4, 3, -2, 1],
639 eleventh: vec![],
640 twelve: [3, 2, 1],
641 thirteen: "abc".to_string(),
642 };
643
644 let expected_serialized_result: Vec<u8> = vec![
645 0x01, 0xfd, 0x00, 0x00, 0x78, 0xec, 0xff, 0xff, 0xd2, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x01, 0x00, 0x00, 0x00, 0x33, 0x33, 0xd3, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
647 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
648 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfe, 0xff,
649 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00,
650 0x00, 0x04, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x00,
651 ];
652
653 let serialized = to_vec::<MyType, LittleEndian>(&micky_mouse).unwrap();
654
655 for x in 0..expected_serialized_result.len() {
656 if expected_serialized_result[x] != serialized[x] {
657 info!("index: {}", x);
658 }
659 }
660 assert_eq!(serialized, expected_serialized_result);
661 info!("serialization successful!");
662
663 let built: MyType = deserialize_from_little_endian(&expected_serialized_result).unwrap();
664 assert_eq!(built, micky_mouse);
665 info!("deserialized: {:?}", built);
666 }
667
668 #[test]
669
670 fn cdr_deserialization_user_defined_data() {
671 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
674 struct ShapeType {
675 color: String,
676 x: i32,
677 y: i32,
678 size: i32,
679 }
680
681 let message = ShapeType {
682 color: "BLUE".to_string(),
683 x: 34,
684 y: 100,
685 size: 24,
686 };
687
688 let expected_serialized_result: Vec<u8> = vec![
689 0x05, 0x00, 0x00, 0x00, 0x42, 0x4c, 0x55, 0x45, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
690 0x00, 0x64, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
691 ];
692
693 let serialized = to_vec::<ShapeType, LittleEndian>(&message).unwrap();
694 assert_eq!(serialized, expected_serialized_result);
695 let deserialized_message: ShapeType = deserialize_from_little_endian(&serialized).unwrap();
696 assert_eq!(deserialized_message, message);
697 }
698
699 #[test]
700
701 fn cdr_deserialization_serialization_topic_name() {
702 let received_cdr_string: Vec<u8> = vec![
708 0x07, 0x00, 0x00, 0x00, 0x053, 0x71, 0x75, 0x61, 0x72, 0x65, 0x00, ];
710
711 let deserialized_message: String =
712 deserialize_from_little_endian(&received_cdr_string).unwrap();
713 info!("{:?}", deserialized_message);
714 assert_eq!("Square", deserialized_message);
715
716 let received_cdr_string2: Vec<u8> = vec![
717 0x0A, 0x00, 0x00, 0x00, 0x53, 0x68, 0x61, 0x70, 0x65, 0x54, 0x79, 0x70, 0x65,
718 0x00, ];
720
721 let deserialized_message2: String =
722 deserialize_from_little_endian(&received_cdr_string2).unwrap();
723 info!("{:?}", deserialized_message2);
724 assert_eq!("ShapeType", deserialized_message2);
725 }
726
727 #[test]
728 fn cdr_deserialization_example_struct() {
729 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
733 struct Example {
734 a: u32,
735 b: [u8; 4],
736 }
737
738 let o = Example {
739 a: 1,
740 b: [b'a', b'b', b'c', b'd'],
741 };
742
743 let serialized_le: Vec<u8> = vec![0x01, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64];
744
745 let serialized_be: Vec<u8> = vec![0x00, 0x00, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64];
746
747 let deserialized_le: Example = deserialize_from_little_endian(&serialized_le).unwrap();
748 let deserialized_be: Example = deserialize_from_big_endian(&serialized_be).unwrap();
749 let serialized_o_le = to_vec::<Example, LittleEndian>(&o).unwrap();
750 let serialized_o_be = to_vec::<Example, BigEndian>(&o).unwrap();
751
752 assert_eq!(
753 serialized_o_le,
754 vec![0x01, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64,]
755 );
756
757 assert_eq!(
758 serialized_o_be,
759 vec![0x00, 0x00, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64,]
760 );
761
762 info!("serialization success");
763
764 assert_eq!(deserialized_le, o);
765 assert_eq!(deserialized_be, o);
766 info!("deserialization success");
767 }
768
769 #[test]
770
771 fn cdr_deserialization_serialization_payload_shapes() {
772 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
775 struct ShapeType {
776 color: String,
777 x: i32,
778 y: i32,
779 size: i32,
780 }
781 let received_message: Vec<u8> = vec![
784 0x04, 0x00, 0x00, 0x00, 0x52, 0x45, 0x44, 0x00, 0x61, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00,
785 0x00, 0x1e, 0x00, 0x00, 0x00,
786 ];
787 let received_message2: Vec<u8> = vec![
788 0x04, 0x00, 0x00, 0x00, 0x52, 0x45, 0x44, 0x00, 0x61, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00,
789 0x00, 0x1e, 0x00, 0x00, 0x00,
790 ];
791
792 let deserialized_message: ShapeType =
793 deserialize_from_little_endian(&received_message).unwrap();
794 info!("{:?}", deserialized_message);
795
796 let serialized_message = to_vec::<ShapeType, LittleEndian>(&deserialized_message).unwrap();
797
798 assert_eq!(serialized_message, received_message2);
799 }
801
802 #[test]
803
804 fn cdr_deserialization_custom_data_message_from_ros_and_wireshark() {
805 #[derive(Serialize, Deserialize, Debug, PartialEq)]
815 struct MessageType {
816 x: f64,
817 y: f64,
818 heading: f64,
819 v_x: f64,
820 v_y: f64,
821 kappa: f64,
822 test: String,
823 }
824
825 let received_message_le: Vec<u8> = vec![
827 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
829 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x85, 0xeb, 0x51, 0xb8,
830 0x1e, 0xd5, 0x3f, 0x0a, 0x00, 0x00, 0x00, 0x54, 0x6f, 0x69, 0x6d, 0x69, 0x69, 0x6b, 0x6f,
831 0x3f, 0x00, ];
833
834 let value: MessageType = deserialize_from_little_endian(&received_message_le).unwrap();
835 info!("{:?}", value);
836 assert_eq!(value.test, "Toimiiko?");
837 }
838
839 #[derive(Serialize, Deserialize, Debug, PartialEq)]
840 struct InterestingMessage {
841 unbounded_string: String,
842 x: i32,
843 y: i32,
844 shape_size: i32,
845 slide: f32,
846 double_slide: f64,
847 three_short: [u16; 3],
848 four_short: [i16; 4],
849 booleans: Vec<bool>,
850 three_bytes: Vec<u8>,
851 }
852
853 #[derive(Serialize, Deserialize, Debug, PartialEq)]
854 enum BigEnum {
855 Interesting(InterestingMessage),
856 Boring,
857 Something { x: f32, y: f32 },
858 }
859
860 #[test]
861 fn cdr_deserialization_custom_type() {
862 let value = InterestingMessage {
896 unbounded_string: "Tassa on aika pitka teksti".to_string(), x: 2,
899 y: -3,
900 shape_size: -4,
901 slide: 5.5,
902 double_slide: -6.6,
903 three_short: [1, 2, 3],
904 four_short: [1, -2, -3, 4],
905 booleans: vec![true, false, true],
906 three_bytes: [23, 0, 2].to_vec(),
907 };
908
909 const DATA: &[u8] = &[
910 0x1b, 0x00, 0x00, 0x00, 0x54, 0x61, 0x73, 0x73, 0x61, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x69,
911 0x6b, 0x61, 0x20, 0x70, 0x69, 0x74, 0x6b, 0x61, 0x20, 0x74, 0x65, 0x6b, 0x73, 0x74, 0x69,
912 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x00,
913 0x00, 0xb0, 0x40, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x1a, 0xc0, 0x01, 0x00, 0x02, 0x00,
914 0x03, 0x00, 0x01, 0x00, 0xfe, 0xff, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
915 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x02,
916 ];
917
918 let serialization_result_le = to_vec::<InterestingMessage, LittleEndian>(&value).unwrap();
919
920 assert_eq!(serialization_result_le, DATA);
921 info!("serialization success!");
922 let deserialization_result: InterestingMessage = deserialize_from_little_endian(DATA).unwrap();
923
924 info!("{:?}", deserialization_result);
925 }
926
927 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
928 enum SomeTupleEnum {
929 A(i32),
930 B(i32),
931 C(i32),
932 }
933
934 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
935 enum MixedEnum {
936 A(i32),
937 B { value: i32 },
938 C(i32, i32),
939 }
940
941 #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
942 #[repr(i8)]
943 pub enum GoalStatusEnum {
944 Unknown = 0, Accepted = 1,
946 Executing = 2,
947 Canceling = 3,
948 Succeeded = 4,
949 Canceled = 5,
950 Aborted = 6,
951 }
952
953 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
954 struct AlignMe {
955 some_bytes: [u8; 4],
956 status: i8,
957 }
958
959 #[test_case(35_u8 ; "u8")]
960 #[test_case(35_u16 ; "u16")]
961 #[test_case(352323_u32 ; "u32")]
962 #[test_case(352323232_u64 ; "u64")]
963 #[test_case(-3_i8 ; "i8")]
964 #[test_case(-3_i16 ; "i16")]
965 #[test_case(-323232_i32 ; "i32")]
966 #[test_case(-3232323434_i64 ; "i64")]
967 #[test_case(true)]
968 #[test_case(false)]
969 #[test_case(2.35_f32 ; "f32")]
970 #[test_case(278.35_f64 ; "f64")]
971 #[test_case('a' ; "char")]
972 #[test_case("BLUE".to_string() ; "string")]
973 #[test_case(vec![1_i32, -2_i32, 3_i32] ; "Vec<i32>")]
974 #[test_case(InterestingMessage {
975 unbounded_string: "Here is a fairly long text".to_string(),
976 x: 2,
977 y: -3,
978 shape_size: -4,
979 slide: 5.5,
980 double_slide: -6.6,
981 three_short: [1, 2, 3],
982 four_short: [1, -2, -3, 4],
983 booleans: vec![true, false, true],
984 three_bytes: [23, 0, 2].to_vec(),
985 } ; "InterestingMessage")]
986 #[test_case( BigEnum::Boring ; "BigEnum::Boring")]
987 #[test_case( BigEnum::Interesting(InterestingMessage {
988 unbounded_string: "Here is a fairly long text".to_string(),
989 x: 2,
990 y: -3,
991 shape_size: -4,
992 slide: 5.5,
993 double_slide: -6.6,
994 three_short: [1, 2, 3],
995 four_short: [1, -2, -3, 4],
996 booleans: vec![true, false, true],
997 three_bytes: [23, 0, 2].to_vec(),
998 }) ; "BigEnum::Interesting")]
999 #[test_case( BigEnum::Something{ x:123.0, y:-0.1 } ; "BigEnum::Something")]
1000 #[test_case( SomeTupleEnum::A(123) ; "SomeTupleEnum::A")]
1001 #[test_case( SomeTupleEnum::B(1234) ; "SomeTupleEnum::B")]
1002 #[test_case( SomeTupleEnum::C(-1) ; "SomeTupleEnum::C")]
1003 #[test_case( MixedEnum::A(123) ; "MixedEnum::A")]
1004 #[test_case( MixedEnum::B{ value:1234 } ; "MixedEnum::B")]
1005 #[test_case( MixedEnum::C(42,43) ; "MixedEnum::C")]
1006 #[test_case( GoalStatusEnum::Accepted ; "GoalStatusEnum::Accepted")]
1007 #[test_case( [AlignMe{some_bytes: [1,2,3,4], status:10 } ,
1008 AlignMe{some_bytes: [5,6,7,8], status:11 } ] ; "AlignMeArray")]
1009 fn cdr_serde_round_trip<T>(input: T)
1010 where
1011 T: PartialEq + std::fmt::Debug + Serialize + for<'a> Deserialize<'a>,
1012 {
1013 let serialized = to_vec::<_, LittleEndian>(&input).unwrap();
1014 println!("Serialized data: {:x?}", &serialized);
1015 let (deserialized, bytes_consumed): (T, usize) =
1016 from_bytes::<T, LittleEndian>(&serialized).unwrap();
1017 assert_eq!(input, deserialized);
1019 assert_eq!(serialized.len(), bytes_consumed);
1020 }
1021
1022 #[test]
1023 fn cdr_serde_round_trip_bytes() {
1024 let input: serde_bytes::ByteBuf = serde_bytes::ByteBuf::from(vec![1u8, 2, 3, 4, 5]);
1025 let serialized = to_vec::<_, LittleEndian>(&input).unwrap();
1026 assert_eq!(
1028 serialized,
1029 vec![0x05, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05]
1030 );
1031 let (deserialized, bytes_consumed): (serde_bytes::ByteBuf, usize) =
1032 from_bytes::<serde_bytes::ByteBuf, LittleEndian>(&serialized).unwrap();
1033 assert_eq!(input, deserialized);
1034 assert_eq!(serialized.len(), bytes_consumed);
1035 }
1036
1037 #[test]
1038 fn cdr_serde_round_trip_bytes_empty() {
1039 let input: serde_bytes::ByteBuf = serde_bytes::ByteBuf::from(vec![]);
1040 let serialized = to_vec::<_, LittleEndian>(&input).unwrap();
1041 assert_eq!(serialized, vec![0x00, 0x00, 0x00, 0x00]);
1043 let (deserialized, bytes_consumed): (serde_bytes::ByteBuf, usize) =
1044 from_bytes::<serde_bytes::ByteBuf, LittleEndian>(&serialized).unwrap();
1045 assert_eq!(input, deserialized);
1046 assert_eq!(serialized.len(), bytes_consumed);
1047 }
1048
1049 #[test]
1050 fn cdr_serde_round_trip_borrowed_bytes() {
1051 let raw = vec![0x03, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC];
1053 let (deserialized, bytes_consumed): (&serde_bytes::Bytes, usize) =
1054 from_bytes::<&serde_bytes::Bytes, LittleEndian>(&raw).unwrap();
1055 assert_eq!(deserialized.as_ref(), &[0xAA, 0xBB, 0xCC]);
1056 assert_eq!(bytes_consumed, 7);
1057 }
1058
1059 #[test]
1060 fn cdr_serde_round_trip_bytes_in_struct() {
1061 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
1062 struct WithBytes {
1063 id: u32,
1064 #[serde(with = "serde_bytes")]
1065 payload: Vec<u8>,
1066 tag: u8,
1067 }
1068
1069 let input = WithBytes {
1070 id: 42,
1071 payload: vec![0xDE, 0xAD, 0xBE, 0xEF],
1072 tag: 7,
1073 };
1074 let serialized = to_vec::<_, LittleEndian>(&input).unwrap();
1075 let (deserialized, bytes_consumed): (WithBytes, usize) =
1076 from_bytes::<WithBytes, LittleEndian>(&serialized).unwrap();
1077 assert_eq!(input, deserialized);
1078 assert_eq!(serialized.len(), bytes_consumed);
1079 }
1080
1081 #[test]
1082 fn cdr_serde_vec_u8_still_works_via_seq() {
1083 let input: Vec<u8> = vec![10, 20, 30];
1086 let serialized = to_vec::<_, LittleEndian>(&input).unwrap();
1087 let (deserialized, bytes_consumed): (Vec<u8>, usize) =
1088 from_bytes::<Vec<u8>, LittleEndian>(&serialized).unwrap();
1089 assert_eq!(input, deserialized);
1090 assert_eq!(serialized.len(), bytes_consumed);
1091 }
1092
1093 #[test]
1094 fn cdr_serde_seq_serialized_bytes_deserializable_via_bytes_path() {
1095 let input: Vec<u8> = vec![0xDE, 0xAD, 0xBE, 0xEF];
1097 let serialized = to_vec::<_, LittleEndian>(&input).unwrap();
1098 let (deserialized, bytes_consumed): (serde_bytes::ByteBuf, usize) =
1099 from_bytes::<serde_bytes::ByteBuf, LittleEndian>(&serialized).unwrap();
1100 assert_eq!(input, deserialized.as_ref());
1101 assert_eq!(serialized.len(), bytes_consumed);
1102 }
1103}