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 paste::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<&[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: &[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: &[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 BO: ByteOrder,
142{
143 type Error = Error;
144
145 fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
149 where
150 V: Visitor<'de>,
151 {
152 Err(Error::NotSelfDescribingFormat(
153 "CDR cannot deserialize \"any\" type. ".to_string(),
154 ))
155 }
156
157 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
161 where
162 V: Visitor<'de>,
163 {
164 match self.next_bytes(1)?.first().unwrap() {
165 0 => visitor.visit_bool(false),
166 1 => visitor.visit_bool(true),
167 x => Err(Error::BadBoolean(*x)),
168 }
169 }
170
171 deserialize_multibyte_number!(i16);
172 deserialize_multibyte_number!(i32);
173 deserialize_multibyte_number!(i64);
174
175 deserialize_multibyte_number!(u16);
176 deserialize_multibyte_number!(u32);
177 deserialize_multibyte_number!(u64);
178
179 deserialize_multibyte_number!(f32);
180 deserialize_multibyte_number!(f64);
181
182 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
184 where
185 V: Visitor<'de>,
186 {
187 visitor.visit_i8(self.next_bytes(1)?.read_i8().unwrap())
188 }
189
190 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
191 where
192 V: Visitor<'de>,
193 {
194 visitor.visit_u8(self.next_bytes(1)?.read_u8().unwrap())
195 }
196
197 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
199 where
200 V: Visitor<'de>,
201 {
202 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
203 let codepoint = self.next_bytes(4)?.read_u32::<BO>().unwrap();
204 match char::from_u32(codepoint) {
205 Some(c) => visitor.visit_char(c),
206 None => Err(Error::BadChar(codepoint)),
207 }
208 }
209
210 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
211 where
212 V: Visitor<'de>,
213 {
214 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
216 let bytes_len = self.next_bytes(4)?.read_u32::<BO>().unwrap() as usize;
217
218 let bytes = self.next_bytes(bytes_len)?; let bytes_without_null = match bytes.split_last() {
222 None => {
223 info!("deserialize_str: Received string with not even a null terminator.");
226 bytes
227 }
228 Some((null_char, contents)) => {
229 if *null_char != 0 {
230 warn!(
231 "deserialize_str: Expected string null terminator, got {:#x} instead.",
232 null_char
233 );
234 }
235 contents
236 }
237 };
238
239 std::str::from_utf8(bytes_without_null)
241 .map_err(Error::BadUTF8)
242 .and_then(|s| visitor.visit_str(s))
243
244 }
249
250 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
251 where
252 V: Visitor<'de>,
253 {
254 self.deserialize_str(visitor)
255 }
256
257 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
260 where
261 V: Visitor<'de>,
262 {
263 self.deserialize_seq(visitor)
264 }
265
266 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
267 where
268 V: Visitor<'de>,
269 {
270 self.deserialize_seq(visitor)
271 }
272
273 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
274 where
275 V: Visitor<'de>,
276 {
277 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
278 let enum_tag = self.next_bytes(4)?.read_u32::<BO>().unwrap();
279 match enum_tag {
280 0 => visitor.visit_none(),
281 1 => visitor.visit_some(self),
282 wtf => Err(Error::BadOption(wtf)),
283 }
284 }
285
286 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
287 where
288 V: Visitor<'de>,
289 {
290 visitor.visit_unit()
292 }
293
294 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
295 where
296 V: Visitor<'de>,
297 {
298 self.deserialize_unit(visitor) }
301
302 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
303 where
304 V: Visitor<'de>,
305 {
306 visitor.visit_newtype_struct(self)
307 }
308
309 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
315 where
316 V: Visitor<'de>,
317 {
318 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
319 let element_count = self.next_bytes(4)?.read_u32::<BO>().unwrap() as usize;
320 visitor.visit_seq(SequenceHelper::new(self, element_count))
321 }
322
323 fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
325 where
326 V: Visitor<'de>,
327 {
328 visitor.visit_seq(SequenceHelper::new(self, len))
329 }
330
331 fn deserialize_tuple_struct<V>(
332 self,
333 _name: &'static str,
334 len: usize,
335 visitor: V,
336 ) -> Result<V::Value>
337 where
338 V: Visitor<'de>,
339 {
340 visitor.visit_seq(SequenceHelper::new(self, len))
341 }
342
343 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
344 where
345 V: Visitor<'de>,
346 {
347 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
348 let element_count = self.next_bytes(4)?.read_u32::<BO>().unwrap() as usize;
349 visitor.visit_map(SequenceHelper::new(self, element_count))
350 }
351
352 fn deserialize_struct<V>(
353 self,
354 _name: &'static str,
355 fields: &'static [&'static str],
356 visitor: V,
357 ) -> Result<V::Value>
358 where
359 V: Visitor<'de>,
360 {
361 visitor.visit_seq(SequenceHelper::new(self, fields.len()))
362 }
363
364 fn deserialize_enum<V>(
371 self,
372 _name: &'static str,
373 _variants: &'static [&'static str],
374 visitor: V,
375 ) -> Result<V::Value>
376 where
377 V: Visitor<'de>,
378 {
379 self.calculate_padding_count_from_written_bytes_and_remove(4)?;
380 visitor.visit_enum(EnumerationHelper::<BO>::new(self))
381 }
382
383 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
388 where
389 V: Visitor<'de>,
390 {
391 self.deserialize_u32(visitor)
392 }
393
394 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
395 where
396 V: Visitor<'de>,
397 {
398 self.deserialize_any(visitor)
399 }
400
401 fn is_human_readable(&self) -> bool {
402 false
403 }
404}
405
406struct EnumerationHelper<'a, 'i: 'a, BO> {
409 de: &'a mut CdrDeserializer<'i, BO>,
410}
411
412impl<'a, 'i, BO> EnumerationHelper<'a, 'i, BO>
413where
414 BO: ByteOrder,
415{
416 fn new(de: &'a mut CdrDeserializer<'i, BO>) -> Self {
417 EnumerationHelper::<BO> { de }
418 }
419}
420
421impl<'de, 'a, BO> EnumAccess<'de> for EnumerationHelper<'a, '_, BO>
422where
423 BO: ByteOrder,
424{
425 type Error = Error;
426 type Variant = Self;
427
428 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
429 where
430 V: DeserializeSeed<'de>,
431 {
432 let enum_tag = self.de.next_bytes(4)?.read_u32::<BO>().unwrap();
434 let val: Result<_> = seed.deserialize(enum_tag.into_deserializer());
435 Ok((val?, self))
436 }
437}
438
439impl<'de, 'a, BO> VariantAccess<'de> for EnumerationHelper<'a, '_, BO>
442where
443 BO: ByteOrder,
444{
445 type Error = Error;
446
447 fn unit_variant(self) -> Result<()> {
448 Ok(())
449 }
450
451 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
452 where
453 T: DeserializeSeed<'de>,
454 {
455 seed.deserialize(self.de)
456 }
457
458 fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value>
459 where
460 V: Visitor<'de>,
461 {
462 de::Deserializer::deserialize_tuple(self.de, len, visitor)
463 }
464
465 fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
466 where
467 V: Visitor<'de>,
468 {
469 de::Deserializer::deserialize_tuple(self.de, fields.len(), visitor)
470 }
471}
472
473struct SequenceHelper<'a, 'i: 'a, BO> {
476 de: &'a mut CdrDeserializer<'i, BO>,
477 element_counter: usize,
478 expected_count: usize,
479}
480
481impl<'a, 'i, BO> SequenceHelper<'a, 'i, BO> {
482 fn new(de: &'a mut CdrDeserializer<'i, BO>, expected_count: usize) -> Self {
483 SequenceHelper {
484 de,
485 element_counter: 0,
486 expected_count,
487 }
488 }
489}
490
491impl<'a, 'de, BO> SeqAccess<'de> for SequenceHelper<'a, '_, BO>
494where
495 BO: ByteOrder,
496{
497 type Error = Error;
498
499 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
500 where
501 T: DeserializeSeed<'de>,
502 {
503 if self.element_counter == self.expected_count {
504 Ok(None)
505 } else {
506 self.element_counter += 1;
507 seed.deserialize(&mut *self.de).map(Some)
508 }
509 }
510}
511
512impl<'de, 'a, BO> MapAccess<'de> for SequenceHelper<'a, '_, BO>
515where
516 BO: ByteOrder,
517{
518 type Error = Error;
519
520 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
521 where
522 K: DeserializeSeed<'de>,
523 {
524 if self.element_counter == self.expected_count {
525 Ok(None)
526 } else {
527 self.element_counter += 1;
528 seed.deserialize(&mut *self.de).map(Some)
529 }
530 }
531
532 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
533 where
534 V: DeserializeSeed<'de>,
535 {
536 seed.deserialize(&mut *self.de)
538 }
539}
540
541#[cfg(test)]
542#[allow(clippy::needless_pass_by_value)]
543mod tests {
544 use byteorder::{BigEndian, LittleEndian};
545 use log::info;
546 use serde::{Deserialize, Serialize};
547 use serde_repr::{Deserialize_repr, Serialize_repr};
548 use test_case::test_case;
549
550 use crate::{
551 cdr_deserializer::{deserialize_from_big_endian, deserialize_from_little_endian},
552 cdr_serializer::to_vec,
553 from_bytes,
554 };
555
556 #[test]
557 fn cdr_deserialization_struct() {
558 #[derive(Serialize, Deserialize, Debug, PartialEq)]
596 struct MyType {
597 first_value: u8,
598 second_value: i8,
599 third_value: i32,
600 fourth_value: u64,
601 fifth: bool,
602 sixth: f32,
603 seventh: bool,
604 eighth: Vec<i32>,
605 ninth: Vec<u8>,
606 tenth: Vec<i16>,
607 eleventh: Vec<i64>,
608 twelve: [u16; 3],
609 thirteen: String,
610 }
611
612 let micky_mouse = MyType {
613 first_value: 1,
614 second_value: -3,
615 third_value: -5000,
616 fourth_value: 1234u64,
617 fifth: true,
618 sixth: -6.6f32,
619 seventh: true,
620 eighth: vec![1, 2],
621 ninth: vec![1],
622 tenth: vec![5, -4, 3, -2, 1],
623 eleventh: vec![],
624 twelve: [3, 2, 1],
625 thirteen: "abc".to_string(),
626 };
627
628 let expected_serialized_result: Vec<u8> = vec![
629 0x01, 0xfd, 0x00, 0x00, 0x78, 0xec, 0xff, 0xff, 0xd2, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x01, 0x00, 0x00, 0x00, 0x33, 0x33, 0xd3, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
631 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
632 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfe, 0xff,
633 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00,
634 0x00, 0x04, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x00,
635 ];
636
637 let serialized = to_vec::<MyType, LittleEndian>(&micky_mouse).unwrap();
638
639 for x in 0..expected_serialized_result.len() {
640 if expected_serialized_result[x] != serialized[x] {
641 info!("index: {}", x);
642 }
643 }
644 assert_eq!(serialized, expected_serialized_result);
645 info!("serialization successful!");
646
647 let built: MyType = deserialize_from_little_endian(&expected_serialized_result).unwrap();
648 assert_eq!(built, micky_mouse);
649 info!("deserialized: {:?}", built);
650 }
651
652 #[test]
653
654 fn cdr_deserialization_user_defined_data() {
655 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
658 struct ShapeType {
659 color: String,
660 x: i32,
661 y: i32,
662 size: i32,
663 }
664
665 let message = ShapeType {
666 color: "BLUE".to_string(),
667 x: 34,
668 y: 100,
669 size: 24,
670 };
671
672 let expected_serialized_result: Vec<u8> = vec![
673 0x05, 0x00, 0x00, 0x00, 0x42, 0x4c, 0x55, 0x45, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
674 0x00, 0x64, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
675 ];
676
677 let serialized = to_vec::<ShapeType, LittleEndian>(&message).unwrap();
678 assert_eq!(serialized, expected_serialized_result);
679 let deserialized_message: ShapeType = deserialize_from_little_endian(&serialized).unwrap();
680 assert_eq!(deserialized_message, message);
681 }
682
683 #[test]
684
685 fn cdr_deserialization_serialization_topic_name() {
686 let received_cdr_string: Vec<u8> = vec![
692 0x07, 0x00, 0x00, 0x00, 0x053, 0x71, 0x75, 0x61, 0x72, 0x65, 0x00, ];
694
695 let deserialized_message: String =
696 deserialize_from_little_endian(&received_cdr_string).unwrap();
697 info!("{:?}", deserialized_message);
698 assert_eq!("Square", deserialized_message);
699
700 let received_cdr_string2: Vec<u8> = vec![
701 0x0A, 0x00, 0x00, 0x00, 0x53, 0x68, 0x61, 0x70, 0x65, 0x54, 0x79, 0x70, 0x65,
702 0x00, ];
704
705 let deserialized_message2: String =
706 deserialize_from_little_endian(&received_cdr_string2).unwrap();
707 info!("{:?}", deserialized_message2);
708 assert_eq!("ShapeType", deserialized_message2);
709 }
710
711 #[test]
712 fn cdr_deserialization_example_struct() {
713 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
717 struct Example {
718 a: u32,
719 b: [u8; 4],
720 }
721
722 let o = Example {
723 a: 1,
724 b: [b'a', b'b', b'c', b'd'],
725 };
726
727 let serialized_le: Vec<u8> = vec![0x01, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64];
728
729 let serialized_be: Vec<u8> = vec![0x00, 0x00, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64];
730
731 let deserialized_le: Example = deserialize_from_little_endian(&serialized_le).unwrap();
732 let deserialized_be: Example = deserialize_from_big_endian(&serialized_be).unwrap();
733 let serialized_o_le = to_vec::<Example, LittleEndian>(&o).unwrap();
734 let serialized_o_be = to_vec::<Example, BigEndian>(&o).unwrap();
735
736 assert_eq!(
737 serialized_o_le,
738 vec![0x01, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64,]
739 );
740
741 assert_eq!(
742 serialized_o_be,
743 vec![0x00, 0x00, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64,]
744 );
745
746 info!("serialization success");
747
748 assert_eq!(deserialized_le, o);
749 assert_eq!(deserialized_be, o);
750 info!("deserialization success");
751 }
752
753 #[test]
754
755 fn cdr_deserialization_serialization_payload_shapes() {
756 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
759 struct ShapeType {
760 color: String,
761 x: i32,
762 y: i32,
763 size: i32,
764 }
765 let received_message: Vec<u8> = vec![
768 0x04, 0x00, 0x00, 0x00, 0x52, 0x45, 0x44, 0x00, 0x61, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00,
769 0x00, 0x1e, 0x00, 0x00, 0x00,
770 ];
771 let received_message2: Vec<u8> = vec![
772 0x04, 0x00, 0x00, 0x00, 0x52, 0x45, 0x44, 0x00, 0x61, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00,
773 0x00, 0x1e, 0x00, 0x00, 0x00,
774 ];
775
776 let deserialized_message: ShapeType =
777 deserialize_from_little_endian(&received_message).unwrap();
778 info!("{:?}", deserialized_message);
779
780 let serialized_message = to_vec::<ShapeType, LittleEndian>(&deserialized_message).unwrap();
781
782 assert_eq!(serialized_message, received_message2);
783 }
785
786 #[test]
787
788 fn cdr_deserialization_custom_data_message_from_ros_and_wireshark() {
789 #[derive(Serialize, Deserialize, Debug, PartialEq)]
799 struct MessageType {
800 x: f64,
801 y: f64,
802 heading: f64,
803 v_x: f64,
804 v_y: f64,
805 kappa: f64,
806 test: String,
807 }
808
809 let received_message_le: Vec<u8> = vec![
811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
813 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x85, 0xeb, 0x51, 0xb8,
814 0x1e, 0xd5, 0x3f, 0x0a, 0x00, 0x00, 0x00, 0x54, 0x6f, 0x69, 0x6d, 0x69, 0x69, 0x6b, 0x6f,
815 0x3f, 0x00, ];
817
818 let value: MessageType = deserialize_from_little_endian(&received_message_le).unwrap();
819 info!("{:?}", value);
820 assert_eq!(value.test, "Toimiiko?");
821 }
822
823 #[derive(Serialize, Deserialize, Debug, PartialEq)]
824 struct InterestingMessage {
825 unbounded_string: String,
826 x: i32,
827 y: i32,
828 shape_size: i32,
829 slide: f32,
830 double_slide: f64,
831 three_short: [u16; 3],
832 four_short: [i16; 4],
833 booleans: Vec<bool>,
834 three_bytes: Vec<u8>,
835 }
836
837 #[derive(Serialize, Deserialize, Debug, PartialEq)]
838 enum BigEnum {
839 Interesting(InterestingMessage),
840 Boring,
841 Something { x: f32, y: f32 },
842 }
843
844 #[test]
845 fn cdr_deserialization_custom_type() {
846 let value = InterestingMessage {
880 unbounded_string: "Tassa on aika pitka teksti".to_string(), x: 2,
883 y: -3,
884 shape_size: -4,
885 slide: 5.5,
886 double_slide: -6.6,
887 three_short: [1, 2, 3],
888 four_short: [1, -2, -3, 4],
889 booleans: vec![true, false, true],
890 three_bytes: [23, 0, 2].to_vec(),
891 };
892
893 const DATA: &[u8] = &[
894 0x1b, 0x00, 0x00, 0x00, 0x54, 0x61, 0x73, 0x73, 0x61, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x69,
895 0x6b, 0x61, 0x20, 0x70, 0x69, 0x74, 0x6b, 0x61, 0x20, 0x74, 0x65, 0x6b, 0x73, 0x74, 0x69,
896 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x00,
897 0x00, 0xb0, 0x40, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x1a, 0xc0, 0x01, 0x00, 0x02, 0x00,
898 0x03, 0x00, 0x01, 0x00, 0xfe, 0xff, 0xfd, 0xff, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
899 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x02,
900 ];
901
902 let serialization_result_le = to_vec::<InterestingMessage, LittleEndian>(&value).unwrap();
903
904 assert_eq!(serialization_result_le, DATA);
905 info!("serialization success!");
906 let deserialization_result: InterestingMessage = deserialize_from_little_endian(DATA).unwrap();
907
908 info!("{:?}", deserialization_result);
909 }
910
911 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
912 enum SomeTupleEnum {
913 A(i32),
914 B(i32),
915 C(i32),
916 }
917
918 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
919 enum MixedEnum {
920 A(i32),
921 B { value: i32 },
922 C(i32, i32),
923 }
924
925 #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
926 #[repr(i8)]
927 pub enum GoalStatusEnum {
928 Unknown = 0, Accepted = 1,
930 Executing = 2,
931 Canceling = 3,
932 Succeeded = 4,
933 Canceled = 5,
934 Aborted = 6,
935 }
936
937 #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
938 struct AlignMe {
939 some_bytes: [u8; 4],
940 status: i8,
941 }
942
943 #[test_case(35_u8 ; "u8")]
944 #[test_case(35_u16 ; "u16")]
945 #[test_case(352323_u32 ; "u32")]
946 #[test_case(352323232_u64 ; "u64")]
947 #[test_case(-3_i8 ; "i8")]
948 #[test_case(-3_i16 ; "i16")]
949 #[test_case(-323232_i32 ; "i32")]
950 #[test_case(-3232323434_i64 ; "i64")]
951 #[test_case(true)]
952 #[test_case(false)]
953 #[test_case(2.35_f32 ; "f32")]
954 #[test_case(278.35_f64 ; "f64")]
955 #[test_case('a' ; "char")]
956 #[test_case("BLUE".to_string() ; "string")]
957 #[test_case(vec![1_i32, -2_i32, 3_i32] ; "Vec<i32>")]
958 #[test_case(InterestingMessage {
959 unbounded_string: "Here is a fairly long text".to_string(),
960 x: 2,
961 y: -3,
962 shape_size: -4,
963 slide: 5.5,
964 double_slide: -6.6,
965 three_short: [1, 2, 3],
966 four_short: [1, -2, -3, 4],
967 booleans: vec![true, false, true],
968 three_bytes: [23, 0, 2].to_vec(),
969 } ; "InterestingMessage")]
970 #[test_case( BigEnum::Boring ; "BigEnum::Boring")]
971 #[test_case( BigEnum::Interesting(InterestingMessage {
972 unbounded_string: "Here is a fairly long text".to_string(),
973 x: 2,
974 y: -3,
975 shape_size: -4,
976 slide: 5.5,
977 double_slide: -6.6,
978 three_short: [1, 2, 3],
979 four_short: [1, -2, -3, 4],
980 booleans: vec![true, false, true],
981 three_bytes: [23, 0, 2].to_vec(),
982 }) ; "BigEnum::Interesting")]
983 #[test_case( BigEnum::Something{ x:123.0, y:-0.1 } ; "BigEnum::Something")]
984 #[test_case( SomeTupleEnum::A(123) ; "SomeTupleEnum::A")]
985 #[test_case( SomeTupleEnum::B(1234) ; "SomeTupleEnum::B")]
986 #[test_case( SomeTupleEnum::C(-1) ; "SomeTupleEnum::C")]
987 #[test_case( MixedEnum::A(123) ; "MixedEnum::A")]
988 #[test_case( MixedEnum::B{ value:1234 } ; "MixedEnum::B")]
989 #[test_case( MixedEnum::C(42,43) ; "MixedEnum::C")]
990 #[test_case( GoalStatusEnum::Accepted ; "GoalStatusEnum::Accepted")]
991 #[test_case( [AlignMe{some_bytes: [1,2,3,4], status:10 } ,
992 AlignMe{some_bytes: [5,6,7,8], status:11 } ] ; "AlignMeArray")]
993 fn cdr_serde_round_trip<T>(input: T)
994 where
995 T: PartialEq + std::fmt::Debug + Serialize + for<'a> Deserialize<'a>,
996 {
997 let serialized = to_vec::<_, LittleEndian>(&input).unwrap();
998 println!("Serialized data: {:x?}", &serialized);
999 let (deserialized, bytes_consumed): (T, usize) =
1000 from_bytes::<T, LittleEndian>(&serialized).unwrap();
1001 assert_eq!(input, deserialized);
1003 assert_eq!(serialized.len(), bytes_consumed);
1004 }
1005
1006 }