use crate::error::{Error, ErrorKind, Result};
use crate::read::{self, Read, Ref};
use serde::de::{self, Expected, Unexpected};
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::{io, vec::Vec};
#[cfg(feature = "std")]
pub fn from_reader<R, T>(r: R) -> Result<T>
where
R: io::Read,
T: de::DeserializeOwned,
{
let mut de = Deserializer::new(read::IoRead::new(r));
let value = T::deserialize(&mut de)?;
de.end()?;
Ok(value)
}
pub fn from_slice<'a, T>(s: &'a [u8]) -> Result<T>
where
T: de::Deserialize<'a>,
{
let mut de = Deserializer::new(read::SliceRead::new(s));
let value = T::deserialize(&mut de)?;
de.end()?;
Ok(value)
}
#[derive(Debug)]
pub struct Deserializer<R> {
read: R,
buf: Vec<u8>,
}
impl<'a, R> Deserializer<R>
where
R: Read<'a>,
{
pub fn new(read: R) -> Self {
Deserializer {
read,
buf: Vec::default(),
}
}
pub fn byte_offset(&self) -> usize {
self.read.byte_offset()
}
pub fn end(&mut self) -> Result<()> {
match self.read.peek() {
Some(r) => r.and(Err(Error::new(
ErrorKind::TrailingData,
self.read.byte_offset(),
))),
None => Ok(()),
}
}
fn on_end_seq(&mut self) -> Result<()> {
match self.parse_peek()? {
b'e' => {
self.parse_next()?;
Ok(())
}
_ => Err(Error::new(ErrorKind::InvalidList, self.read.byte_offset())),
}
}
fn on_end_map(&mut self) -> Result<()> {
match self.parse_peek()? {
b'e' => {
self.parse_next()?;
Ok(())
}
_ => Err(Error::new(ErrorKind::InvalidDict, self.read.byte_offset())),
}
}
fn unexpected_type_err(&mut self, exp: &dyn Expected) -> Result<Error> {
match self.parse_peek()? {
b'0'..=b'9' => {
self.buf.clear();
let bytes = self.read.parse_byte_str(&mut self.buf)?;
Ok(de::Error::invalid_type(Unexpected::Bytes(&bytes), exp))
}
b'i' => {
self.parse_next()?;
let (is_positive, num) = self.parse_integer()?;
if is_positive {
Ok(de::Error::invalid_type(Unexpected::Unsigned(num), exp))
} else {
use core::convert::TryFrom;
Ok(de::Error::invalid_type(
Unexpected::Signed(-i64::try_from(num).map_err(|_| {
Error::new(ErrorKind::InvalidInteger, self.read.byte_offset())
})?),
exp,
))
}
}
b'l' => Ok(de::Error::invalid_type(Unexpected::Seq, exp)),
b'd' => Ok(de::Error::invalid_type(Unexpected::Map, exp)),
_ => Err(Error::new(
ErrorKind::ExpectedSomeValue,
self.read.byte_offset(),
)),
}
}
#[inline]
fn parse_peek(&mut self) -> Result<u8> {
self.read
.peek()
.ok_or_else(|| Error::new(ErrorKind::EofWhileParsingValue, self.read.byte_offset()))?
}
#[inline]
fn parse_next(&mut self) -> Result<u8> {
self.read
.next()
.ok_or_else(|| Error::new(ErrorKind::EofWhileParsingValue, self.read.byte_offset()))?
}
fn parse_integer(&mut self) -> Result<(bool, u64)> {
let peek = self
.read
.peek()
.ok_or_else(|| Error::new(ErrorKind::EofWhileParsingValue, self.byte_offset()))??;
let is_positive = if peek == b'-' {
self.read
.next()
.ok_or_else(|| Error::new(ErrorKind::EofWhileParsingValue, self.byte_offset()))??;
false
} else {
true
};
let peek = self
.read
.peek()
.ok_or_else(|| Error::new(ErrorKind::EofWhileParsingValue, self.byte_offset()))??;
match peek {
b'0'..=b'9' => {}
_ => {
return Err(Error::new(ErrorKind::InvalidInteger, self.byte_offset()));
}
}
let mut value: u64 = 0;
loop {
match self
.read
.next()
.ok_or_else(|| Error::new(ErrorKind::EofWhileParsingValue, self.byte_offset()))??
{
b'e' => {
return Ok((is_positive, value));
}
n @ b'0'..=b'9' => {
value = value
.checked_mul(10)
.ok_or_else(|| Error::new(ErrorKind::InvalidInteger, self.byte_offset()))?;
value = value
.checked_add(u64::from(n - b'0'))
.ok_or_else(|| Error::new(ErrorKind::InvalidInteger, self.byte_offset()))?;
}
_ => return Err(Error::new(ErrorKind::InvalidInteger, self.byte_offset())),
}
}
}
}
#[cfg(feature = "std")]
impl<R> Deserializer<read::IoRead<R>>
where
R: io::Read,
{
#[must_use]
pub fn from_reader(reader: R) -> Self {
Deserializer::new(read::IoRead::new(reader))
}
}
impl<'a> Deserializer<read::SliceRead<'a>> {
#[must_use]
pub fn from_slice(bytes: &'a [u8]) -> Self {
Deserializer::new(read::SliceRead::new(bytes))
}
}
macro_rules! forward_deserialize_signed_integer {
($method:ident) => {
#[inline]
fn $method<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_i64(visitor)
}
};
}
macro_rules! forward_deserialize_unsigned_integer {
($method:ident) => {
#[inline]
fn $method<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_u64(visitor)
}
};
}
impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
match self.parse_peek()? {
b'0'..=b'9' => {
self.buf.clear();
match self.read.parse_byte_str(&mut self.buf)? {
Ref::Source(bytes) => visitor.visit_borrowed_bytes(bytes),
Ref::Buffer(bytes) => visitor.visit_bytes(bytes),
}
}
b'i' => {
self.parse_next()?;
let (is_positive, num) = self.parse_integer()?;
if is_positive {
visitor.visit_u64(num)
} else {
use core::convert::TryFrom;
visitor.visit_i64(-i64::try_from(num).map_err(|_| {
Error::new(ErrorKind::InvalidInteger, self.read.byte_offset())
})?)
}
}
b'l' => {
self.parse_next()?;
let ret = visitor.visit_seq(SeqAccess { de: self });
match (ret, self.on_end_seq()) {
(Ok(ret), Ok(())) => Ok(ret),
(Err(err), _) | (_, Err(err)) => Err(err),
}
}
b'd' => {
self.parse_next()?;
let ret = visitor.visit_map(MapAccess { de: self });
match (ret, self.on_end_map()) {
(Ok(ret), Ok(())) => Ok(ret),
(Err(err), _) | (_, Err(err)) => Err(err),
}
}
_ => Err(Error::new(
ErrorKind::ExpectedSomeValue,
self.read.byte_offset(),
)),
}
}
forward_to_deserialize_any! {
bool f32 f64 unit unit_struct
char str string
struct enum identifier ignored_any
}
forward_deserialize_signed_integer!(deserialize_i8);
forward_deserialize_signed_integer!(deserialize_i16);
forward_deserialize_signed_integer!(deserialize_i32);
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
match self.parse_peek()? {
b'i' => {
self.parse_next()?;
let (is_positive, num) = self.parse_integer()?;
if is_positive {
visitor.visit_u64(num)
} else {
use core::convert::TryFrom;
visitor.visit_i64(-i64::try_from(num).map_err(|_| {
Error::new(ErrorKind::InvalidInteger, self.read.byte_offset())
})?)
}
}
_ => Err(self.unexpected_type_err(&visitor)?),
}
}
forward_deserialize_unsigned_integer!(deserialize_u8);
forward_deserialize_unsigned_integer!(deserialize_u16);
forward_deserialize_unsigned_integer!(deserialize_u32);
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_i64(visitor)
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
match self.parse_peek()? {
b'0'..=b'9' => {
self.buf.clear();
match self.read.parse_byte_str(&mut self.buf)? {
Ref::Source(bytes) => visitor.visit_borrowed_bytes(bytes),
Ref::Buffer(bytes) => visitor.visit_bytes(bytes),
}
}
b'i' => {
self.buf.clear();
match self.read.parse_raw_integer(&mut self.buf)? {
Ref::Source(bytes) => visitor.visit_borrowed_bytes(bytes),
Ref::Buffer(bytes) => visitor.visit_bytes(bytes),
}
}
b'l' => {
self.buf.clear();
match self.read.parse_raw_list(&mut self.buf)? {
Ref::Source(bytes) => visitor.visit_borrowed_bytes(bytes),
Ref::Buffer(bytes) => visitor.visit_bytes(bytes),
}
}
b'd' => {
self.buf.clear();
match self.read.parse_raw_dict(&mut self.buf)? {
Ref::Source(bytes) => visitor.visit_borrowed_bytes(bytes),
Ref::Buffer(bytes) => visitor.visit_bytes(bytes),
}
}
_ => Err(self.unexpected_type_err(&visitor)?),
}
}
#[inline]
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_bytes(visitor)
}
#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
visitor.visit_some(self)
}
#[inline]
fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
match self.parse_peek()? {
b'l' => {
self.parse_next()?;
let ret = visitor.visit_seq(SeqAccess { de: self });
match (ret, self.on_end_seq()) {
(Ok(ret), Ok(())) => Ok(ret),
(Err(err), _) | (_, Err(err)) => Err(err),
}
}
_ => Err(self.unexpected_type_err(&visitor)?),
}
}
#[inline]
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_seq(visitor)
}
#[inline]
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
match self.parse_peek()? {
b'd' => {
self.parse_next()?;
let ret = visitor.visit_map(MapAccess { de: self });
match (ret, self.on_end_map()) {
(Ok(ret), Ok(())) => Ok(ret),
(Err(err), _) | (_, Err(err)) => Err(err),
}
}
_ => Err(self.unexpected_type_err(&visitor)?),
}
}
#[inline]
fn is_human_readable(&self) -> bool {
false
}
}
struct SeqAccess<'a, R> {
de: &'a mut Deserializer<R>,
}
impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
where
T: de::DeserializeSeed<'de>,
{
match self.de.parse_peek()? {
b'e' => Ok(None),
_ => Ok(Some(seed.deserialize(&mut *self.de)?)),
}
}
}
struct MapAccess<'a, R> {
de: &'a mut Deserializer<R>,
}
impl<'de, 'a, R: Read<'de> + 'a> de::MapAccess<'de> for MapAccess<'a, R> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
where
K: de::DeserializeSeed<'de>,
{
match self.de.parse_peek()? {
b'0'..=b'9' => seed.deserialize(MapKey { de: &mut *self.de }).map(Some),
b'e' => Ok(None),
_ => Err(Error::new(
ErrorKind::KeyMustBeAByteStr,
self.de.read.byte_offset(),
)),
}
}
#[inline]
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
where
V: de::DeserializeSeed<'de>,
{
seed.deserialize(&mut *self.de)
}
}
struct MapKey<'a, R> {
de: &'a mut Deserializer<R>,
}
impl<'de, 'a, R> de::Deserializer<'de> for MapKey<'a, R>
where
R: Read<'de>,
{
type Error = Error;
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.de.deserialize_any(visitor)
}
#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
visitor.visit_some(self)
}
#[inline]
fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 unit unit_struct seq tuple tuple_struct map
char str string bytes byte_buf enum struct identifier ignored_any
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_bytes::ByteBuf;
use serde_derive::Deserialize;
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::{collections::BTreeMap, string::String, vec};
#[cfg(feature = "std")]
use std::{collections::BTreeMap, string::String, vec};
#[test]
fn test_deserialize_str() -> Result<()> {
let s: &str = from_slice("4:spam".as_bytes())?;
assert_eq!(s, "spam");
Ok(())
}
#[test]
fn test_deserialize_string() -> Result<()> {
let s: String = from_slice("4:spam".as_bytes())?;
assert_eq!(s, "spam");
Ok(())
}
#[test]
fn test_deserialize_integer_1() -> Result<()> {
let input = "i3e";
let i: u64 = from_slice(input.as_bytes())?;
assert_eq!(i, 3);
Ok(())
}
#[test]
fn test_deserialize_integer_2() -> Result<()> {
let input = "i-3e";
let i: i64 = from_slice(input.as_bytes())?;
assert_eq!(i, -3);
Ok(())
}
#[test]
fn test_deserialize_integer_3() -> Result<()> {
let input = "i0e";
let i: u64 = from_slice(input.as_bytes())?;
assert_eq!(i, 0);
Ok(())
}
#[test]
fn test_deserialize_integer_4() -> Result<()> {
let input = "i0e";
let i: i64 = from_slice(input.as_bytes())?;
assert_eq!(i, 0);
Ok(())
}
#[test]
fn test_deserialize_illegal_unsigned_int() {
let input = "ie";
let result: Result<u64> = from_slice(input.as_bytes());
let error = result.unwrap_err();
match error.kind() {
ErrorKind::InvalidInteger => {}
_ => panic!(),
}
assert_eq!(error.byte_offset(), 1);
}
#[test]
fn test_deserialize_illegal_signed_int() {
let input = "i-e";
let result: Result<i64> = from_slice(input.as_bytes());
let error = result.unwrap_err();
match error.kind() {
ErrorKind::InvalidInteger => {}
_ => panic!(),
}
assert_eq!(error.byte_offset(), 2);
}
#[test]
fn test_deserialize_list() -> Result<()> {
let input = "l4:spam4:eggse";
let v: Vec<String> = from_slice(input.as_bytes())?;
assert_eq!(v, vec!["spam", "eggs"]);
Ok(())
}
#[test]
fn test_deserialize_list_str() -> Result<()> {
let input = "l4:spam4:eggse";
let v: Vec<&str> = from_slice(input.as_bytes())?;
assert_eq!(v, vec!["spam", "eggs"]);
Ok(())
}
#[test]
fn test_deserialize_list_as_tuple() -> Result<()> {
let input = "li123e4:eggse";
let v: (i64, &str) = from_slice(input.as_bytes())?;
assert_eq!(v, (123, "eggs"));
Ok(())
}
#[test]
fn test_deserialize_list_as_struct_tuple() -> Result<()> {
#[derive(Debug, serde_derive::Deserialize, PartialEq, Eq)]
struct S<'a>(i64, &'a str);
let input = "li123e4:eggse";
let v: S<'_> = from_slice(input.as_bytes())?;
assert_eq!(v, S(123, "eggs"));
Ok(())
}
#[test]
fn test_deserialize_dict_1() -> Result<()> {
let input = "d3:cow3:moo4:spam4:eggse";
let m: BTreeMap<String, String> = from_slice(input.as_bytes())?;
let mut expected = BTreeMap::new();
expected.insert(String::from("cow"), String::from("moo"));
expected.insert(String::from("spam"), String::from("eggs"));
assert_eq!(m, expected);
Ok(())
}
#[test]
fn test_deserialize_dict_1_str() -> Result<()> {
let input = "d3:cow3:moo4:spam4:eggse";
let m: BTreeMap<&str, &str> = from_slice(input.as_bytes())?;
let mut expected = BTreeMap::new();
expected.insert("cow", "moo");
expected.insert("spam", "eggs");
assert_eq!(m, expected);
Ok(())
}
#[test]
fn test_deserialize_dict_2() -> Result<()> {
let input = "d4:spaml1:a1:bee";
let m: BTreeMap<String, Vec<String>> = from_slice(input.as_bytes())?;
let mut expected = BTreeMap::new();
expected.insert(String::from("spam"), vec!["a".into(), "b".into()]);
assert_eq!(m, expected);
Ok(())
}
#[test]
fn test_deserialize_dict_2_str() -> Result<()> {
let input = "d4:spaml1:a1:bee";
let m: BTreeMap<&str, Vec<&str>> = from_slice(input.as_bytes())?;
let mut expected = BTreeMap::new();
expected.insert("spam", vec!["a", "b"]);
assert_eq!(m, expected);
Ok(())
}
#[test]
fn test_deserialize_struct() -> Result<()> {
#[derive(Debug, PartialEq, Deserialize)]
struct S {
spam: Vec<String>,
}
let input = "d4:spaml1:a1:bee";
let s: S = from_slice(input.as_bytes())?;
let expected = S {
spam: vec!["a".into(), "b".into()],
};
assert_eq!(s, expected);
Ok(())
}
#[test]
fn test_deserialize_integer_as_raw_slice() -> Result<()> {
#[derive(Debug, PartialEq, Deserialize)]
struct S<'a>(&'a [u8]);
let input = "i-1234e";
let s: S<'_> = from_slice(input.as_bytes())?;
let expected = S(input.as_bytes());
assert_eq!(s, expected);
Ok(())
}
#[test]
fn test_deserialize_list_as_raw_slice() -> Result<()> {
#[derive(Debug, PartialEq, Deserialize)]
struct S<'a>(&'a [u8]);
let input = "l4:spam4:eggse";
let s: S<'_> = from_slice(input.as_bytes())?;
let expected = S(input.as_bytes());
assert_eq!(s, expected);
Ok(())
}
#[test]
fn test_deserialize_map_value_as_raw_slice() -> Result<()> {
#[derive(Debug, PartialEq, Deserialize)]
struct S<'a> {
spam: &'a [u8],
}
let input = "d4:spamd1:a1:bee";
let s: S<'_> = from_slice(input.as_bytes())?;
let expected = S { spam: b"d1:a1:be" };
assert_eq!(s, expected);
Ok(())
}
#[test]
fn test_deserialize_map_as_raw_slice() -> Result<()> {
#[derive(Debug, PartialEq, Deserialize)]
struct S<'a>(&'a [u8]);
let input = "d4:spamd1:a1:bee";
let s: S<'_> = from_slice(input.as_bytes())?;
let expected = S(input.as_bytes());
assert_eq!(s, expected);
Ok(())
}
#[test]
fn test_deserialize_integer_as_raw_bytes() -> Result<()> {
#[derive(Debug, PartialEq, Deserialize)]
struct S(ByteBuf);
let input = "i-1234e";
let s: S = from_slice(input.as_bytes())?;
let expected = S(ByteBuf::from(input.as_bytes().to_vec()));
assert_eq!(s, expected);
Ok(())
}
#[test]
fn test_deserialize_list_as_raw_bytes() -> Result<()> {
#[derive(Debug, PartialEq, Deserialize)]
struct S(ByteBuf);
let input = "l4:spam4:eggse";
let s: S = from_slice(input.as_bytes())?;
let expected = S(ByteBuf::from(input.as_bytes().to_vec()));
assert_eq!(s, expected);
Ok(())
}
#[test]
fn test_deserialize_map_value_as_raw_bytes() -> Result<()> {
#[derive(Debug, PartialEq, Deserialize)]
struct S {
spam: ByteBuf,
}
let input = "d4:spamd1:a1:bee";
let s: S = from_slice(input.as_bytes())?;
let expected = S {
spam: ByteBuf::from(b"d1:a1:be".to_vec()),
};
assert_eq!(s, expected);
Ok(())
}
#[test]
fn test_deserialize_map_as_raw_bytes() -> Result<()> {
#[derive(Debug, PartialEq, Deserialize)]
struct S(ByteBuf);
let input = "d4:spamd1:a1:bee";
let s: S = from_slice(input.as_bytes())?;
let expected = S(ByteBuf::from(input.as_bytes().to_vec()));
assert_eq!(s, expected);
Ok(())
}
}