cdr_encoding/
cdr_serializer.rs

1//! OMG Common Data Representation (CDR) serialization with [Serde](https://serde.rs/)
2//!
3//!
4//!
5//! Note: In CDR encoding, alignment padding bytes are inserted *before* a
6//! multibyte primitive, but not after.
7//!
8//!  e.g. `struct Example {
9//!   a: u8,
10//!   b: i32,
11//!   c: u16,
12//! }`
13//!
14//! Would be serialized as
15//! `
16//! |aa|PP|PP|PP|
17//! |bb|bb|bb|bb|
18//! |cc|cc|
19//! `
20//! which is 10 bytes. `PP` means a byte of padding data.
21//!
22//! Tuple type  `(Example,Example)` would be serialized as
23//! `
24//! |aa|PP|PP|PP|
25//! |bb|bb|bb|bb|
26//! |cc|cc|aa|PP|
27//! |bb|bb|bb|bb|
28//! |cc|cc|
29//! `
30//! Note that this is only 18 bytes, not 20, and the layout of the second
31//! struct is different due to different padding.
32
33use std::{io, io::Write, marker::PhantomData};
34
35#[cfg(test)]
36use byteorder::{BigEndian, LittleEndian};
37use byteorder::{ByteOrder, WriteBytesExt};
38use serde::{ser, Serialize};
39
40pub use super::error::{Error, Result};
41
42// CountingWrite is a wrapper for a Write object. The wrapper keeps count of
43// bytes written. CDR needs to count bytes, because multibyte primitive types '
44// (such as integers and floats) must be aligned to their size, i.e. 2, 4, or 8
45// bytes.
46struct CountingWrite<W: io::Write> {
47  writer: W,
48  bytes_written: usize,
49}
50
51impl<W> CountingWrite<W>
52where
53  W: io::Write,
54{
55  pub fn new(w: W) -> Self {
56    Self {
57      writer: w,
58      bytes_written: 0,
59    }
60  }
61  pub fn count(&self) -> usize {
62    self.bytes_written
63  }
64}
65
66impl<W> io::Write for CountingWrite<W>
67where
68  W: io::Write,
69{
70  fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
71    match self.writer.write(buf) {
72      Ok(c) => {
73        self.bytes_written += c;
74        Ok(c)
75      }
76      e => e,
77    }
78  }
79  fn flush(&mut self) -> io::Result<()> {
80    self.writer.flush()
81  }
82}
83
84// ---------------------------------------------------------------------------------
85// ---------------------------------------------------------------------------------
86
87// ---------------------------------------------------------------------------------
88// ---------------------------------------------------------------------------------
89
90/// a CDR serializer implementation
91///
92/// Parameter W is an [`io::Write`] that would receive the serialization.
93///
94/// Parameter BO is byte order: [`LittleEndian`](byteorder::LittleEndian) or
95/// [`BigEndian`](byteorder::BigEndian)
96pub struct CdrSerializer<W, BO>
97where
98  W: io::Write,
99{
100  writer: CountingWrite<W>, // serialization destination
101  phantom: PhantomData<BO>, // This field exists only to provide use for BO. See PhantomData docs.
102}
103
104impl<W, BO> CdrSerializer<W, BO>
105where
106  BO: ByteOrder,
107  W: io::Write,
108{
109  pub fn new(w: W) -> Self {
110    Self {
111      writer: CountingWrite::new(w),
112      phantom: PhantomData,
113    }
114  }
115
116  fn calculate_padding_need_and_write_padding(&mut self, alignment: usize) -> Result<()> {
117    let modulo = self.writer.count() % alignment;
118    if modulo != 0 {
119      let padding_need: usize = alignment - modulo;
120      for _x in 0..padding_need {
121        self.writer.write_u8(0)?;
122      }
123    }
124    Ok(())
125  }
126} // impl
127
128/// General CDR serialization for type `T:Serialize`
129///
130/// Takes ownership of the `writer`, but that can be a reference.
131///
132/// You need to specifiy the byte order (endianness) to use. In CDR, endianess
133/// cannot be detected from serialized stream, but has to be agreed out-of-band.
134pub fn to_writer<T, BO, W>(writer: W, value: &T) -> Result<()>
135where
136  T: Serialize,
137  BO: ByteOrder,
138  W: io::Write,
139{
140  value.serialize(&mut CdrSerializer::<W, BO>::new(writer))
141}
142
143/// Serialize to `Vec<u8>`
144/// Size hint indicates how many bytes to initially allocate for serialized
145/// data.
146pub fn to_vec_with_size_hint<T, BO>(value: &T, capacity_hint: usize) -> Result<Vec<u8>>
147where
148  T: Serialize,
149  BO: ByteOrder,
150{
151  let mut buffer: Vec<u8> = Vec::with_capacity(capacity_hint);
152  to_writer::<T, BO, &mut Vec<u8>>(&mut buffer, value)?;
153  Ok(buffer)
154}
155
156/// Serialize to `Vec<u8>`
157pub fn to_vec<T, BO>(value: &T) -> Result<Vec<u8>>
158where
159  T: Serialize,
160  BO: ByteOrder,
161{
162  to_vec_with_size_hint::<T, BO>(value, std::mem::size_of_val(value) * 2)
163}
164
165// just testing
166#[cfg(test)]
167pub(crate) fn to_little_endian_binary<T>(value: &T) -> Result<Vec<u8>>
168where
169  T: Serialize,
170{
171  to_vec::<T, LittleEndian>(value)
172}
173
174#[cfg(test)]
175fn to_big_endian_binary<T>(value: &T) -> Result<Vec<u8>>
176where
177  T: Serialize,
178{
179  to_vec::<T, BigEndian>(value)
180}
181
182// ----------------------------------------------------------
183// ----------------------------------------------------------
184// ----------------------------------------------------------
185// ----------------------------------------------------------
186// ----------------------------------------------------------
187
188impl<'a, W, BO> ser::Serializer for &'a mut CdrSerializer<W, BO>
189where
190  BO: ByteOrder,
191  W: io::Write,
192{
193  type Ok = ();
194  // The error type when some error occurs during serialization.
195  type Error = Error;
196
197  // Associated types for keeping track of additional state while serializing
198  // compound data structures like sequences and maps. In this case no
199  // additional state is required beyond what is already stored in the
200  // Serializer struct.
201  type SerializeSeq = Self;
202  type SerializeTuple = Self;
203  type SerializeTupleStruct = Self;
204  type SerializeTupleVariant = Self;
205  type SerializeMap = Self;
206  type SerializeStruct = Self;
207  type SerializeStructVariant = Self;
208
209  // Little-Endian encoding least significant bit is first.
210
211  // 15.3.1.5 Boolean
212  //  Boolean values are encoded as single octets, where TRUE is the value 1, and
213  // FALSE as 0.
214  fn serialize_bool(self, v: bool) -> Result<()> {
215    if v {
216      self.writer.write_u8(1u8)?;
217    } else {
218      self.writer.write_u8(0u8)?;
219    }
220    Ok(())
221  }
222
223  // Figure 15-1 on page 15-7 illustrates the representations for OMG IDL integer
224  // data types, including the following data types:
225  // short
226  // unsigned short
227  // long
228  // unsigned long
229  // long long
230  // unsigned long long
231
232  fn serialize_u8(self, v: u8) -> Result<()> {
233    self.writer.write_u8(v)?;
234    Ok(())
235  }
236
237  fn serialize_u16(self, v: u16) -> Result<()> {
238    self.calculate_padding_need_and_write_padding(2)?;
239    self.writer.write_u16::<BO>(v)?;
240    Ok(())
241  }
242
243  fn serialize_u32(self, v: u32) -> Result<()> {
244    self.calculate_padding_need_and_write_padding(4)?;
245    self.writer.write_u32::<BO>(v)?;
246    Ok(())
247  }
248
249  fn serialize_u64(self, v: u64) -> Result<()> {
250    self.calculate_padding_need_and_write_padding(8)?;
251    self.writer.write_u64::<BO>(v)?;
252    Ok(())
253  }
254
255  fn serialize_u128(self, v: u128) -> Result<()> {
256    self.calculate_padding_need_and_write_padding(16)?;
257    self.writer.write_u128::<BO>(v)?;
258    Ok(())
259  }
260
261  fn serialize_i8(self, v: i8) -> Result<()> {
262    self.writer.write_i8(v)?;
263    Ok(())
264  }
265
266  fn serialize_i16(self, v: i16) -> Result<()> {
267    self.calculate_padding_need_and_write_padding(2)?;
268    self.writer.write_i16::<BO>(v)?;
269    Ok(())
270  }
271
272  fn serialize_i32(self, v: i32) -> Result<()> {
273    self.calculate_padding_need_and_write_padding(4)?;
274    self.writer.write_i32::<BO>(v)?;
275    Ok(())
276  }
277
278  fn serialize_i64(self, v: i64) -> Result<()> {
279    self.calculate_padding_need_and_write_padding(8)?;
280    self.writer.write_i64::<BO>(v)?;
281    Ok(())
282  }
283
284  fn serialize_f32(self, v: f32) -> Result<()> {
285    self.calculate_padding_need_and_write_padding(4)?;
286    self.writer.write_f32::<BO>(v)?;
287    Ok(())
288  }
289  fn serialize_f64(self, v: f64) -> Result<()> {
290    self.calculate_padding_need_and_write_padding(8)?;
291    self.writer.write_f64::<BO>(v)?;
292    Ok(())
293  }
294
295  // An IDL character is represented as a single octet; the code set used for
296  // transmission of character data (e.g., TCS-C) between a particular client
297  // and server ORBs is determined via the process described in Section 13.10,
298  // “Code Set Conversion,”
299  fn serialize_char(self, v: char) -> Result<()> {
300    // Rust "char" means a 32-bit Unicode code point.
301    // IDL & CDR "char" means an octet.
302    // We are here actually serializing the 32-bit quantity.
303    // If we want to serialize CDR "char", then the corresponding Rust type is "u8".
304    self.serialize_u32(v as u32)?;
305    Ok(())
306  }
307
308  // A string is encoded as an unsigned long indicating the length of the string
309  // in octets, followed by the string value in single- or multi-byte form
310  // represented as a sequence of octets. The string contents include a single
311  // terminating null character. The string length includes the null character,
312  // so an empty string has a length of 1.
313  fn serialize_str(self, v: &str) -> Result<()> {
314    let byte_count: u32 = v.as_bytes().len() as u32 + 1;
315    self.serialize_u32(byte_count)?; // +1 for terminator
316    self.writer.write_all(v.as_bytes())?;
317    self.writer.write_u8(0)?; // CDR spec requires a null terminator
318    Ok(())
319    // The end result is not UTF-8-encoded string, but how could we do better in
320    // CDR?
321  }
322
323  fn serialize_bytes(self, v: &[u8]) -> Result<()> {
324    self.writer.write_all(v)?;
325    Ok(())
326  }
327
328  fn serialize_none(self) -> Result<()> {
329    self.serialize_u32(0) // None is the first variant
330  }
331
332  fn serialize_some<T>(self, t: &T) -> Result<()>
333  where
334    T: ?Sized + Serialize,
335  {
336    self.serialize_u32(1)?; // Some is the second variant
337    t.serialize(self)?;
338    Ok(())
339  }
340
341  // Unit contains no data, but the CDR spec has no concept of types that carry no
342  // data. We decide to serialize this as nothing.
343  fn serialize_unit(self) -> Result<()> {
344    // nothing
345    Ok(())
346  }
347
348  fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
349    self.serialize_unit()
350  }
351
352  // CDR 15.3.2.6:
353  // Enum values are encoded as unsigned longs. The numeric values associated with
354  // enum identifiers are determined by the order in which the identifiers
355  // appear in the enum declaration. The first enum identifier has the numeric
356  // value zero (0). Successive enum identifiers take ascending numeric values,
357  // in order of declaration from left to right.
358  fn serialize_unit_variant(
359    self,
360    _name: &'static str,
361    variant_index: u32,
362    _variant: &'static str,
363  ) -> Result<()> {
364    self.serialize_u32(variant_index)
365  }
366
367  // In CDR, this would be a special case of struct.
368  fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
369  where
370    T: ?Sized + Serialize,
371  {
372    value.serialize(self)
373  }
374
375  fn serialize_newtype_variant<T>(
376    self,
377    _name: &'static str,
378    variant_index: u32,
379    _variant: &'static str,
380    value: &T,
381  ) -> Result<()>
382  where
383    T: ?Sized + Serialize,
384  {
385    self.serialize_u32(variant_index)?;
386    value.serialize(self)
387  }
388
389  // Sequences are encoded as an unsigned long value, followed by the elements of
390  // the sequence. The initial unsigned long contains the number of elements in
391  // the sequence. The elements of the sequence are encoded as specified for
392  // their type.
393  //
394  // Serde calls this to start sequence. Then it calls serialize_element() for
395  // each element, and finally calls end().
396  fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
397    match len {
398      None => Err(Error::SequenceLengthUnknown),
399      Some(elem_count) => {
400        self.serialize_u32(elem_count as u32)?;
401        Ok(self)
402      }
403    } // match
404  } // fn
405
406  // if CDR contains fixed length array then number of elements is not written.
407  fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
408    // nothing to be done here
409    Ok(self)
410  }
411
412  fn serialize_tuple_struct(
413    self,
414    _name: &'static str,
415    _len: usize,
416  ) -> Result<Self::SerializeTupleStruct> {
417    // (tuple) struct length is not written. Nothing to be done.
418    Ok(self)
419  }
420
421  // This is technically enum/union, so write the variant index.
422  fn serialize_tuple_variant(
423    self,
424    _name: &'static str,
425    variant_index: u32,
426    _variant: &'static str,
427    _len: usize,
428  ) -> Result<Self::SerializeTupleVariant> {
429    self.serialize_u32(variant_index)?;
430    Ok(self)
431  }
432
433  // CDR spec from year 2002 does not yet know about maps.
434  // We make an educated guess that the design is similar to sequences:
435  // First the number of key-value pairs, then each entry as a (key,value)-pair.
436  fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
437    match len {
438      None => Err(Error::SequenceLengthUnknown),
439      Some(elem_count) => {
440        self.serialize_u32(elem_count as u32)?;
441        Ok(self)
442      }
443    } // match
444  }
445
446  // Similar to tuple. No need to mark the beginning.
447  fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
448    // self.calculate_padding_need_and_write_padding(4)?;
449    // No! There is no "align to 4 before struct"-rule in CDR!
450
451    // nothing to be done.
452    Ok(self)
453  }
454
455  // Same as tuple variant: Serialize variant index. Serde will then serialize
456  // fields.
457  fn serialize_struct_variant(
458    self,
459    _name: &'static str,
460    variant_index: u32,
461    _variant: &'static str,
462    _len: usize,
463  ) -> Result<Self::SerializeStructVariant> {
464    self.serialize_u32(variant_index)?;
465    Ok(self)
466  }
467
468  fn is_human_readable(&self) -> bool {
469    false
470  }
471}
472
473impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeSeq for &'a mut CdrSerializer<W, BO> {
474  type Ok = ();
475  type Error = Error;
476
477  fn serialize_element<T>(&mut self, value: &T) -> Result<()>
478  where
479    T: ?Sized + Serialize,
480  {
481    value.serialize(&mut **self)
482  }
483
484  fn end(self) -> Result<()> {
485    Ok(())
486  }
487}
488
489impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeTuple for &'a mut CdrSerializer<W, BO> {
490  type Ok = ();
491  type Error = Error;
492
493  fn serialize_element<T>(&mut self, value: &T) -> Result<()>
494  where
495    T: ?Sized + Serialize,
496  {
497    value.serialize(&mut **self)
498  }
499
500  fn end(self) -> Result<()> {
501    Ok(())
502  }
503}
504
505impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeTupleStruct for &'a mut CdrSerializer<W, BO> {
506  type Ok = ();
507  type Error = Error;
508
509  fn serialize_field<T>(&mut self, value: &T) -> Result<()>
510  where
511    T: ?Sized + Serialize,
512  {
513    value.serialize(&mut **self)
514  }
515
516  fn end(self) -> Result<()> {
517    Ok(())
518  }
519}
520
521impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeTupleVariant for &'a mut CdrSerializer<W, BO> {
522  type Ok = ();
523  type Error = Error;
524
525  fn serialize_field<T>(&mut self, value: &T) -> Result<()>
526  where
527    T: ?Sized + Serialize,
528  {
529    value.serialize(&mut **self)
530  }
531  fn end(self) -> Result<()> {
532    Ok(())
533  }
534}
535
536impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeMap for &'a mut CdrSerializer<W, BO> {
537  type Ok = ();
538  type Error = Error;
539  fn serialize_key<T>(&mut self, key: &T) -> Result<()>
540  where
541    T: ?Sized + Serialize,
542  {
543    key.serialize(&mut **self)
544  }
545
546  fn serialize_value<T>(&mut self, value: &T) -> Result<()>
547  where
548    T: ?Sized + Serialize,
549  {
550    value.serialize(&mut **self)
551  }
552
553  fn end(self) -> Result<()> {
554    Ok(())
555  }
556}
557
558impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeStruct for &'a mut CdrSerializer<W, BO> {
559  type Ok = ();
560  type Error = Error;
561
562  fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
563  where
564    T: ?Sized + Serialize,
565  {
566    value.serialize(&mut **self)?;
567    Ok(())
568  }
569
570  fn end(self) -> Result<()> {
571    Ok(())
572  }
573}
574
575impl<'a, W: io::Write, BO: ByteOrder> ser::SerializeStructVariant for &'a mut CdrSerializer<W, BO> {
576  type Ok = ();
577  type Error = Error;
578
579  fn serialize_field<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
580  where
581    T: ?Sized + Serialize,
582  {
583    value.serialize(&mut **self)?;
584    Ok(())
585  }
586
587  fn end(self) -> Result<()> {
588    Ok(())
589  }
590}
591
592#[cfg(test)]
593mod tests {
594  use log::info;
595  use serde::{Deserialize, Serialize};
596  use serde_repr::{Deserialize_repr, Serialize_repr};
597
598  use crate::{
599    cdr_deserializer::deserialize_from_little_endian,
600    cdr_serializer::{to_big_endian_binary, to_little_endian_binary},
601  };
602
603  #[test]
604
605  fn cdr_serialize_and_deserialize_sequence_of_structs() {
606    // this length is not dividable by 4 so paddings are necessary???
607    #[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
608    pub struct MyType {
609      first_value: i16,
610      second: u8,
611    }
612    impl MyType {
613      pub fn new(first_value: i16, second: u8) -> Self {
614        Self {
615          first_value,
616          second,
617        }
618      }
619    }
620
621    let sequence_of_structs: Vec<MyType> =
622      vec![MyType::new(1, 23), MyType::new(2, 34), MyType::new(-3, 45)];
623    let serialized = to_little_endian_binary(&sequence_of_structs).unwrap();
624    let deserialized: Vec<MyType> = deserialize_from_little_endian(&serialized).unwrap();
625    info!("deserialized    {:?}", deserialized);
626    info!("serialized    {:?}", serialized);
627    assert_eq!(deserialized, sequence_of_structs);
628  }
629
630  #[test]
631  fn cdr_serialize_enum() {
632    // Enum values are encoded as unsigned longs. The numeric values associated with
633    // enum identifiers are determined by the order in which the identifiers
634    // appear in the enum declaration. The first enum identifier has the numeric
635    // value zero (0). Successive enum identifiers are take ascending numeric
636    // values, in order of declaration from left to right. -> Only C type
637    // "classic enumerations" are possible to be serialized. use Serialize_repr
638    // and Deserialize_repr when enum member has value that is not same as unit
639    // variant index (when specified explicitly in code with assign)
640    #[derive(Debug, Eq, PartialEq, Serialize_repr, Deserialize_repr)]
641    #[repr(u32)]
642    pub enum MyEnumeration {
643      First,
644      Second,
645      Third,
646      // fourth(u8,u8,u8,u8),
647      // fifth(u8,u8,u16),
648      // sixth(i16,i16),
649      SevenHundredth = 700,
650      /*eighth(u32),
651       *this_should_not_be_valid(u64,u8,u8,u16,String),
652       *similar_to_fourth(u8,u8,u8,u8), */
653    }
654
655    let enum_object_1 = MyEnumeration::First;
656    let enum_object_2 = MyEnumeration::Second;
657    let enum_object_3 = MyEnumeration::Third;
658    // let enum_object_4 = MyEnumeration::fourth(1,2,3,4);
659    // let enum_object_5 = MyEnumeration::fifth(5,6,7);
660    // let enum_object_6 = MyEnumeration::sixth(-8,9);
661    let enum_object_7 = MyEnumeration::SevenHundredth;
662    // let enum_object_8 = MyEnumeration::eighth(1000);
663    // let enum_object_9 =
664    // MyEnumeration::this_should_not_be_valid(1000,1,2,3,String::from("Hey all!"));
665    // let enum_object_10 =MyEnumeration::similar_to_fourth(5,6,7,8);
666
667    let serialized_1 = to_little_endian_binary(&enum_object_1).unwrap();
668    info!("{:?}", serialized_1);
669    let u32_value_1: u32 = deserialize_from_little_endian(&serialized_1).unwrap();
670    let deserialized_1: MyEnumeration = deserialize_from_little_endian(&serialized_1).unwrap();
671    info!("Decoded 1: {:?}", deserialized_1);
672    assert_eq!(deserialized_1, enum_object_1);
673    assert_eq!(u32_value_1, 0);
674
675    let serialized_2 = to_little_endian_binary(&enum_object_2).unwrap();
676    info!("{:?}", serialized_2);
677    let u32_value_2: u32 = deserialize_from_little_endian(&serialized_2).unwrap();
678    let deserialized_2: MyEnumeration = deserialize_from_little_endian(&serialized_2).unwrap();
679    info!("Decoded 2: {:?}", deserialized_2);
680    assert_eq!(deserialized_2, enum_object_2);
681    assert_eq!(u32_value_2, 1);
682
683    let serialized_3 = to_little_endian_binary(&enum_object_3).unwrap();
684    info!("{:?}", serialized_3);
685    let deserialized_3: MyEnumeration = deserialize_from_little_endian(&serialized_3).unwrap();
686    let u32_value_3: u32 = deserialize_from_little_endian(&serialized_3).unwrap();
687    info!("Decoded 3: {:?}", deserialized_3);
688    assert_eq!(deserialized_3, enum_object_3);
689    assert_eq!(u32_value_3, 2);
690
691    // let serialized_4 = to_little_endian_binary(&enum_object_4).unwrap();
692    // let deserialized_4 : MyEnumeration =
693    // deserialize_from_little_endian(serialized_4).unwrap();
694
695    let serialized_7 = to_little_endian_binary(&enum_object_7).unwrap();
696    info!("{:?}", serialized_7);
697    let deserialized_7: MyEnumeration = deserialize_from_little_endian(&serialized_7).unwrap();
698    let u32_value_7: u32 = deserialize_from_little_endian(&serialized_7).unwrap();
699    info!("Decoded 7: {:?}", deserialized_7);
700    assert_eq!(deserialized_7, enum_object_7);
701    assert_eq!(u32_value_7, 700);
702
703    /*
704    let serialized_5 = to_little_endian_binary(&enum_object_5).unwrap();
705    let serialized_6 = to_little_endian_binary(&enum_object_6).unwrap();
706    let serialized_8 = to_little_endian_binary(&enum_object_8).unwrap();
707    let serialized_9 = to_little_endian_binary(&enum_object_9).unwrap();
708    let serialized_10 = to_little_endian_binary(&enum_object_10).unwrap();
709    */
710  }
711
712  #[test]
713  fn cdr_serialization_example() {
714    // look this example https://www.omg.org/spec/DDSI-RTPS/2.2/PDF
715    // 10.2.2 Example
716
717    #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
718    struct Example {
719      a: u32,
720      b: [u8; 4],
721    }
722
723    let o = Example {
724      a: 1,
725      b: [b'a', b'b', b'c', b'd'],
726    };
727
728    let expected_serialization_le: Vec<u8> = vec![0x01, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63, 0x64];
729
730    let expected_serialization_be: Vec<u8> = vec![0x00, 0x00, 0x00, 0x01, 0x61, 0x62, 0x63, 0x64];
731
732    let serialized_le = to_little_endian_binary(&o).unwrap();
733    let serialized_be = to_big_endian_binary(&o).unwrap();
734    assert_eq!(serialized_le, expected_serialization_le);
735    assert_eq!(serialized_be, expected_serialization_be);
736  }
737
738  #[test]
739  fn cdr_serialization_test() {
740    #[derive(Serialize)]
741    struct MyType {
742      first_value: u8,
743      second_value: i8,
744      third_value: i32,
745      fourth_value: u64,
746      fifth: bool,
747    }
748
749    let micky_mouse = MyType {
750      first_value: 1,
751      second_value: -1,
752      third_value: 23,
753      fourth_value: 3434343,
754      fifth: true,
755    };
756
757    let serialized = to_little_endian_binary(&micky_mouse).unwrap();
758    let expected: Vec<u8> = vec![
759      0x01, 0xff, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x67, 0x67, 0x34, 0x00, 0x00, 0x00, 0x00,
760      0x00, 0x01,
761    ];
762    assert_eq!(expected, serialized);
763  }
764
765  #[test]
766  fn cdr_serialization_char() {
767    #[derive(Serialize)]
768    struct MyType {
769      first_value: u8,
770      second: u8,
771      third: u8,
772    }
773    let micky_mouse = MyType {
774      first_value: b'a',
775      second: b'b',
776      third: b'\xE4', // 'ä'
777    };
778
779    let serialized = to_little_endian_binary(&micky_mouse).unwrap();
780    let expected: Vec<u8> = vec![0x61, 0x62, 0xe4];
781    assert_eq!(expected, serialized);
782  }
783
784  #[test]
785  fn cdr_serialization_string() {
786    #[derive(Serialize)]
787    struct MyType<'a> {
788      first_value: &'a str,
789    }
790    let micky_mouse = MyType {
791      first_value: "BLUE",
792    };
793    let serialized = to_little_endian_binary(&micky_mouse).unwrap();
794    let expected: Vec<u8> = vec![0x05, 0x00, 0x00, 0x00, 0x42, 0x4c, 0x55, 0x45, 0x00];
795    assert_eq!(expected, serialized);
796  }
797
798  #[test]
799  fn cdr_serialization_little() {
800    let number: u16 = 60000;
801    let le = to_little_endian_binary(&number).unwrap();
802    let be = to_big_endian_binary(&number).unwrap();
803
804    assert_ne!(le, be);
805  }
806
807  #[test]
808  fn cdr_serialize_seq() {
809    #[derive(Serialize)]
810    struct MyType {
811      first_value: Vec<i32>,
812    }
813    let micky_mouse = MyType {
814      first_value: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 123123],
815    };
816    let serialized = to_little_endian_binary(&micky_mouse).unwrap();
817    let expected: Vec<u8> = vec![
818      0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
819      0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00,
820      0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf3,
821      0xe0, 0x01, 0x00,
822    ];
823    assert_eq!(expected, serialized);
824  }
825}