use std::convert::TryFrom; use std::str; use std::io::Read; use super::error::{Error, Result}; use serde::de::{ self, Visitor, DeserializeSeed, IntoDeserializer }; pub struct Deserializer<'de, T: Read + ?Sized> { input: &'de mut T, } fn try_from>(value: TSource) -> Result { let cast = TDest::try_from(value).or_else(|_| Err(Error::TypeConversion))?; Ok(cast) } impl<'de, T: Read + ?Sized> Deserializer<'de, T> { pub fn new(input: &'de mut T) -> Self { Deserializer { input: input } } fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> { self.input.read_exact(buf).or_else(|e| Err(Error::Io(e)))?; Ok(()) } fn read_u8(&mut self) -> Result { let mut buf = [0u8; 1]; self.read_exact(&mut buf)?; Ok(buf[0]) } fn read_u16(&mut self) -> Result { let mut buf = [0u8; 2]; self.read_exact(&mut buf)?; Ok(u16::from_le_bytes(buf)) } fn read_u32(&mut self) -> Result { let mut buf = [0u8; 4]; self.read_exact(&mut buf)?; Ok(u32::from_le_bytes(buf)) } fn read_u64(&mut self) -> Result { let mut buf = [0u8; 8]; self.read_exact(&mut buf)?; Ok(u64::from_le_bytes(buf)) } fn read_i8(&mut self) -> Result { let value = self.read_u8()?; try_from(value) } fn read_i16(&mut self) -> Result { let value = self.read_u16()?; try_from(value) } fn read_i32(&mut self) -> Result { let value = self.read_u32()?; try_from(value) } fn read_bool(&mut self) -> Result { let byte = self.read_u8()?; Ok(byte > 0) } fn read_vec(&mut self) -> Result> { let len = try_from(self.read_u32()?)?; let mut vec = vec![0; len]; self.read_exact(vec.as_mut_slice())?; Ok(vec) } fn read_string(&mut self) -> Result { let vec = self.read_vec()?; let value = String::from_utf8(vec).or_else(|_| Err(Error::TypeConversion))?; Ok(value) } } impl<'de, 'a, T: Read> de::Deserializer<'de> for &'a mut Deserializer<'de, T> { type Error = Error; fn deserialize_any>(self, _visitor: V) -> Result { Err(Error::Message("deserialize_any is not supported".to_string())) } fn deserialize_bool>(self, visitor: V) -> Result { let value = self.read_bool()?; visitor.visit_bool(value) } fn deserialize_i8>(self, visitor: V) -> Result { let value = self.read_i8()?; visitor.visit_i8(value) } fn deserialize_i16>(self, visitor: V) -> Result { let value = self.read_i16()?; visitor.visit_i16(value) } fn deserialize_i32>(self, visitor: V) -> Result { let value = self.read_i32()?; visitor.visit_i32(value) } fn deserialize_i64>(self, visitor: V) -> Result { let unsigned = self.read_u64()?; let signed = try_from(unsigned)?; visitor.visit_i64(signed) } fn deserialize_u8>(self, visitor: V) -> Result { let value = self.read_u8()?; visitor.visit_u8(value) } fn deserialize_u16>(self, visitor: V) -> Result { let value = self.read_u16()?; visitor.visit_u16(value) } fn deserialize_u32>(self, visitor: V) -> Result { let value = self.read_u32()?; visitor.visit_u32(value) } fn deserialize_u64>(self, visitor: V) -> Result { let value = self.read_u64()?; visitor.visit_u64(value) } fn deserialize_f32>(self, visitor: V) -> Result { let mut buf = [0u8; 4]; self.read_exact(&mut buf)?; let value = f32::from_le_bytes(buf); visitor.visit_f32(value) } fn deserialize_f64>(self, visitor: V) -> Result { let mut buf = [0u8; 8]; self.read_exact(&mut buf)?; let value = f64::from_le_bytes(buf); visitor.visit_f64(value) } fn deserialize_char>(self, visitor: V) -> Result { let byte = self.read_u8()?; let value = try_from(byte)?; visitor.visit_char(value) } fn deserialize_str>(self, visitor: V) -> Result { let value = self.read_string()?; visitor.visit_str(value.as_str()) } fn deserialize_string>(self, visitor: V) -> Result { let value = self.read_string()?; visitor.visit_string(value) } fn deserialize_bytes>(self, visitor: V) -> Result { let value = self.read_vec()?; visitor.visit_bytes(value.as_slice()) } fn deserialize_byte_buf>(self, visitor: V) -> Result { let value = self.read_vec()?; visitor.visit_byte_buf(value) } fn deserialize_option>(self, visitor: V) -> Result { let some = self.read_bool()?; if some { visitor.visit_some(self) } else { visitor.visit_none() } } fn deserialize_unit>(self, visitor: V) -> Result { visitor.visit_unit() } fn deserialize_unit_struct>( self, _name: &'static str, visitor: V ) -> Result { visitor.visit_unit() } fn deserialize_newtype_struct>( self, _name: &'static str, visitor: V ) -> Result { visitor.visit_newtype_struct(self) } fn deserialize_seq>(self, visitor: V) -> Result { let len = self.read_u32()?; visitor.visit_seq(SeqAccess { elements_left: len, deserializer: self}) } fn deserialize_tuple>(self, len: usize, visitor: V) -> Result { visitor.visit_seq(SeqAccess { elements_left: try_from(len)?, deserializer: self}) } fn deserialize_tuple_struct>( self, _name: &'static str, len: usize, visitor: V ) -> Result { self.deserialize_tuple(len, visitor) } fn deserialize_map>(self, visitor: V) -> Result { let len = self.read_u32()?; visitor.visit_map(SeqAccess { elements_left: len, deserializer: self}) } fn deserialize_struct>( self, _name: &'static str, fields: &'static [&'static str], visitor: V ) -> Result { self.deserialize_tuple(fields.len(), visitor) } fn deserialize_enum>( self, _name: &'static str, _variants: &'static [&'static str], visitor: V ) -> Result { visitor.visit_enum(self) } fn deserialize_identifier>(self, _visitor: V) -> Result { Err(Error::NotSupported("Deserializer::deserialize_identifier")) } fn deserialize_ignored_any>(self, _visitor: V) -> Result { Err(Error::NotSupported("Deserializer::deserialize_ignored_any")) } fn is_human_readable(&self) -> bool { false } } struct SeqAccess<'a, 'de, T: Read> { elements_left: u32, deserializer: &'a mut Deserializer<'de, T> } impl<'a, 'de, T: Read> de::SeqAccess<'de> for SeqAccess<'a, 'de, T> { type Error = Error; fn next_element_seed>(&mut self, seed: S) -> Result> { if 0 == self.elements_left { return Ok(None) } self.elements_left -= 1; seed.deserialize(&mut *self.deserializer).map(Some) } } impl<'a, 'de, T: Read> de::MapAccess<'de> for SeqAccess<'a, 'de, T> { type Error = Error; fn next_key_seed>(&mut self, seed: S) -> Result> { if 0 == self.elements_left { return Ok(None) } self.elements_left -= 1; seed.deserialize(&mut *self.deserializer).map(Some) } fn next_value_seed>(&mut self, seed: U) -> Result { seed.deserialize(&mut *self.deserializer) } } impl<'de, T: Read> de::VariantAccess<'de> for &mut Deserializer<'de, T> { type Error = Error; fn unit_variant(self) -> Result<()> { Ok(()) } fn newtype_variant_seed>(self, seed: S) -> Result { seed.deserialize(self) } fn tuple_variant>(self, len: usize, visitor: V) -> Result { de::Deserializer::deserialize_tuple(self, len, visitor) } fn struct_variant>( self, fields: &'static [&'static str], visitor: V ) -> Result { de::Deserializer::deserialize_struct(self, "", fields, visitor) } } impl<'a, 'de, T: Read> de::EnumAccess<'de> for &mut Deserializer<'de, T> { type Error = Error; type Variant = Self; fn variant_seed>(self, seed: S) -> Result<(S::Value, Self::Variant)> { let int = self.read_u16()?; let index: u32 = try_from(int)?; let value = seed.deserialize(index.into_deserializer())?; Ok((value, self)) } } mod test { #[allow(unused_imports)] use serde::Deserialize; #[allow(unused_imports)] use super::{Result, Deserializer}; #[test] fn new() -> Result<()> { let vec: Vec = vec![0xA1, 0x42, 0x71, 0xAC]; let mut slice = vec.as_slice(); let de = Deserializer::new(&mut slice); assert_eq!(&vec.as_slice(), de.input); Ok(()) } #[test] fn deserialize_struct() -> Result<()> { #[derive(Debug, PartialEq, Deserialize)] struct Order { customer: String, item_id: u16, quantity: u8 } let expected = Order { customer: "Bob".to_string(), item_id: 256, quantity: 255 }; let vec: Vec = vec![ 0x03, 0x00, 0x00, 0x00, 'B' as u8, 'o' as u8, 'b' as u8, 0x00, 0x01, 0xFF ]; let mut slice = vec.as_slice(); let mut de = Deserializer::new(&mut slice); let result = Deserialize::deserialize(&mut de); let actual = result?; assert_eq!(expected, actual); Ok(()) } #[test] fn deserialize_enum() -> Result<()> { #[derive(Debug, PartialEq, Deserialize)] enum Emotions { Anguish, Catharsis } let vec: Vec = vec![0x01, 0x00]; let mut slice = vec.as_slice(); let mut de = Deserializer::new(&mut slice); let value = Deserialize::deserialize(&mut de)?; assert_eq!(Emotions::Catharsis, value); Ok(()) } }