| use crate::error::Error; |
| use crate::token::Token; |
| use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer}; |
| use serde::de::{ |
| self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, |
| VariantAccess, Visitor, |
| }; |
| use serde::forward_to_deserialize_any; |
| |
| #[derive(Debug)] |
| pub struct Deserializer<'de> { |
| tokens: &'de [Token], |
| } |
| |
| fn assert_next_token(de: &mut Deserializer, expected: Token) -> Result<(), Error> { |
| match de.next_token_opt() { |
| Some(token) if token == expected => Ok(()), |
| Some(other) => Err(de::Error::custom(format!( |
| "expected Token::{} but deserialization wants Token::{}", |
| other, expected, |
| ))), |
| None => Err(de::Error::custom(format!( |
| "end of tokens but deserialization wants Token::{}", |
| expected, |
| ))), |
| } |
| } |
| |
| fn unexpected(token: Token) -> Error { |
| de::Error::custom(format!( |
| "deserialization did not expect this token: {}", |
| token, |
| )) |
| } |
| |
| fn end_of_tokens() -> Error { |
| de::Error::custom("ran out of tokens to deserialize") |
| } |
| |
| impl<'de> Deserializer<'de> { |
| pub fn new(tokens: &'de [Token]) -> Self { |
| Deserializer { tokens } |
| } |
| |
| fn peek_token_opt(&self) -> Option<Token> { |
| self.tokens.first().copied() |
| } |
| |
| fn peek_token(&self) -> Result<Token, Error> { |
| self.peek_token_opt().ok_or_else(end_of_tokens) |
| } |
| |
| pub fn next_token_opt(&mut self) -> Option<Token> { |
| match self.tokens.split_first() { |
| Some((&first, rest)) => { |
| self.tokens = rest; |
| Some(first) |
| } |
| None => None, |
| } |
| } |
| |
| fn next_token(&mut self) -> Result<Token, Error> { |
| let (&first, rest) = self.tokens.split_first().ok_or_else(end_of_tokens)?; |
| self.tokens = rest; |
| Ok(first) |
| } |
| |
| pub fn remaining(&self) -> usize { |
| self.tokens.len() |
| } |
| |
| fn visit_seq<V>( |
| &mut self, |
| len: Option<usize>, |
| end: Token, |
| visitor: V, |
| ) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| let value = visitor.visit_seq(DeserializerSeqVisitor { de: self, len, end })?; |
| assert_next_token(self, end)?; |
| Ok(value) |
| } |
| |
| fn visit_map<V>( |
| &mut self, |
| len: Option<usize>, |
| end: Token, |
| visitor: V, |
| ) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| let value = visitor.visit_map(DeserializerMapVisitor { de: self, len, end })?; |
| assert_next_token(self, end)?; |
| Ok(value) |
| } |
| } |
| |
| impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> { |
| type Error = Error; |
| |
| forward_to_deserialize_any! { |
| bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string |
| bytes byte_buf unit seq map identifier ignored_any |
| } |
| |
| fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| let token = self.next_token()?; |
| match token { |
| Token::Bool(v) => visitor.visit_bool(v), |
| Token::I8(v) => visitor.visit_i8(v), |
| Token::I16(v) => visitor.visit_i16(v), |
| Token::I32(v) => visitor.visit_i32(v), |
| Token::I64(v) => visitor.visit_i64(v), |
| Token::U8(v) => visitor.visit_u8(v), |
| Token::U16(v) => visitor.visit_u16(v), |
| Token::U32(v) => visitor.visit_u32(v), |
| Token::U64(v) => visitor.visit_u64(v), |
| Token::F32(v) => visitor.visit_f32(v), |
| Token::F64(v) => visitor.visit_f64(v), |
| Token::Char(v) => visitor.visit_char(v), |
| Token::Str(v) => visitor.visit_str(v), |
| Token::BorrowedStr(v) => visitor.visit_borrowed_str(v), |
| Token::String(v) => visitor.visit_string(v.to_owned()), |
| Token::Bytes(v) => visitor.visit_bytes(v), |
| Token::BorrowedBytes(v) => visitor.visit_borrowed_bytes(v), |
| Token::ByteBuf(v) => visitor.visit_byte_buf(v.to_vec()), |
| Token::None => visitor.visit_none(), |
| Token::Some => visitor.visit_some(self), |
| Token::Unit | Token::UnitStruct { .. } => visitor.visit_unit(), |
| Token::NewtypeStruct { .. } => visitor.visit_newtype_struct(self), |
| Token::Seq { len } => self.visit_seq(len, Token::SeqEnd, visitor), |
| Token::Tuple { len } => self.visit_seq(Some(len), Token::TupleEnd, visitor), |
| Token::TupleStruct { len, .. } => { |
| self.visit_seq(Some(len), Token::TupleStructEnd, visitor) |
| } |
| Token::Map { len } => self.visit_map(len, Token::MapEnd, visitor), |
| Token::Struct { len, .. } => self.visit_map(Some(len), Token::StructEnd, visitor), |
| Token::Enum { .. } => { |
| let variant = self.next_token()?; |
| let next = self.peek_token()?; |
| match (variant, next) { |
| (Token::Str(variant), Token::Unit) => { |
| self.next_token()?; |
| visitor.visit_str(variant) |
| } |
| (Token::BorrowedStr(variant), Token::Unit) => { |
| self.next_token()?; |
| visitor.visit_borrowed_str(variant) |
| } |
| (Token::String(variant), Token::Unit) => { |
| self.next_token()?; |
| visitor.visit_string(variant.to_string()) |
| } |
| (Token::Bytes(variant), Token::Unit) => { |
| self.next_token()?; |
| visitor.visit_bytes(variant) |
| } |
| (Token::BorrowedBytes(variant), Token::Unit) => { |
| self.next_token()?; |
| visitor.visit_borrowed_bytes(variant) |
| } |
| (Token::ByteBuf(variant), Token::Unit) => { |
| self.next_token()?; |
| visitor.visit_byte_buf(variant.to_vec()) |
| } |
| (Token::U8(variant), Token::Unit) => { |
| self.next_token()?; |
| visitor.visit_u8(variant) |
| } |
| (Token::U16(variant), Token::Unit) => { |
| self.next_token()?; |
| visitor.visit_u16(variant) |
| } |
| (Token::U32(variant), Token::Unit) => { |
| self.next_token()?; |
| visitor.visit_u32(variant) |
| } |
| (Token::U64(variant), Token::Unit) => { |
| self.next_token()?; |
| visitor.visit_u64(variant) |
| } |
| (variant, Token::Unit) => Err(unexpected(variant)), |
| (variant, _) => { |
| visitor.visit_map(EnumMapVisitor::new(self, variant, EnumFormat::Any)) |
| } |
| } |
| } |
| Token::UnitVariant { variant, .. } => visitor.visit_str(variant), |
| Token::NewtypeVariant { variant, .. } => visitor.visit_map(EnumMapVisitor::new( |
| self, |
| Token::Str(variant), |
| EnumFormat::Any, |
| )), |
| Token::TupleVariant { variant, .. } => visitor.visit_map(EnumMapVisitor::new( |
| self, |
| Token::Str(variant), |
| EnumFormat::Seq, |
| )), |
| Token::StructVariant { variant, .. } => visitor.visit_map(EnumMapVisitor::new( |
| self, |
| Token::Str(variant), |
| EnumFormat::Map, |
| )), |
| Token::SeqEnd |
| | Token::TupleEnd |
| | Token::TupleStructEnd |
| | Token::MapEnd |
| | Token::StructEnd |
| | Token::TupleVariantEnd |
| | Token::StructVariantEnd => Err(unexpected(token)), |
| } |
| } |
| |
| fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| match self.peek_token()? { |
| Token::Unit | Token::None => { |
| self.next_token()?; |
| visitor.visit_none() |
| } |
| Token::Some => { |
| self.next_token()?; |
| visitor.visit_some(self) |
| } |
| _ => self.deserialize_any(visitor), |
| } |
| } |
| |
| fn deserialize_enum<V>( |
| self, |
| name: &'static str, |
| _variants: &'static [&'static str], |
| visitor: V, |
| ) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| match self.peek_token()? { |
| Token::Enum { name: n } if name == n => { |
| self.next_token()?; |
| |
| visitor.visit_enum(DeserializerEnumVisitor { de: self }) |
| } |
| Token::UnitVariant { name: n, .. } |
| | Token::NewtypeVariant { name: n, .. } |
| | Token::TupleVariant { name: n, .. } |
| | Token::StructVariant { name: n, .. } |
| if name == n => |
| { |
| visitor.visit_enum(DeserializerEnumVisitor { de: self }) |
| } |
| _ => self.deserialize_any(visitor), |
| } |
| } |
| |
| fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| match self.peek_token()? { |
| Token::UnitStruct { .. } => { |
| assert_next_token(self, Token::UnitStruct { name })?; |
| visitor.visit_unit() |
| } |
| _ => self.deserialize_any(visitor), |
| } |
| } |
| |
| fn deserialize_newtype_struct<V>( |
| self, |
| name: &'static str, |
| visitor: V, |
| ) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| match self.peek_token()? { |
| Token::NewtypeStruct { .. } => { |
| assert_next_token(self, Token::NewtypeStruct { name })?; |
| visitor.visit_newtype_struct(self) |
| } |
| _ => self.deserialize_any(visitor), |
| } |
| } |
| |
| fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| match self.peek_token()? { |
| Token::Unit | Token::UnitStruct { .. } => { |
| self.next_token()?; |
| visitor.visit_unit() |
| } |
| Token::Seq { .. } => { |
| self.next_token()?; |
| self.visit_seq(Some(len), Token::SeqEnd, visitor) |
| } |
| Token::Tuple { .. } => { |
| self.next_token()?; |
| self.visit_seq(Some(len), Token::TupleEnd, visitor) |
| } |
| Token::TupleStruct { .. } => { |
| self.next_token()?; |
| self.visit_seq(Some(len), Token::TupleStructEnd, visitor) |
| } |
| _ => self.deserialize_any(visitor), |
| } |
| } |
| |
| fn deserialize_tuple_struct<V>( |
| self, |
| name: &'static str, |
| len: usize, |
| visitor: V, |
| ) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| match self.peek_token()? { |
| Token::Unit => { |
| self.next_token()?; |
| visitor.visit_unit() |
| } |
| Token::UnitStruct { .. } => { |
| assert_next_token(self, Token::UnitStruct { name })?; |
| visitor.visit_unit() |
| } |
| Token::Seq { .. } => { |
| self.next_token()?; |
| self.visit_seq(Some(len), Token::SeqEnd, visitor) |
| } |
| Token::Tuple { .. } => { |
| self.next_token()?; |
| self.visit_seq(Some(len), Token::TupleEnd, visitor) |
| } |
| Token::TupleStruct { len: n, .. } => { |
| assert_next_token(self, Token::TupleStruct { name, len: n })?; |
| self.visit_seq(Some(len), Token::TupleStructEnd, visitor) |
| } |
| _ => self.deserialize_any(visitor), |
| } |
| } |
| |
| fn deserialize_struct<V>( |
| self, |
| name: &'static str, |
| fields: &'static [&'static str], |
| visitor: V, |
| ) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| match self.peek_token()? { |
| Token::Struct { len: n, .. } => { |
| assert_next_token(self, Token::Struct { name, len: n })?; |
| self.visit_map(Some(fields.len()), Token::StructEnd, visitor) |
| } |
| Token::Map { .. } => { |
| self.next_token()?; |
| self.visit_map(Some(fields.len()), Token::MapEnd, visitor) |
| } |
| _ => self.deserialize_any(visitor), |
| } |
| } |
| |
| fn is_human_readable(&self) -> bool { |
| panic!( |
| "Types which have different human-readable and compact representations \ |
| must explicitly mark their test cases with `serde_test::Configure`" |
| ); |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| |
| struct DeserializerSeqVisitor<'a, 'de: 'a> { |
| de: &'a mut Deserializer<'de>, |
| len: Option<usize>, |
| end: Token, |
| } |
| |
| impl<'de, 'a> SeqAccess<'de> for DeserializerSeqVisitor<'a, 'de> { |
| type Error = Error; |
| |
| fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error> |
| where |
| T: DeserializeSeed<'de>, |
| { |
| if self.de.peek_token_opt() == Some(self.end) { |
| return Ok(None); |
| } |
| self.len = self.len.map(|len| len.saturating_sub(1)); |
| seed.deserialize(&mut *self.de).map(Some) |
| } |
| |
| fn size_hint(&self) -> Option<usize> { |
| self.len |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| |
| struct DeserializerMapVisitor<'a, 'de: 'a> { |
| de: &'a mut Deserializer<'de>, |
| len: Option<usize>, |
| end: Token, |
| } |
| |
| impl<'de, 'a> MapAccess<'de> for DeserializerMapVisitor<'a, 'de> { |
| type Error = Error; |
| |
| fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error> |
| where |
| K: DeserializeSeed<'de>, |
| { |
| if self.de.peek_token_opt() == Some(self.end) { |
| return Ok(None); |
| } |
| self.len = self.len.map(|len| len.saturating_sub(1)); |
| seed.deserialize(&mut *self.de).map(Some) |
| } |
| |
| fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error> |
| where |
| V: DeserializeSeed<'de>, |
| { |
| seed.deserialize(&mut *self.de) |
| } |
| |
| fn size_hint(&self) -> Option<usize> { |
| self.len |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| |
| struct DeserializerEnumVisitor<'a, 'de: 'a> { |
| de: &'a mut Deserializer<'de>, |
| } |
| |
| impl<'de, 'a> EnumAccess<'de> for DeserializerEnumVisitor<'a, 'de> { |
| type Error = Error; |
| type Variant = Self; |
| |
| fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self), Error> |
| where |
| V: DeserializeSeed<'de>, |
| { |
| match self.de.peek_token()? { |
| Token::UnitVariant { variant: v, .. } |
| | Token::NewtypeVariant { variant: v, .. } |
| | Token::TupleVariant { variant: v, .. } |
| | Token::StructVariant { variant: v, .. } => { |
| let de = v.into_deserializer(); |
| let value = seed.deserialize(de)?; |
| Ok((value, self)) |
| } |
| _ => { |
| let value = seed.deserialize(&mut *self.de)?; |
| Ok((value, self)) |
| } |
| } |
| } |
| } |
| |
| impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> { |
| type Error = Error; |
| |
| fn unit_variant(self) -> Result<(), Error> { |
| match self.de.peek_token()? { |
| Token::UnitVariant { .. } => { |
| self.de.next_token()?; |
| Ok(()) |
| } |
| _ => Deserialize::deserialize(self.de), |
| } |
| } |
| |
| fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error> |
| where |
| T: DeserializeSeed<'de>, |
| { |
| match self.de.peek_token()? { |
| Token::NewtypeVariant { .. } => { |
| self.de.next_token()?; |
| seed.deserialize(self.de) |
| } |
| _ => seed.deserialize(self.de), |
| } |
| } |
| |
| fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| match self.de.peek_token()? { |
| Token::TupleVariant { len: enum_len, .. } => { |
| let token = self.de.next_token()?; |
| |
| if len == enum_len { |
| self.de |
| .visit_seq(Some(len), Token::TupleVariantEnd, visitor) |
| } else { |
| Err(unexpected(token)) |
| } |
| } |
| Token::Seq { |
| len: Some(enum_len), |
| } => { |
| let token = self.de.next_token()?; |
| |
| if len == enum_len { |
| self.de.visit_seq(Some(len), Token::SeqEnd, visitor) |
| } else { |
| Err(unexpected(token)) |
| } |
| } |
| _ => de::Deserializer::deserialize_any(self.de, visitor), |
| } |
| } |
| |
| fn struct_variant<V>( |
| self, |
| fields: &'static [&'static str], |
| visitor: V, |
| ) -> Result<V::Value, Error> |
| where |
| V: Visitor<'de>, |
| { |
| match self.de.peek_token()? { |
| Token::StructVariant { len: enum_len, .. } => { |
| let token = self.de.next_token()?; |
| |
| if fields.len() == enum_len { |
| self.de |
| .visit_map(Some(fields.len()), Token::StructVariantEnd, visitor) |
| } else { |
| Err(unexpected(token)) |
| } |
| } |
| Token::Map { |
| len: Some(enum_len), |
| } => { |
| let token = self.de.next_token()?; |
| |
| if fields.len() == enum_len { |
| self.de |
| .visit_map(Some(fields.len()), Token::MapEnd, visitor) |
| } else { |
| Err(unexpected(token)) |
| } |
| } |
| _ => de::Deserializer::deserialize_any(self.de, visitor), |
| } |
| } |
| } |
| |
| ////////////////////////////////////////////////////////////////////////// |
| |
| struct EnumMapVisitor<'a, 'de: 'a> { |
| de: &'a mut Deserializer<'de>, |
| variant: Option<Token>, |
| format: EnumFormat, |
| } |
| |
| enum EnumFormat { |
| Seq, |
| Map, |
| Any, |
| } |
| |
| impl<'a, 'de> EnumMapVisitor<'a, 'de> { |
| fn new(de: &'a mut Deserializer<'de>, variant: Token, format: EnumFormat) -> Self { |
| EnumMapVisitor { |
| de, |
| variant: Some(variant), |
| format, |
| } |
| } |
| } |
| |
| impl<'de, 'a> MapAccess<'de> for EnumMapVisitor<'a, 'de> { |
| type Error = Error; |
| |
| fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error> |
| where |
| K: DeserializeSeed<'de>, |
| { |
| match self.variant.take() { |
| Some(Token::Str(variant)) => seed.deserialize(variant.into_deserializer()).map(Some), |
| Some(Token::Bytes(variant)) => seed |
| .deserialize(BytesDeserializer { value: variant }) |
| .map(Some), |
| Some(Token::U32(variant)) => seed.deserialize(variant.into_deserializer()).map(Some), |
| Some(other) => Err(unexpected(other)), |
| None => Ok(None), |
| } |
| } |
| |
| fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error> |
| where |
| V: DeserializeSeed<'de>, |
| { |
| match self.format { |
| EnumFormat::Seq => { |
| let value = { |
| let visitor = DeserializerSeqVisitor { |
| de: self.de, |
| len: None, |
| end: Token::TupleVariantEnd, |
| }; |
| seed.deserialize(SeqAccessDeserializer::new(visitor))? |
| }; |
| assert_next_token(self.de, Token::TupleVariantEnd)?; |
| Ok(value) |
| } |
| EnumFormat::Map => { |
| let value = { |
| let visitor = DeserializerMapVisitor { |
| de: self.de, |
| len: None, |
| end: Token::StructVariantEnd, |
| }; |
| seed.deserialize(MapAccessDeserializer::new(visitor))? |
| }; |
| assert_next_token(self.de, Token::StructVariantEnd)?; |
| Ok(value) |
| } |
| EnumFormat::Any => seed.deserialize(&mut *self.de), |
| } |
| } |
| } |
| |
| struct BytesDeserializer { |
| value: &'static [u8], |
| } |
| |
| impl<'de> de::Deserializer<'de> for BytesDeserializer { |
| type Error = Error; |
| |
| fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> |
| where |
| V: de::Visitor<'de>, |
| { |
| visitor.visit_bytes(self.value) |
| } |
| |
| forward_to_deserialize_any! { |
| bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string |
| bytes byte_buf option unit unit_struct newtype_struct seq tuple |
| tuple_struct map struct enum identifier ignored_any |
| } |
| } |