use std::{self, io::Write, marker::PhantomData};
use byteorder::{ByteOrder, WriteBytesExt};
use serde::ser;
use crate::error::{Error, Result};
use crate::size::{
calc_serialized_data_size, calc_serialized_data_size_bounded, Infinite, SizeLimit,
};
pub struct Serializer<W, E> {
writer: W,
pos: u64,
phantom: PhantomData<E>,
}
impl<W, E> Serializer<W, E>
where
W: Write,
E: ByteOrder,
{
pub fn new(writer: W) -> Self {
Self {
writer,
pos: 0,
phantom: PhantomData,
}
}
fn add_pos(&mut self, size: u64) {
self.pos += size;
}
pub(crate) fn reset_pos(&mut self) {
self.pos = 0;
}
fn set_pos_of<T>(&mut self) -> Result<()> {
self.write_padding_of::<T>()?;
self.add_pos(std::mem::size_of::<T>() as u64);
Ok(())
}
fn write_padding_of<T>(&mut self) -> Result<()> {
const PADDING: [u8; 8] = [0; 8];
let alignment = std::mem::size_of::<T>();
let rem_mask = alignment - 1; match (self.pos as usize) & rem_mask {
0 => Ok(()),
n @ 1..=7 => {
let amt = alignment - n;
self.pos += amt as u64;
self.writer.write_all(&PADDING[..amt]).map_err(Into::into)
}
_ => unreachable!(),
}
}
fn write_usize_as_u32(&mut self, v: usize) -> Result<()> {
if v > std::u32::MAX as usize {
return Err(Error::NumberOutOfRange);
}
ser::Serializer::serialize_u32(self, v as u32)
}
}
impl<'a, W, E> ser::Serializer for &'a mut Serializer<W, E>
where
W: Write,
E: ByteOrder,
{
type Ok = ();
type Error = Error;
type SerializeSeq = Compound<'a, W, E>;
type SerializeTuple = Compound<'a, W, E>;
type SerializeTupleStruct = Compound<'a, W, E>;
type SerializeTupleVariant = Compound<'a, W, E>;
type SerializeMap = Compound<'a, W, E>;
type SerializeStruct = Compound<'a, W, E>;
type SerializeStructVariant = Compound<'a, W, E>;
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
self.set_pos_of::<bool>()?;
self.writer
.write_u8(if v { 1 } else { 0 })
.map_err(Into::into)
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
self.set_pos_of::<u8>()?;
self.writer.write_u8(v).map_err(Into::into)
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
self.set_pos_of::<u16>()?;
self.writer.write_u16::<E>(v).map_err(Into::into)
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
self.set_pos_of::<u32>()?;
self.writer.write_u32::<E>(v).map_err(Into::into)
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
self.set_pos_of::<u64>()?;
self.writer.write_u64::<E>(v).map_err(Into::into)
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
self.set_pos_of::<i8>()?;
self.writer.write_i8(v).map_err(Into::into)
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
self.set_pos_of::<i16>()?;
self.writer.write_i16::<E>(v).map_err(Into::into)
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
self.set_pos_of::<i32>()?;
self.writer.write_i32::<E>(v).map_err(Into::into)
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
self.set_pos_of::<i64>()?;
self.writer.write_i64::<E>(v).map_err(Into::into)
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
self.set_pos_of::<f32>()?;
self.writer.write_f32::<E>(v).map_err(Into::into)
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
self.set_pos_of::<f64>()?;
self.writer.write_f64::<E>(v).map_err(Into::into)
}
fn serialize_char(self, v: char) -> Result<Self::Ok> {
let width = v.len_utf8();
if width != 1 {
Err(Error::InvalidChar(v))
} else {
let mut buf = [0u8; 1];
v.encode_utf8(&mut buf);
self.add_pos(width as u64);
self.writer.write_all(&buf[..width]).map_err(Into::into)
}
}
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
let terminating_char = [0u8];
let l = v.len() + terminating_char.len();
self.write_usize_as_u32(l)?;
self.add_pos(l as u64);
self.writer.write_all(v.as_bytes())?;
self.writer.write_all(&terminating_char).map_err(Into::into)
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
let l = v.len();
self.write_usize_as_u32(l)?;
self.add_pos(l as u64);
self.writer.write_all(v).map_err(Into::into)
}
fn serialize_none(self) -> Result<Self::Ok> {
Err(Error::TypeNotSupported)
}
fn serialize_some<T: ?Sized>(self, _v: &T) -> Result<Self::Ok>
where
T: ser::Serialize,
{
Err(Error::TypeNotSupported)
}
fn serialize_unit(self) -> Result<Self::Ok> {
Ok(())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
Ok(())
}
fn serialize_unit_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
) -> Result<Self::Ok> {
self.serialize_u32(variant_index)
}
fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Self::Ok>
where
T: ser::Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized>(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
value: &T,
) -> Result<Self::Ok>
where
T: ser::Serialize,
{
self.serialize_u32(variant_index)?;
value.serialize(self)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
let len = len.ok_or(Error::SequenceMustHaveLength)?;
self.write_usize_as_u32(len)?;
Ok(Compound { ser: self })
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
Ok(Compound { ser: self })
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct> {
Ok(Compound { ser: self })
}
fn serialize_tuple_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant> {
self.serialize_u32(variant_index)?;
Ok(Compound { ser: self })
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
Err(Error::TypeNotSupported)
}
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
Ok(Compound { ser: self })
}
fn serialize_struct_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant> {
self.serialize_u32(variant_index)?;
Ok(Compound { ser: self })
}
fn is_human_readable(&self) -> bool {
false
}
}
#[doc(hidden)]
pub struct Compound<'a, W: 'a, E: 'a> {
ser: &'a mut Serializer<W, E>,
}
impl<'a, W, E> ser::SerializeSeq for Compound<'a, W, E>
where
W: Write,
E: ByteOrder,
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: ser::Serialize,
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> ser::SerializeTuple for Compound<'a, W, E>
where
W: Write,
E: ByteOrder,
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: ser::Serialize,
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> ser::SerializeTupleStruct for Compound<'a, W, E>
where
W: Write,
E: ByteOrder,
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: ser::Serialize,
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> ser::SerializeTupleVariant for Compound<'a, W, E>
where
W: Write,
E: ByteOrder,
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: ser::Serialize,
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> ser::SerializeMap for Compound<'a, W, E>
where
W: Write,
E: ByteOrder,
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>
where
T: ser::Serialize,
{
key.serialize(&mut *self.ser)
}
#[inline]
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>
where
T: ser::Serialize,
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> ser::SerializeStruct for Compound<'a, W, E>
where
W: Write,
E: ByteOrder,
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<()>
where
T: ser::Serialize,
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W, E> ser::SerializeStructVariant for Compound<'a, W, E>
where
W: Write,
E: ByteOrder,
{
type Ok = ();
type Error = Error;
#[inline]
fn serialize_field<T: ?Sized>(&mut self, _key: &'static str, value: &T) -> Result<()>
where
T: ser::Serialize,
{
value.serialize(&mut *self.ser)
}
#[inline]
fn end(self) -> Result<()> {
Ok(())
}
}
pub fn serialize_data<T: ?Sized, S, E>(value: &T, size_limit: S) -> Result<Vec<u8>>
where
T: ser::Serialize,
S: SizeLimit,
E: ByteOrder,
{
let mut writer = match size_limit.limit() {
Some(limit) => {
let actual_size = calc_serialized_data_size_bounded(value, limit)?;
Vec::with_capacity(actual_size as usize)
}
None => {
let size = calc_serialized_data_size(value) as usize;
Vec::with_capacity(size)
}
};
serialize_data_into::<_, _, _, E>(&mut writer, value, Infinite)?;
Ok(writer)
}
pub fn serialize_data_into<W, T: ?Sized, S, E>(writer: W, value: &T, size_limit: S) -> Result<()>
where
W: Write,
T: ser::Serialize,
S: SizeLimit,
E: ByteOrder,
{
if let Some(limit) = size_limit.limit() {
calc_serialized_data_size_bounded(value, limit)?;
}
let mut serializer = Serializer::<_, E>::new(writer);
ser::Serialize::serialize(value, &mut serializer)
}
#[cfg(test)]
mod tests {
use super::*;
use byteorder::{BigEndian, LittleEndian};
#[test]
fn serialize_octet() {
let v = 32u8;
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0x20]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x20]
);
}
#[test]
fn serialize_char() {
let v = 'Z';
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0x5a]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x5a]
);
}
#[test]
fn serialize_ushort() {
let v = 65500u16;
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0xff, 0xdc]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0xdc, 0xff]
);
}
#[test]
fn serialize_short() {
let v = -32700i16;
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0x80, 0x44]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x44, 0x80]
);
}
#[test]
fn serialize_ulong() {
let v = 4294967200u32;
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0xff, 0xff, 0xff, 0xa0]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0xa0, 0xff, 0xff, 0xff]
);
}
#[test]
fn serialize_long() {
let v = -2147483600i32;
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0x80, 0x00, 0x00, 0x30]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x30, 0x00, 0x00, 0x80]
);
}
#[test]
fn serialize_ulonglong() {
let v = 18446744073709551600u64;
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
);
}
#[test]
fn serialize_longlong() {
let v = -9223372036800i64;
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0xff, 0xff, 0xf7, 0x9c, 0x84, 0x2f, 0xa5, 0x40]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x40, 0xa5, 0x2f, 0x84, 0x9c, 0xf7, 0xff, 0xff]
);
}
#[test]
fn serialize_float() {
let v = std::f32::MIN_POSITIVE;
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0x00, 0x80, 0x00, 0x00]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x00, 0x00, 0x80, 0x00]
);
}
#[test]
fn serialize_double() {
let v = std::f64::MIN_POSITIVE;
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00]
);
}
#[test]
fn serialize_bool() {
let v = true;
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0x01]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x01]
);
}
#[test]
fn serialize_string() {
let v = "Hola a todos, esto es un test";
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x1e, 0x48, 0x6f, 0x6c, 0x61, 0x20, 0x61, 0x20, 0x74, 0x6f, 0x64,
0x6f, 0x73, 0x2c, 0x20, 0x65, 0x73, 0x74, 0x6f, 0x20, 0x65, 0x73, 0x20, 0x75, 0x6e,
0x20, 0x74, 0x65, 0x73, 0x74, 0x00,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x1e, 0x00, 0x00, 0x00, 0x48, 0x6f, 0x6c, 0x61, 0x20, 0x61, 0x20, 0x74, 0x6f, 0x64,
0x6f, 0x73, 0x2c, 0x20, 0x65, 0x73, 0x74, 0x6f, 0x20, 0x65, 0x73, 0x20, 0x75, 0x6e,
0x20, 0x74, 0x65, 0x73, 0x74, 0x00,
]
);
}
#[test]
fn serialize_empty_string() {
let v = "";
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0x00, 0x00, 0x00, 0x01, 0x00]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x01, 0x00, 0x00, 0x00, 0x00]
);
}
#[test]
fn serialize_octet_array() {
let v = [1u8, 2, 3, 4, 5];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0x01, 0x02, 0x03, 0x04, 0x05]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x01, 0x02, 0x03, 0x04, 0x05]
);
}
#[test]
fn serialize_char_array() {
let v = ['A', 'B', 'C', 'D', 'E'];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0x41, 0x42, 0x43, 0x44, 0x45]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x41, 0x42, 0x43, 0x44, 0x45]
);
}
#[test]
fn serialize_ushort_array() {
let v = [65500u16, 65501, 65502, 65503, 65504];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0xff, 0xdc, 0xff, 0xdd, 0xff, 0xde, 0xff, 0xdf, 0xff, 0xe0
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0xdc, 0xff, 0xdd, 0xff, 0xde, 0xff, 0xdf, 0xff, 0xe0, 0xff
]
);
}
#[test]
fn serialize_short_array() {
let v = [-32700i16, -32701, -32702, -32703, -32704];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x80, 0x44, 0x80, 0x43, 0x80, 0x42, 0x80, 0x41, 0x80, 0x40
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x44, 0x80, 0x43, 0x80, 0x42, 0x80, 0x41, 0x80, 0x40, 0x80
]
);
}
#[test]
fn serialize_ulong_array() {
let v = [
4294967200u32,
4294967201,
4294967202,
4294967203,
4294967204,
];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0xff, 0xff, 0xff, 0xa0, 0xff, 0xff, 0xff, 0xa1, 0xff, 0xff, 0xff, 0xa2, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0xa4,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0xa0, 0xff, 0xff, 0xff, 0xa1, 0xff, 0xff, 0xff, 0xa2, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0xa4, 0xff, 0xff, 0xff,
]
);
}
#[test]
fn serialize_long_array() {
let v = [
-2147483600,
-2147483601,
-2147483602,
-2147483603,
-2147483604,
];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x80, 0x00, 0x00, 0x30, 0x80, 0x00, 0x00, 0x2f, 0x80, 0x00, 0x00, 0x2e, 0x80, 0x00, 0x00, 0x2d, 0x80, 0x00, 0x00, 0x2c,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x30, 0x00, 0x00, 0x80, 0x2f, 0x00, 0x00, 0x80, 0x2e, 0x00, 0x00, 0x80, 0x2d, 0x00, 0x00, 0x80, 0x2c, 0x00, 0x00, 0x80,
]
);
}
#[test]
fn serialize_ulonglong_array() {
let v = [
18446744073709551600u64,
18446744073709551601,
18446744073709551602,
18446744073709551603,
18446744073709551604,
];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
]
);
}
#[test]
fn serialize_longlong_array() {
let v = [
-9223372036800i64,
-9223372036801,
-9223372036802,
-9223372036803,
-9223372036804,
];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0xff, 0xff, 0xf7, 0x9c, 0x84, 0x2f, 0xa5, 0x40, 0xff, 0xff, 0xf7, 0x9c, 0x84, 0x2f, 0xa5, 0x3f, 0xff, 0xff, 0xf7, 0x9c, 0x84, 0x2f, 0xa5, 0x3e, 0xff, 0xff, 0xf7, 0x9c, 0x84, 0x2f, 0xa5, 0x3d, 0xff, 0xff, 0xf7, 0x9c, 0x84, 0x2f, 0xa5, 0x3c,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x40, 0xa5, 0x2f, 0x84, 0x9c, 0xf7, 0xff, 0xff, 0x3f, 0xa5, 0x2f, 0x84, 0x9c, 0xf7, 0xff, 0xff, 0x3e, 0xa5, 0x2f, 0x84, 0x9c, 0xf7, 0xff, 0xff, 0x3d, 0xa5, 0x2f, 0x84, 0x9c, 0xf7, 0xff, 0xff, 0x3c, 0xa5, 0x2f, 0x84, 0x9c, 0xf7, 0xff, 0xff,
]
);
}
#[test]
fn serialize_float_array() {
let f = std::f32::MIN_POSITIVE;
let v = [f, f + 1., f + 2., f + 3., f + 4.];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x80, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x40,
]
);
}
#[test]
fn serialize_double_array() {
let f = std::f64::MIN_POSITIVE;
let v = [f, f + 1., f + 2., f + 3., f + 4.];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40,
]
);
}
#[test]
fn serialize_bool_array() {
let v = [true, false, true, false, true];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![0x01, 0x00, 0x01, 0x00, 0x01]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![0x01, 0x00, 0x01, 0x00, 0x01]
);
}
#[test]
fn serialize_string_array() {
let v = ["HOLA", "ADIOS", "HELLO", "BYE", "GOODBYE"];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0x48, 0x4f, 0x4c, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x41, 0x44, 0x49, 0x4f, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x48, 0x45, 0x4c, 0x4c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x42, 0x59, 0x45, 0x00, 0x00, 0x00, 0x00, 0x08, 0x47, 0x4f, 0x4f, 0x44, 0x42, 0x59, 0x45, 0x00,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0x48, 0x4f, 0x4c, 0x41, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x41, 0x44, 0x49, 0x4f, 0x53, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x48, 0x45, 0x4c, 0x4c, 0x4f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x42, 0x59, 0x45, 0x00, 0x08, 0x00, 0x00, 0x00, 0x47, 0x4f, 0x4f, 0x44, 0x42, 0x59, 0x45, 0x00,
]
);
}
#[test]
fn serialize_octet_sequence() {
let v = vec![1u8, 2, 3, 4, 5];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05
]
);
}
#[test]
fn serialize_char_sequence() {
let v = vec!['A', 'B', 'C', 'D', 'E'];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0x41, 0x42, 0x43, 0x44, 0x45
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0x41, 0x42, 0x43, 0x44, 0x45
]
);
}
#[test]
fn serialize_ushort_sequence() {
let v = vec![65500u16, 65501, 65502, 65503, 65504];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0xff, 0xdc, 0xff, 0xdd, 0xff, 0xde, 0xff, 0xdf, 0xff, 0xe0
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0xdc, 0xff, 0xdd, 0xff, 0xde, 0xff, 0xdf, 0xff, 0xe0, 0xff
]
);
}
#[test]
fn serialize_short_sequence() {
let v = vec![-32700i16, -32701, -32702, -32703, -32704];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0x80, 0x44, 0x80, 0x43, 0x80, 0x42, 0x80, 0x41, 0x80, 0x40
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0x44, 0x80, 0x43, 0x80, 0x42, 0x80, 0x41, 0x80, 0x40, 0x80
]
);
}
#[test]
fn serialize_ulong_sequence() {
let v = vec![
4294967200u32,
4294967201,
4294967202,
4294967203,
4294967204,
];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0xff, 0xff, 0xff, 0xa0, 0xff, 0xff, 0xff, 0xa1, 0xff, 0xff, 0xff, 0xa2, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0xa4,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0xa0, 0xff, 0xff, 0xff, 0xa1, 0xff, 0xff, 0xff, 0xa2, 0xff, 0xff, 0xff, 0xa3, 0xff, 0xff, 0xff, 0xa4, 0xff, 0xff, 0xff,
]
);
}
#[test]
fn serialize_long_sequence() {
let v = vec![
-2147483600,
-2147483601,
-2147483602,
-2147483603,
-2147483604,
];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0x80, 0x00, 0x00, 0x30, 0x80, 0x00, 0x00, 0x2f, 0x80, 0x00, 0x00, 0x2e, 0x80, 0x00, 0x00, 0x2d, 0x80, 0x00, 0x00, 0x2c,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x80, 0x2f, 0x00, 0x00, 0x80, 0x2e, 0x00, 0x00, 0x80, 0x2d, 0x00, 0x00, 0x80, 0x2c, 0x00, 0x00, 0x80,
]
);
}
#[test]
fn serialize_ulonglong_sequence() {
let v = vec![
18446744073709551600u64,
18446744073709551601,
18446744073709551602,
18446744073709551603,
18446744073709551604,
];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
]
);
}
#[test]
fn serialize_longlong_sequence() {
let v = vec![
-9223372036800i64,
-9223372036801,
-9223372036802,
-9223372036803,
-9223372036804,
];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x9c, 0x84, 0x2f, 0xa5, 0x40, 0xff, 0xff, 0xf7, 0x9c, 0x84, 0x2f, 0xa5, 0x3f, 0xff, 0xff, 0xf7, 0x9c, 0x84, 0x2f, 0xa5, 0x3e, 0xff, 0xff, 0xf7, 0x9c, 0x84, 0x2f, 0xa5, 0x3d, 0xff, 0xff, 0xf7, 0x9c, 0x84, 0x2f, 0xa5, 0x3c,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xa5, 0x2f, 0x84, 0x9c, 0xf7, 0xff, 0xff, 0x3f, 0xa5, 0x2f, 0x84, 0x9c, 0xf7, 0xff, 0xff, 0x3e, 0xa5, 0x2f, 0x84, 0x9c, 0xf7, 0xff, 0xff, 0x3d, 0xa5, 0x2f, 0x84, 0x9c, 0xf7, 0xff, 0xff, 0x3c, 0xa5, 0x2f, 0x84, 0x9c, 0xf7, 0xff, 0xff,
]
);
}
#[test]
fn serialize_float_sequence() {
let f = std::f32::MIN_POSITIVE;
let v = vec![f, f + 1., f + 2., f + 3., f + 4.];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0x00, 0x80, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x40,
]
);
}
#[test]
fn serialize_double_sequence() {
let f = std::f64::MIN_POSITIVE;
let v = vec![f, f + 1., f + 2., f + 3., f + 4.];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40,
]
);
}
#[test]
fn serialize_bool_sequence() {
let v = vec![true, false, true, false, true];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x01, 0x00, 0x01
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01
]
);
}
#[test]
fn serialize_string_sequence() {
let v = vec!["HOLA", "ADIOS", "HELLO", "BYE", "GOODBYE"];
assert_eq!(
serialize_data::<_, _, BigEndian>(&v, Infinite).unwrap(),
vec![
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x48, 0x4f, 0x4c, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x41, 0x44, 0x49, 0x4f, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x48, 0x45, 0x4c, 0x4c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x42, 0x59, 0x45, 0x00, 0x00, 0x00, 0x00, 0x08, 0x47, 0x4f, 0x4f, 0x44, 0x42, 0x59, 0x45, 0x00,
]
);
assert_eq!(
serialize_data::<_, _, LittleEndian>(&v, Infinite).unwrap(),
vec![
0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x4f, 0x4c, 0x41, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x41, 0x44, 0x49, 0x4f, 0x53, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x48, 0x45, 0x4c, 0x4c, 0x4f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x42, 0x59, 0x45, 0x00, 0x08, 0x00, 0x00, 0x00, 0x47, 0x4f, 0x4f, 0x44, 0x42, 0x59, 0x45, 0x00,
]
);
}
}