use core::fmt::{self, Debug};
use serde::de::{self, MapAccess, SeqAccess, Visitor};
use serde::ser::{
SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
SerializeTupleStruct, SerializeTupleVariant,
};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SbinType {
Nil = 0,
U8 = 1,
U16 = 2,
U32 = 3,
U64 = 4,
I8 = 5,
I16 = 6,
I32 = 7,
I64 = 8,
F32 = 9,
F64 = 10,
Bool = 11,
Str = 12,
Bytes = 13,
Array = 14,
Object = 15,
End = 16,
}
impl SbinType {
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(SbinType::Nil),
1 => Some(SbinType::U8),
2 => Some(SbinType::U16),
3 => Some(SbinType::U32),
4 => Some(SbinType::U64),
5 => Some(SbinType::I8),
6 => Some(SbinType::I16),
7 => Some(SbinType::I32),
8 => Some(SbinType::I64),
9 => Some(SbinType::F32),
10 => Some(SbinType::F64),
11 => Some(SbinType::Bool),
12 => Some(SbinType::Str),
13 => Some(SbinType::Bytes),
14 => Some(SbinType::Array),
15 => Some(SbinType::Object),
16 => Some(SbinType::End),
_ => None,
}
}
}
impl Serialize for SbinType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
impl<'de> Deserialize<'de> for SbinType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct SbinTypeVisitor;
impl<'de> Visitor<'de> for SbinTypeVisitor {
type Value = SbinType;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a valid SbinType u8 value")
}
fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E>
where
E: de::Error,
{
SbinType::from_u8(value).ok_or_else(|| {
de::Error::invalid_value(
de::Unexpected::Unsigned(value as u64),
&"valid SbinType value (0-27)",
)
})
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
if value <= 16 {
SbinType::from_u8(value as u8).ok_or_else(|| {
de::Error::invalid_value(
de::Unexpected::Unsigned(value),
&"valid SbinType value (0-27)",
)
})
} else {
Err(de::Error::invalid_value(
de::Unexpected::Unsigned(value),
&"valid SbinType value (0-27)",
))
}
}
}
deserializer.deserialize_u8(SbinTypeVisitor)
}
}
pub struct SbinSerializer {
output: Vec<u8>,
}
impl SbinSerializer {
pub fn new() -> Self {
Self { output: Vec::new() }
}
pub fn into_vec(self) -> Vec<u8> {
self.output
}
fn write_type(&mut self, ty: SbinType) {
self.output.push(ty as u8);
}
fn write_u32(&mut self, value: u32) {
self.output.extend_from_slice(&value.to_le_bytes());
}
}
impl Default for SbinSerializer {
fn default() -> Self {
Self::new()
}
}
impl<'a> Serializer for &'a mut SbinSerializer {
type Ok = ();
type Error = SbinError;
type SerializeSeq = SbinSeqSerializer<'a>;
type SerializeTuple = SbinSeqSerializer<'a>;
type SerializeTupleStruct = SbinSeqSerializer<'a>;
type SerializeTupleVariant = SbinSeqSerializer<'a>;
type SerializeMap = SbinMapSerializer<'a>;
type SerializeStruct = SbinStructSerializer<'a>;
type SerializeStructVariant = SbinStructSerializer<'a>;
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::Bool);
self.output.push(v as u8);
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::I8);
self.output.push(v as u8);
Ok(())
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::I16);
self.output.extend_from_slice(&v.to_le_bytes());
Ok(())
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::I32);
self.output.extend_from_slice(&v.to_le_bytes());
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::I64);
self.output.extend_from_slice(&v.to_le_bytes());
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::U8);
self.output.push(v);
Ok(())
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::U16);
self.output.extend_from_slice(&v.to_le_bytes());
Ok(())
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::U32);
self.output.extend_from_slice(&v.to_le_bytes());
Ok(())
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::U64);
self.output.extend_from_slice(&v.to_le_bytes());
Ok(())
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::F32);
self.output.extend_from_slice(&v.to_le_bytes());
Ok(())
}
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::F64);
self.output.extend_from_slice(&v.to_le_bytes());
Ok(())
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
self.serialize_str(&v.to_string())
}
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::Str);
self.write_u32(v.len() as u32);
self.output.extend_from_slice(v.as_bytes());
self.output.push(0u8);
Ok(())
}
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::Bytes);
self.write_u32(v.len() as u32);
self.output.extend_from_slice(v);
Ok(())
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::Nil);
Ok(())
}
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
value.serialize(self)
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
self.write_type(SbinType::Nil);
Ok(())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
self.serialize_unit()
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
self.serialize_unit()
}
fn serialize_newtype_struct<T: ?Sized>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: 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, Self::Error>
where
T: Serialize,
{
value.serialize(self)
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
self.write_type(SbinType::Array);
Ok(SbinSeqSerializer { ser: self })
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
self.write_type(SbinType::Array);
Ok(SbinSeqSerializer { ser: self })
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
self.write_type(SbinType::Array);
Ok(SbinSeqSerializer { ser: self })
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
self.write_type(SbinType::Array);
Ok(SbinSeqSerializer { ser: self })
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
self.write_type(SbinType::Object);
Ok(SbinMapSerializer { ser: self })
}
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
self.write_type(SbinType::Object);
Ok(SbinStructSerializer { ser: self })
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
self.write_type(SbinType::Object);
Ok(SbinStructSerializer { ser: self })
}
}
pub struct SbinSeqSerializer<'a> {
ser: &'a mut SbinSerializer,
}
impl<'a> SerializeSeq for SbinSeqSerializer<'a> {
type Ok = ();
type Error = SbinError;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
self.ser.write_type(SbinType::End);
Ok(())
}
}
impl<'a> SerializeTuple for SbinSeqSerializer<'a> {
type Ok = ();
type Error = SbinError;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
self.ser.write_type(SbinType::End);
Ok(())
}
}
impl<'a> SerializeTupleStruct for SbinSeqSerializer<'a> {
type Ok = ();
type Error = SbinError;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
self.ser.write_type(SbinType::End);
Ok(())
}
}
impl<'a> SerializeTupleVariant for SbinSeqSerializer<'a> {
type Ok = ();
type Error = SbinError;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
self.ser.write_type(SbinType::End);
self.ser.write_type(SbinType::End);
Ok(())
}
}
pub struct SbinMapSerializer<'a> {
ser: &'a mut SbinSerializer,
}
impl<'a> SerializeMap for SbinMapSerializer<'a> {
type Ok = ();
type Error = SbinError;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
key.serialize(&mut *self.ser)
}
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
self.ser.write_type(SbinType::End);
Ok(())
}
}
pub struct SbinStructSerializer<'a> {
ser: &'a mut SbinSerializer,
}
impl<'a> SerializeStruct for SbinStructSerializer<'a> {
type Ok = ();
type Error = SbinError;
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: Serialize,
{
self.ser.serialize_str(key)?;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
self.ser.write_type(SbinType::End);
Ok(())
}
}
impl<'a> SerializeStructVariant for SbinStructSerializer<'a> {
type Ok = ();
type Error = SbinError;
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: Serialize,
{
self.ser.serialize_str(key)?;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
self.ser.write_type(SbinType::End);
self.ser.write_type(SbinType::End);
Ok(())
}
}
pub struct SbinDeserializer<'de> {
input: &'de [u8],
pos: usize,
}
impl<'de> SbinDeserializer<'de> {
pub fn from_bytes(input: &'de [u8]) -> Self {
Self { input, pos: 0 }
}
fn peek_byte(&self) -> Option<u8> {
self.input.get(self.pos).copied()
}
fn next_byte(&mut self) -> Result<u8, SbinError> {
if self.pos < self.input.len() {
let byte = self.input[self.pos];
self.pos += 1;
Ok(byte)
} else {
Err(SbinError::UnexpectedEof)
}
}
fn read_type(&mut self) -> Result<SbinType, SbinError> {
let byte = self.next_byte()?;
SbinType::from_u8(byte).ok_or(SbinError::InvalidType(byte))
}
fn read_u32(&mut self) -> Result<u32, SbinError> {
if self.pos + 4 > self.input.len() {
return Err(SbinError::UnexpectedEof);
}
let bytes: [u8; 4] = [
self.input[self.pos],
self.input[self.pos + 1],
self.input[self.pos + 2],
self.input[self.pos + 3],
];
self.pos += 4;
Ok(u32::from_le_bytes(bytes))
}
fn read_u64(&mut self) -> Result<u64, SbinError> {
if self.pos + 8 > self.input.len() {
return Err(SbinError::UnexpectedEof);
}
let mut bytes = [0u8; 8];
bytes.copy_from_slice(&self.input[self.pos..self.pos + 8]);
self.pos += 8;
Ok(u64::from_le_bytes(bytes))
}
fn read_bytes(&mut self, len: usize) -> Result<&'de [u8], SbinError> {
if self.pos + len > self.input.len() {
return Err(SbinError::UnexpectedEof);
}
let bytes = &self.input[self.pos..self.pos + len];
self.pos += len;
Ok(bytes)
}
pub fn read_nil(&mut self) -> Result<(), SbinError> {
let ty = self.read_type()?;
if ty != SbinType::Nil {
return Err(SbinError::TypeMismatch);
}
Ok(())
}
pub fn read_end(&mut self) -> Result<(), SbinError> {
let ty = self.read_type()?;
if ty != SbinType::End {
return Err(SbinError::TypeMismatch);
}
Ok(())
}
}
impl<'de> Deserializer<'de> for &mut SbinDeserializer<'de> {
type Error = SbinError;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
match ty {
SbinType::Nil => visitor.visit_unit(),
SbinType::U8 => visitor.visit_u8(self.next_byte()?),
SbinType::U16 => {
let bytes = self.read_bytes(2)?;
visitor.visit_u16(u16::from_le_bytes([bytes[0], bytes[1]]))
}
SbinType::U32 => visitor.visit_u32(self.read_u32()?),
SbinType::U64 => visitor.visit_u64(self.read_u64()?),
SbinType::I8 => visitor.visit_i8(self.next_byte()? as i8),
SbinType::I16 => {
let bytes = self.read_bytes(2)?;
visitor.visit_i16(i16::from_le_bytes([bytes[0], bytes[1]]))
}
SbinType::I32 => {
let bytes = self.read_bytes(4)?;
visitor.visit_i32(i32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
}
SbinType::I64 => {
let bytes = self.read_bytes(8)?;
let mut arr = [0u8; 8];
arr.copy_from_slice(bytes);
visitor.visit_i64(i64::from_le_bytes(arr))
}
SbinType::F32 => {
let bytes = self.read_bytes(4)?;
visitor.visit_f32(f32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
}
SbinType::F64 => {
let bytes = self.read_bytes(8)?;
let mut arr = [0u8; 8];
arr.copy_from_slice(bytes);
visitor.visit_f64(f64::from_le_bytes(arr))
}
SbinType::Bool => visitor.visit_bool(self.next_byte()? != 0),
SbinType::Str => {
let len = self.read_u32()? as usize;
let bytes = self.read_bytes(len)?;
self.pos += 1;
let s = std::str::from_utf8(bytes).map_err(|_| SbinError::InvalidUtf8)?;
visitor.visit_str(s)
}
SbinType::Bytes => {
let len = self.read_u32()? as usize;
let bytes = self.read_bytes(len)?;
visitor.visit_byte_buf(bytes.to_vec())
}
SbinType::Array => visitor.visit_seq(SbinSeqDeserializer { de: self }),
SbinType::Object => visitor.visit_map(SbinMapDeserializer { de: self }),
_ => Err(SbinError::InvalidType(ty as u8)),
}
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::Bool {
return Err(SbinError::TypeMismatch);
}
visitor.visit_bool(self.next_byte()? != 0)
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::I8 {
return Err(SbinError::TypeMismatch);
}
visitor.visit_i8(self.next_byte()? as i8)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::I16 {
return Err(SbinError::TypeMismatch);
}
let bytes = self.read_bytes(2)?;
visitor.visit_i16(i16::from_le_bytes([bytes[0], bytes[1]]))
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::I32 {
return Err(SbinError::TypeMismatch);
}
let bytes = self.read_bytes(4)?;
visitor.visit_i32(i32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::I64 {
return Err(SbinError::TypeMismatch);
}
let bytes = self.read_bytes(8)?;
let mut arr = [0u8; 8];
arr.copy_from_slice(bytes);
visitor.visit_i64(i64::from_le_bytes(arr))
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::U8 {
return Err(SbinError::TypeMismatch);
}
visitor.visit_u8(self.next_byte()?)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::U16 {
return Err(SbinError::TypeMismatch);
}
let bytes = self.read_bytes(2)?;
visitor.visit_u16(u16::from_le_bytes([bytes[0], bytes[1]]))
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::U32 {
return Err(SbinError::TypeMismatch);
}
visitor.visit_u32(self.read_u32()?)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::U64 {
return Err(SbinError::TypeMismatch);
}
visitor.visit_u64(self.read_u64()?)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::F32 {
return Err(SbinError::TypeMismatch);
}
let bytes = self.read_bytes(4)?;
visitor.visit_f32(f32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::F64 {
return Err(SbinError::TypeMismatch);
}
let bytes = self.read_bytes(8)?;
let mut arr = [0u8; 8];
arr.copy_from_slice(bytes);
visitor.visit_f64(f64::from_le_bytes(arr))
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_str(visitor)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::Str {
return Err(SbinError::TypeMismatch);
}
let len = self.read_u32()? as usize;
let bytes = self.read_bytes(len)?;
self.pos += 1;
let s = std::str::from_utf8(bytes).map_err(|_| SbinError::InvalidUtf8)?;
visitor.visit_str(s)
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_str(visitor)
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::Bytes {
return Err(SbinError::TypeMismatch);
}
let len = self.read_u32()? as usize;
let bytes = self.read_bytes(len)?;
visitor.visit_byte_buf(bytes.to_vec())
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_bytes(visitor)
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if self.peek_byte() == Some(SbinType::Nil as u8) {
self.pos += 1;
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::Nil {
return Err(SbinError::TypeMismatch);
}
visitor.visit_unit()
}
fn deserialize_unit_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_unit(visitor)
}
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::Array {
return Err(SbinError::TypeMismatch);
}
visitor.visit_seq(SbinSeqDeserializer { de: self })
}
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let ty = self.read_type()?;
if ty != SbinType::Object {
return Err(SbinError::TypeMismatch);
}
visitor.visit_map(SbinMapDeserializer { de: self })
}
fn deserialize_struct<V>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_map(visitor)
}
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_enum(SbinEnumDeserializer { de: self })
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_str(visitor)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_any(visitor)
}
}
struct SbinSeqDeserializer<'a, 'de: 'a> {
de: &'a mut SbinDeserializer<'de>,
}
impl<'a, 'de> SeqAccess<'de> for SbinSeqDeserializer<'a, 'de> {
type Error = SbinError;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
if self.de.peek_byte() == Some(SbinType::End as u8) {
self.de.pos += 1;
return Ok(None);
}
seed.deserialize(&mut *self.de).map(Some)
}
}
struct SbinMapDeserializer<'a, 'de: 'a> {
de: &'a mut SbinDeserializer<'de>,
}
impl<'a, 'de> MapAccess<'de> for SbinMapDeserializer<'a, 'de> {
type Error = SbinError;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
where
K: de::DeserializeSeed<'de>,
{
if self.de.peek_byte() == Some(SbinType::End as u8) {
self.de.pos += 1;
return Ok(None);
}
seed.deserialize(&mut *self.de).map(Some)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
where
V: de::DeserializeSeed<'de>,
{
seed.deserialize(&mut *self.de)
}
}
struct SbinEnumDeserializer<'a, 'de: 'a> {
de: &'a mut SbinDeserializer<'de>,
}
impl<'a, 'de> de::EnumAccess<'de> for SbinEnumDeserializer<'a, 'de> {
type Error = SbinError;
type Variant = Self;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
where
V: de::DeserializeSeed<'de>,
{
let val = seed.deserialize(&mut *self.de)?;
Ok((val, self))
}
}
impl<'a, 'de> de::VariantAccess<'de> for SbinEnumDeserializer<'a, 'de> {
type Error = SbinError;
fn unit_variant(self) -> Result<(), Self::Error> {
Ok(())
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
where
T: de::DeserializeSeed<'de>,
{
seed.deserialize(self.de)
}
fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
de::Deserializer::deserialize_seq(self.de, visitor)
}
fn struct_variant<V>(
self,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
de::Deserializer::deserialize_map(self.de, visitor)
}
}
#[derive(Debug)]
pub enum SbinError {
Message(String),
UnexpectedEof,
InvalidType(u8),
TypeMismatch,
InvalidUtf8,
}
impl fmt::Display for SbinError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SbinError::Message(msg) => write!(f, "{}", msg),
SbinError::UnexpectedEof => write!(f, "unexpected end of input"),
SbinError::InvalidType(ty) => write!(f, "invalid type: {}", ty),
SbinError::TypeMismatch => write!(f, "type mismatch"),
SbinError::InvalidUtf8 => write!(f, "invalid utf8"),
}
}
}
impl std::error::Error for SbinError {}
impl serde::ser::Error for SbinError {
fn custom<T: fmt::Display>(msg: T) -> Self {
SbinError::Message(msg.to_string())
}
}
impl serde::de::Error for SbinError {
fn custom<T: fmt::Display>(msg: T) -> Self {
SbinError::Message(msg.to_string())
}
}
pub fn to_bytes<T>(value: &T) -> Result<Vec<u8>, SbinError>
where
T: Serialize,
{
let mut serializer = SbinSerializer::new();
value.serialize(&mut serializer)?;
Ok(serializer.into_vec())
}
pub fn from_bytes<'de, T>(bytes: &'de [u8]) -> Result<T, SbinError>
where
T: Deserialize<'de>,
{
let mut deserializer = SbinDeserializer::from_bytes(bytes);
T::deserialize(&mut deserializer)
}
#[cfg(test)]
mod tests {
use super::*;
use serde::{Deserialize, Serialize};
#[test]
fn test_primitives() {
let val: u8 = 42;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes, vec![SbinType::U8 as u8, 42]);
let decoded: u8 = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
let val: u16 = 1000;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::U16 as u8);
let decoded: u16 = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
let val: u32 = 100000;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::U32 as u8);
let decoded: u32 = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
let val: u64 = 10000000000;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::U64 as u8);
let decoded: u64 = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
let val: i8 = -42;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::I8 as u8);
let decoded: i8 = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
let val: i16 = -1000;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::I16 as u8);
let decoded: i16 = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
let val: i32 = -100000;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::I32 as u8);
let decoded: i32 = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
let val: i64 = -10000000000;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::I64 as u8);
let decoded: i64 = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
let val: f32 = 3.14;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::F32 as u8);
let decoded: f32 = from_bytes(&bytes).unwrap();
assert!((decoded - val).abs() < 0.001);
let val: f64 = 3.14159265359;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::F64 as u8);
let decoded: f64 = from_bytes(&bytes).unwrap();
assert!((decoded - val).abs() < 0.0001);
let val: bool = true;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes, vec![SbinType::Bool as u8, 1]);
let decoded: bool = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
let val: bool = false;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes, vec![SbinType::Bool as u8, 0]);
let decoded: bool = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
}
#[test]
fn test_string() {
let val = "hello world".to_string();
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::Str as u8);
let decoded: String = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
}
#[test]
fn test_vec() {
let val = vec![1u8, 2, 3, 4, 5];
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::Array as u8);
let decoded: Vec<u8> = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
}
#[test]
fn test_bytes() {
let val: &[u8] = &[1, 2, 3, 4, 5];
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::Array as u8);
let decoded: Vec<u8> = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val.to_vec());
}
#[test]
fn test_option() {
let val: Option<u32> = Some(42);
let bytes = to_bytes(&val).unwrap();
let decoded: Option<u32> = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
let val: Option<u32> = None;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes, vec![SbinType::Nil as u8]);
let decoded: Option<u32> = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct TestStruct {
name: String,
age: u32,
score: f64,
}
#[test]
fn test_struct() {
let val = TestStruct {
name: "Alice".to_string(),
age: 30,
score: 95.5,
};
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::Object as u8);
let decoded: TestStruct = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct NestedStruct {
id: u64,
data: TestStruct,
tags: Vec<String>,
}
#[test]
fn test_nested_struct() {
let val = NestedStruct {
id: 12345,
data: TestStruct {
name: "Bob".to_string(),
age: 25,
score: 88.0,
},
tags: vec!["student".to_string(), "active".to_string()],
};
let bytes = to_bytes(&val).unwrap();
let decoded: NestedStruct = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
enum TestEnum {
Unit,
Newtype(u32),
Tuple(u32, String),
Struct { a: u32, b: String },
}
#[test]
fn test_enum_unit() {
let val = TestEnum::Unit;
let bytes = to_bytes(&val).unwrap();
assert_eq!(bytes[0], SbinType::Nil as u8);
}
#[test]
fn test_hashmap() {
use std::collections::HashMap;
let mut val = HashMap::new();
val.insert("key1".to_string(), 100u32);
val.insert("key2".to_string(), 200u32);
let bytes = to_bytes(&val).unwrap();
let decoded: HashMap<String, u32> = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
}
#[test]
fn test_complex_nested() {
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Complex {
id: u64,
items: Vec<TestStruct>,
metadata: Option<std::collections::HashMap<String, String>>,
}
let mut metadata = std::collections::HashMap::new();
metadata.insert("created".to_string(), "2024-01-01".to_string());
metadata.insert("updated".to_string(), "2024-02-01".to_string());
let val = Complex {
id: 999,
items: vec![
TestStruct {
name: "Item1".to_string(),
age: 10,
score: 90.0,
},
TestStruct {
name: "Item2".to_string(),
age: 20,
score: 85.5,
},
],
metadata: Some(metadata),
};
let bytes = to_bytes(&val).unwrap();
let decoded: Complex = from_bytes(&bytes).unwrap();
assert_eq!(decoded, val);
}
}