use serde::{ser, Serialize};
use crate::error::{Error, Result};
pub struct Serializer {
output: Vec<u8>,
is_message: bool,
has_option: bool,
}
pub fn to_bytes<T>(value: &T) -> Result<Vec<u8>>
where
T: Serialize,
{
let mut serializer = Serializer {
output: Vec::new(),
is_message: false,
has_option: false,
};
value.serialize(&mut serializer)?;
Ok(serializer.output)
}
pub fn to_bytes_message<T>(value: &T) -> Result<Vec<u8>>
where
T: Serialize,
{
let mut serializer = Serializer {
output: Vec::new(),
is_message: true,
has_option: false,
};
value.serialize(&mut serializer)?;
Ok(serializer.output)
}
impl<'a> ser::Serializer for &'a mut Serializer {
type Ok = ();
type Error = Error;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleStruct = Self;
type SerializeTupleVariant = Self;
type SerializeMap = Self;
type SerializeStruct = StructSerializer<'a>;
type SerializeStructVariant = StructSerializer<'a>;
fn serialize_bool(self, v: bool) -> Result<()> {
self.output.push(if v { 0x01 } else { 0x00 });
Ok(())
}
fn serialize_i8(self, _v: i8) -> Result<()> {
Err(Error::Int8NotSupported)
}
fn serialize_i16(self, v: i16) -> Result<()> {
self.output.extend(&v.to_le_bytes());
Ok(())
}
fn serialize_i32(self, v: i32) -> Result<()> {
self.output.extend(&v.to_le_bytes());
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<()> {
self.output.extend(&v.to_le_bytes());
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<()> {
self.output.extend(&v.to_le_bytes());
Ok(())
}
fn serialize_u16(self, v: u16) -> Result<()> {
self.output.extend(&v.to_le_bytes());
Ok(())
}
fn serialize_u32(self, v: u32) -> Result<()> {
self.output.extend(&v.to_le_bytes());
Ok(())
}
fn serialize_u64(self, v: u64) -> Result<()> {
self.output.extend(&v.to_le_bytes());
Ok(())
}
fn serialize_f32(self, v: f32) -> Result<()> {
self.output.extend(&v.to_le_bytes());
Ok(())
}
fn serialize_f64(self, v: f64) -> Result<()> {
self.output.extend(&v.to_le_bytes());
Ok(())
}
fn serialize_char(self, v: char) -> Result<()> {
self.output.extend(&(v.len_utf8() as u32).to_le_bytes());
let mut encoded = Vec::with_capacity(v.len_utf8());
v.encode_utf8(&mut encoded);
self.output.extend(encoded);
Ok(())
}
fn serialize_str(self, v: &str) -> Result<()> {
self.output
.extend(&(v.as_bytes().len() as u32).to_le_bytes());
self.output.extend(v.as_bytes());
Ok(())
}
fn serialize_bytes(self, v: &[u8]) -> Result<()> {
use serde::ser::SerializeSeq;
let mut seq = self.serialize_seq(Some(v.len()))?;
for byte in v {
seq.serialize_element(byte)?;
}
seq.end()
}
fn serialize_none(self) -> Result<()> {
self.has_option = true;
Ok(())
}
fn serialize_some<T>(self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.has_option = true;
value.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
Ok(())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &'static str,
variant_index: u32,
_variant: &'static str,
) -> Result<()> {
self.output.extend(&variant_index.to_le_bytes());
Ok(())
}
fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_value: &T,
) -> Result<()>
where
T: ?Sized + Serialize,
{
Err(Error::VariantDataNotAllowed)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
self.output
.extend(&(len.ok_or(Error::ExpectedArrayLength)? as u32).to_le_bytes());
Ok(self)
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant> {
Err(Error::VariantDataNotAllowed)
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
self.output
.extend(&(len.ok_or(Error::ExpectedMapLength)? as u32).to_le_bytes());
Ok(self)
}
fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
Ok(StructSerializer {
parts: Vec::new(),
expected_length: len,
has_option: false,
inner: self,
})
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant> {
Err(Error::VariantDataNotAllowed)
}
}
pub struct StructSerializer<'a> {
parts: Vec<Option<Vec<u8>>>,
expected_length: usize,
has_option: bool,
inner: &'a mut Serializer,
}
impl<'a> StructSerializer<'a> {
fn serialize_message(self) -> Result<()> {
let mut body = (1u8..)
.zip(self.parts)
.fold(Vec::new(), |mut acc, (index, data)| {
if let Some(bytes) = data {
acc.push(index);
acc.extend(bytes);
}
acc
});
body.push(0u8);
self.inner.output.extend(&(body.len() as u32).to_le_bytes());
self.inner.output.extend(body);
Ok(())
}
fn serialize_struct(self) -> Result<()> {
self.inner
.output
.extend(self.parts.into_iter().flatten().flatten());
Ok(())
}
fn serialize_field_inner<T>(&mut self, _key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
let mut serializer = Serializer {
output: Vec::new(),
is_message: false,
has_option: false,
};
value.serialize(&mut serializer)?;
self.has_option = serializer.has_option || self.has_option;
if serializer.output.is_empty() {
self.parts.push(None)
} else {
self.parts.push(Some(serializer.output))
}
Ok(())
}
fn end_inner(self) -> Result<()> {
if self.expected_length != self.parts.len() {
return Err(Error::StructLengthMismatch(
self.expected_length,
self.parts.len(),
));
}
if self.has_option || self.inner.is_message {
self.serialize_message()
} else {
self.serialize_struct()
}
}
}
impl<'a> ser::SerializeStruct for StructSerializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.serialize_field_inner(key, value)
}
fn end(self) -> Result<()> {
self.end_inner()
}
}
impl<'a> ser::SerializeSeq for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a> ser::SerializeTuple for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a> ser::SerializeMap for &'a mut Serializer {
type Ok = ();
type Error = Error;
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
key.serialize(&mut **self)
}
fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a> ser::SerializeStructVariant for StructSerializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where
T: ?Sized + Serialize,
{
self.serialize_field_inner(key, value)
}
fn end(self) -> Result<()> {
self.end_inner()
}
}
#[cfg(test)]
mod test {
use std::collections::HashMap;
use super::*;
use serde::Serialize;
#[derive(Serialize)]
struct SimpleStruct {
name: String,
age: u16,
}
#[test]
fn test_valid_struct() {
let data = SimpleStruct {
name: "Charlie".to_string(),
age: 28,
};
let raw = to_bytes(&data).expect("Unable to serialize");
let expected: Vec<u8> = vec![7, 0, 0, 0, 67, 104, 97, 114, 108, 105, 101, 28, 0];
assert_eq!(raw, expected);
}
#[test]
fn test_valid_struct_message() {
let data = SimpleStruct {
name: "Charlie".to_string(),
age: 28,
};
let raw = to_bytes_message(&data).expect("Unable to serialize");
let expected: Vec<u8> = vec![
16, 0, 0, 0, 1, 7, 0, 0, 0, 67, 104, 97, 114, 108, 105, 101, 2, 28, 0, 0,
];
assert_eq!(raw, expected);
}
#[derive(Serialize)]
struct SimpleMessage {
name: String,
age: Option<u16>,
}
#[test]
fn test_valid_message_all_fields() {
let data = SimpleMessage {
name: "Charlie".to_string(),
age: Some(28),
};
let raw = to_bytes(&data).expect("Unable to serialize");
let expected: Vec<u8> = vec![
16, 0, 0, 0, 1, 7, 0, 0, 0, 67, 104, 97, 114, 108, 105, 101, 2, 28, 0, 0,
];
assert_eq!(raw, expected);
}
#[test]
fn test_valid_message_some_fields() {
let data = SimpleMessage {
name: "Charlie".to_string(),
age: None,
};
let raw = to_bytes(&data).expect("Unable to serialize");
let expected: Vec<u8> = vec![
13, 0, 0, 0, 1, 7, 0, 0, 0, 67, 104, 97, 114, 108, 105, 101, 0,
];
assert_eq!(raw, expected);
}
#[derive(Serialize)]
#[allow(dead_code)]
enum Fun {
Not,
Somewhat,
Really,
}
#[derive(Serialize)]
struct Complex {
name: Option<String>,
fun_level: Fun,
map: HashMap<String, SimpleStruct>,
message_map: HashMap<String, SimpleMessage>,
list: Vec<f32>,
boolean: bool,
int16: i16,
int32: i32,
int64: i64,
uint16: u16,
uint32: u32,
uint64: u64,
byte: u8,
float64: f64,
}
#[test]
fn test_complex() {
let mut map = HashMap::new();
map.insert(
"one".to_string(),
SimpleStruct {
name: "One".to_string(),
age: 16,
},
);
let mut message_map = HashMap::new();
message_map.insert(
"one".to_string(),
SimpleMessage {
name: "One".to_string(),
age: None,
},
);
#[allow(clippy::approx_constant, clippy::clippy::excessive_precision)]
let data = Complex {
name: Some("Charlie".to_string()),
fun_level: Fun::Somewhat,
map,
message_map,
list: vec![3.1415926, 2.71828],
boolean: true,
int16: -3,
int32: 42,
int64: 123456789,
uint16: 3,
uint32: 42,
uint64: 123456789,
byte: 17,
float64: 3.1415926,
};
let raw = to_bytes(&data).expect("Unable to serialize");
let expected: Vec<u8> = vec![
124, 0, 0, 0, 1, 7, 0, 0, 0, 67, 104, 97, 114, 108, 105, 101, 2, 1, 0, 0, 0, 3, 1, 0,
0, 0, 3, 0, 0, 0, 111, 110, 101, 3, 0, 0, 0, 79, 110, 101, 16, 0, 4, 1, 0, 0, 0, 3, 0,
0, 0, 111, 110, 101, 9, 0, 0, 0, 1, 3, 0, 0, 0, 79, 110, 101, 0, 5, 2, 0, 0, 0, 218,
15, 73, 64, 77, 248, 45, 64, 6, 1, 7, 253, 255, 8, 42, 0, 0, 0, 9, 21, 205, 91, 7, 0,
0, 0, 0, 10, 3, 0, 11, 42, 0, 0, 0, 12, 21, 205, 91, 7, 0, 0, 0, 0, 13, 17, 14, 74,
216, 18, 77, 251, 33, 9, 64, 0,
];
assert_eq!(raw, expected);
}
}