use std::{io::Read, marker::PhantomData};
use crate::{
char_with_position::CharsWithPositionIterator,
error::AsonError,
lexer::Lexer,
normalizer::NormalizeSignedNumberIter,
peekable_iterator::PeekableIterator,
range::Range,
token::{NumberToken, Token, TokenWithRange},
utf8_char_iterator::UTF8CharIterator,
};
use serde::de::{self, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess};
pub fn de_from_str<T>(s: &str) -> Result<T, AsonError>
where
T: de::DeserializeOwned,
{
let mut chars = s.chars();
de_from_char_iterator(&mut chars)
}
pub fn de_from_reader<T, R: Read>(mut reader: R) -> Result<T, AsonError>
where
T: de::DeserializeOwned,
{
let mut char_iter = UTF8CharIterator::new(&mut reader);
de_from_char_iterator(&mut char_iter)
}
pub fn de_from_char_iterator<T>(
char_iterator: &mut dyn Iterator<Item = char>,
) -> Result<T, AsonError>
where
T: de::DeserializeOwned,
{
let char_position_iter = CharsWithPositionIterator::new(char_iterator);
let peekable_char_position_iter = PeekableIterator::new(char_position_iter);
let lexer = Lexer::new(peekable_char_position_iter);
let peekable_lexer_iter = PeekableIterator::new(lexer);
let normalizer_iter = NormalizeSignedNumberIter::new(peekable_lexer_iter);
let peekable_token_iter = PeekableIterator::new(normalizer_iter);
let mut deserializer = Deserializer::new(peekable_token_iter);
let value = T::deserialize(&mut deserializer)?;
match deserializer.next_token()? {
Some(_) => Err(AsonError::MessageWithRange(
"Extraneous token found after document end.".to_owned(),
deserializer.last_range,
)),
None => Ok(value),
}
}
pub fn list_from_char_iterator<T>(
char_iterator: &'_ mut dyn Iterator<Item = char>,
) -> Result<ListDeserializer<'_, T>, AsonError>
where
T: de::DeserializeOwned,
{
let char_position_iter = CharsWithPositionIterator::new(char_iterator);
let peekable_char_position_iter = PeekableIterator::new(char_position_iter);
let lexer = Lexer::new(peekable_char_position_iter);
let peekable_lexer_iter = PeekableIterator::new(lexer);
let normalizer_iter = NormalizeSignedNumberIter::new(peekable_lexer_iter);
let mut peekable_token_iter = PeekableIterator::new(normalizer_iter);
match peekable_token_iter.peek(0) {
Some(Ok(TokenWithRange { token, range })) => {
if token == &Token::BracketOpen {
peekable_token_iter.next();
} else {
return Err(AsonError::MessageWithRange(
"Expect a \"List\".".to_owned(),
*range,
));
}
}
Some(Err(e)) => return Err(e.clone()),
None => {
return Err(AsonError::UnexpectedEndOfDocument(
"Expect a \"List\".".to_owned(),
));
}
}
let deserializer = Deserializer::new(peekable_token_iter);
Ok(ListDeserializer::new(deserializer))
}
pub struct ListDeserializer<'a, T>
where
T: de::DeserializeOwned,
{
deserializer: Deserializer<'a>,
_marker: PhantomData<T>,
}
impl<'a, T> ListDeserializer<'a, T>
where
T: de::DeserializeOwned,
{
pub fn new(deserializer: Deserializer<'a>) -> Self {
Self {
deserializer,
_marker: PhantomData,
}
}
}
impl<'a, T> Iterator for ListDeserializer<'a, T>
where
T: de::DeserializeOwned,
{
type Item = Result<T, AsonError>;
fn next(&mut self) -> Option<Self::Item> {
if self
.deserializer
.peek_token_and_equals(0, &Token::BracketClose)
.ok()?
{
self.deserializer.next_token().ok()?; None
} else {
let value = T::deserialize(&mut self.deserializer);
Some(value)
}
}
}
type UpstreamIterator<'a> =
NormalizeSignedNumberIter<Lexer<CharsWithPositionIterator<&'a mut dyn Iterator<Item = char>>>>;
pub struct Deserializer<'a> {
upstream: PeekableIterator<Result<TokenWithRange, AsonError>, UpstreamIterator<'a>>,
last_range: Range,
}
impl<'a> Deserializer<'a> {
fn new(
upstream: PeekableIterator<Result<TokenWithRange, AsonError>, UpstreamIterator<'a>>,
) -> Self {
Self {
upstream,
last_range: Range::default(),
}
}
fn next_token(&mut self) -> Result<Option<Token>, AsonError> {
match self.upstream.next() {
Some(Ok(TokenWithRange { token, range })) => {
self.last_range = range;
Ok(Some(token))
}
Some(Err(e)) => Err(e),
None => Ok(None),
}
}
fn peek_token(&self, offset: usize) -> Result<Option<&Token>, AsonError> {
match self.upstream.peek(offset) {
Some(Ok(TokenWithRange { token, .. })) => Ok(Some(token)),
Some(Err(e)) => Err(e.clone()),
None => Ok(None),
}
}
#[allow(dead_code)]
fn peek_range(&self, offset: usize) -> Result<Option<&Range>, AsonError> {
match self.upstream.peek(offset) {
Some(Ok(TokenWithRange { range, .. })) => Ok(Some(range)),
Some(Err(e)) => Err(e.clone()),
None => Ok(None),
}
}
fn peek_token_and_equals(
&self,
offset: usize,
expected_token: &Token,
) -> Result<bool, AsonError> {
Ok(matches!(
self.peek_token(offset)?,
Some(token) if token == expected_token))
}
fn consume_token_and_assert(
&mut self,
expected_token: &Token,
token_description: &str,
) -> Result<(), AsonError> {
match self.next_token()? {
Some(token) => {
if &token == expected_token {
Ok(())
} else {
Err(AsonError::MessageWithRange(
format!("Expect token: {}.", token_description),
self.last_range,
))
}
}
None => Err(AsonError::UnexpectedEndOfDocument(format!(
"Expect token: {}.",
token_description
))),
}
}
fn consume_opening_parenthesis(&mut self) -> Result<(), AsonError> {
self.consume_token_and_assert(&Token::ParenthesisOpen, "opening parenthesis")
}
fn consume_closing_parenthesis(&mut self) -> Result<(), AsonError> {
self.consume_token_and_assert(&Token::ParenthesisClose, "closing parenthesis")
}
fn consume_closing_bracket(&mut self) -> Result<(), AsonError> {
self.consume_token_and_assert(&Token::BracketClose, "closing bracket")
}
fn consume_closing_brace(&mut self) -> Result<(), AsonError> {
self.consume_token_and_assert(&Token::BraceClose, "closing brace")
}
fn consume_colon(&mut self) -> Result<(), AsonError> {
self.consume_token_and_assert(&Token::Colon, "colon")
}
}
impl<'de> de::Deserializer<'de> for &mut Deserializer<'de> {
type Error = AsonError;
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
Err(AsonError::MessageWithRange(
"Unexpected value.".to_owned(),
self.last_range,
))
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Boolean(v)) => visitor.visit_bool(v),
Some(_) => Err(AsonError::MessageWithRange(
"Expect a \"Boolean\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect a \"Boolean\" value.".to_owned(),
)),
}
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Number(NumberToken::I8(v))) => visitor.visit_i8(v as i8),
Some(_) => Err(AsonError::MessageWithRange(
"Expect an \"i8\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect an \"i8\" value.".to_owned(),
)),
}
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Number(NumberToken::I16(v))) => visitor.visit_i16(v as i16),
Some(_) => Err(AsonError::MessageWithRange(
"Expect an \"i16\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect an \"i16\" value.".to_owned(),
)),
}
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Number(NumberToken::I32(v))) => visitor.visit_i32(v as i32),
Some(_) => Err(AsonError::MessageWithRange(
"Expect an \"i32\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect an \"i32\" value.".to_owned(),
)),
}
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Number(NumberToken::I64(v))) => visitor.visit_i64(v as i64),
Some(_) => Err(AsonError::MessageWithRange(
"Expect an \"i64\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect an \"i64\" value.".to_owned(),
)),
}
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Number(NumberToken::U8(v))) => visitor.visit_u8(v),
Some(_) => Err(AsonError::MessageWithRange(
"Expect an \"u8\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect an \"u8\" value.".to_owned(),
)),
}
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Number(NumberToken::U16(v))) => visitor.visit_u16(v),
Some(_) => Err(AsonError::MessageWithRange(
"Expect an \"u16\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect an \"u16\" value.".to_owned(),
)),
}
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Number(NumberToken::U32(v))) => visitor.visit_u32(v),
Some(_) => Err(AsonError::MessageWithRange(
"Expect an \"u32\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect an \"u32\" value.".to_owned(),
)),
}
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Number(NumberToken::U64(v))) => visitor.visit_u64(v),
Some(_) => Err(AsonError::MessageWithRange(
"Expect an \"u64\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect an \"u64\" value.".to_owned(),
)),
}
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Number(NumberToken::F32(v))) => visitor.visit_f32(v),
Some(_) => Err(AsonError::MessageWithRange(
"Expect a \"f32\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect a \"f32\" value.".to_owned(),
)),
}
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Number(NumberToken::F64(v))) => visitor.visit_f64(v),
Some(_) => Err(AsonError::MessageWithRange(
"Expect a \"f64\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect a \"f64\" value.".to_owned(),
)),
}
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Char(c)) => visitor.visit_char(c),
Some(_) => Err(AsonError::MessageWithRange(
"Expect a \"Char\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect a \"Char\" value.".to_owned(),
)),
}
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::String(s)) => visitor.visit_str(&s),
Some(_) => Err(AsonError::MessageWithRange(
"Expect a \"String\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect a \"String\" value.".to_owned(),
)),
}
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::String(s)) => visitor.visit_string(s),
Some(_) => Err(AsonError::MessageWithRange(
"Expect a \"String\" value.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect a \"String\" value.".to_owned(),
)),
}
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::HexadecimalByteData(d)) => visitor.visit_bytes(&d),
Some(_) => Err(AsonError::MessageWithRange(
"Expect \"Hexadecimal Byte Data\".".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect \"Hexadecimal Byte Data\".".to_owned(),
)),
}
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::HexadecimalByteData(d)) => visitor.visit_byte_buf(d),
Some(_) => Err(AsonError::MessageWithRange(
"Expect \"Hexadecimal Byte Data\".".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect \"Hexadecimal Byte Data\".".to_owned(),
)),
}
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Enumeration(type_name, variant_name)) => {
if type_name == "Option" {
if variant_name == "None"
&& !self.peek_token_and_equals(0, &Token::ParenthesisOpen)?
{
visitor.visit_none()
} else if variant_name == "Some"
&& self.peek_token_and_equals(0, &Token::ParenthesisOpen)?
{
self.next_token()?; let v = visitor.visit_some(&mut *self);
self.consume_closing_parenthesis()?;
v
} else {
Err(AsonError::MessageWithRange(
"Expect \"None\" or \"Some\" variant of enum \"Option\".".to_owned(),
self.last_range,
))
}
} else {
Err(AsonError::MessageWithRange(
"Expect the enum \"Option\".".to_owned(),
self.last_range,
))
}
}
Some(_) => Err(AsonError::MessageWithRange(
"Expect the enum \"Option\".".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect the enum \"Option\".".to_owned(),
)),
}
}
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
Err(AsonError::Message("Does not support Unit.".to_owned()))
}
fn deserialize_unit_struct<V>(
self,
_name: &'static str,
_visitor: V,
) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
Err(AsonError::Message(
"Does not support \"Unit\" style Struct.".to_owned(),
))
}
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
_visitor: V,
) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
Err(AsonError::Message(
"Does not support \"New-Type\" style Struct.".to_owned(),
))
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::BracketOpen) => {
let value = visitor.visit_seq(ArrayAccessor::new(self))?;
self.consume_closing_bracket()?; Ok(value)
}
Some(_) => Err(AsonError::MessageWithRange(
"Expect a \"List\".".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect a \"List\".".to_owned(),
)),
}
}
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::ParenthesisOpen) => {
let value = visitor.visit_seq(TupleAccessor::new(self))?;
self.consume_closing_parenthesis()?; Ok(value)
}
Some(_) => Err(AsonError::MessageWithRange(
"Expect a \"Tuple\".".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect a \"Tuple\".".to_owned(),
)),
}
}
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
_len: usize,
_visitor: V,
) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
Err(AsonError::Message(
"Does not support \"Tuple\" style Struct.".to_owned(),
))
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::BracketOpen) => {
let value = visitor.visit_map(MapAccessor::new(self))?;
self.consume_closing_bracket()?;
Ok(value)
}
Some(_) => Err(AsonError::MessageWithRange(
"Expect a \"Named List\".".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect a \"Named List\".".to_owned(),
)),
}
}
fn deserialize_struct<V>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::BraceOpen) => {
let value = visitor.visit_map(ObjectAccessor::new(self))?;
self.consume_closing_brace()?;
Ok(value)
}
Some(_) => Err(AsonError::MessageWithRange(
"Expect an \"Object\".".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect an \"Object\".".to_owned(),
)),
}
}
fn deserialize_enum<V>(
self,
name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Enumeration(type_name, variant_name)) => {
if type_name == name {
if self.peek_token_and_equals(0, &Token::ParenthesisOpen)? {
let v = visitor.visit_enum(VariantAccessor::new(self, &variant_name))?;
Ok(v)
} else if self.peek_token_and_equals(0, &Token::BraceOpen)? {
let v = visitor.visit_enum(VariantAccessor::new(self, &variant_name))?;
Ok(v)
} else {
visitor.visit_enum(variant_name.into_deserializer())
}
} else {
Err(AsonError::MessageWithRange(
format!("Expect an \"Enum\" \"{}\".", name,),
self.last_range,
))
}
}
Some(_) => Err(AsonError::MessageWithRange(
"Expect an \"Enum\".".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect an \"Enum\".".to_owned(),
)),
}
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
match self.next_token()? {
Some(Token::Identifier(id)) => visitor.visit_string(id),
Some(_) => Err(AsonError::MessageWithRange(
"Expect an identifier.".to_owned(),
self.last_range,
)),
None => Err(AsonError::UnexpectedEndOfDocument(
"Expect an identifier.".to_owned(),
)),
}
}
fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
unreachable!()
}
}
struct ArrayAccessor<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
}
impl<'a, 'de> ArrayAccessor<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>) -> Self {
Self { de }
}
}
impl<'de> SeqAccess<'de> for ArrayAccessor<'_, 'de> {
type Error = AsonError;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, AsonError>
where
T: de::DeserializeSeed<'de>,
{
if self.de.peek_token_and_equals(0, &Token::BracketClose)? {
return Ok(None);
}
if self.de.peek_token(0)?.is_none() {
return Err(AsonError::UnexpectedEndOfDocument(
"Incomplete List.".to_owned(),
));
}
seed.deserialize(&mut *self.de).map(Some)
}
}
struct TupleAccessor<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
}
impl<'a, 'de> TupleAccessor<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>) -> Self {
Self { de }
}
}
impl<'de> SeqAccess<'de> for TupleAccessor<'_, 'de> {
type Error = AsonError;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, AsonError>
where
T: de::DeserializeSeed<'de>,
{
if self.de.peek_token(0)?.is_none() {
return Err(AsonError::UnexpectedEndOfDocument(
"Incomplete Tuple.".to_owned(),
));
}
seed.deserialize(&mut *self.de).map(Some)
}
}
struct MapAccessor<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
}
impl<'a, 'de> MapAccessor<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>) -> Self {
Self { de }
}
}
impl<'de> MapAccess<'de> for MapAccessor<'_, 'de> {
type Error = AsonError;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, AsonError>
where
K: de::DeserializeSeed<'de>,
{
if self.de.peek_token_and_equals(0, &Token::BracketClose)? {
return Ok(None);
}
if self.de.peek_token(0)?.is_none() {
return Err(AsonError::UnexpectedEndOfDocument(
"Incomplete Named List.".to_owned(),
));
}
seed.deserialize(&mut *self.de).map(Some)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, AsonError>
where
V: de::DeserializeSeed<'de>,
{
self.de.consume_colon()?;
seed.deserialize(&mut *self.de)
}
}
struct ObjectAccessor<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
}
impl<'a, 'de> ObjectAccessor<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>) -> Self {
Self { de }
}
}
impl<'de> MapAccess<'de> for ObjectAccessor<'_, 'de> {
type Error = AsonError;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, AsonError>
where
K: de::DeserializeSeed<'de>,
{
if self.de.peek_token_and_equals(0, &Token::BraceClose)? {
return Ok(None);
}
if self.de.peek_token(0)?.is_none() {
return Err(AsonError::UnexpectedEndOfDocument(
"Incomplete Object.".to_owned(),
));
}
seed.deserialize(&mut *self.de).map(Some)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, AsonError>
where
V: de::DeserializeSeed<'de>,
{
self.de.consume_colon()?;
seed.deserialize(&mut *self.de)
}
}
struct VariantAccessor<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
variant_name: &'a str,
}
impl<'a, 'de> VariantAccessor<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>, variant_name: &'a str) -> Self {
Self { de, variant_name }
}
}
impl<'de> EnumAccess<'de> for VariantAccessor<'_, 'de> {
type Error = AsonError;
type Variant = Self;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), AsonError>
where
V: de::DeserializeSeed<'de>,
{
let de: de::value::StrDeserializer<AsonError> = self.variant_name.into_deserializer();
let value = seed.deserialize(de)?;
Ok((value, self))
}
}
impl<'de> VariantAccess<'de> for VariantAccessor<'_, 'de> {
type Error = AsonError;
fn unit_variant(self) -> Result<(), AsonError> {
unreachable!()
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, AsonError>
where
T: de::DeserializeSeed<'de>,
{
self.de.consume_opening_parenthesis()?; let v = seed.deserialize(&mut *self.de);
self.de.consume_closing_parenthesis()?; v
}
fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
de::Deserializer::deserialize_tuple(self.de, len, visitor)
}
fn struct_variant<V>(
self,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, AsonError>
where
V: de::Visitor<'de>,
{
de::Deserializer::deserialize_struct(self.de, "", fields, visitor)
}
}
#[cfg(test)]
mod tests {
use crate::{
de::{de_from_str, list_from_char_iterator},
error::AsonError,
utf8_char_iterator::UTF8CharIterator,
};
use pretty_assertions::assert_eq;
use serde::Deserialize;
use serde_bytes::ByteBuf;
use std::collections::HashMap;
#[test]
fn test_primitive_values() {
{
assert_eq!(de_from_str::<bool>(r#"true"#).unwrap(), true);
assert_eq!(de_from_str::<bool>(r#"false"#).unwrap(), false);
}
{
assert_eq!(de_from_str::<i8>(r#"11_i8"#).unwrap(), 11);
assert_eq!(de_from_str::<i16>(r#"13_i16"#).unwrap(), 13);
assert_eq!(de_from_str::<i32>(r#"17"#).unwrap(), 17);
assert_eq!(de_from_str::<i32>(r#"17_i32"#).unwrap(), 17);
assert_eq!(de_from_str::<i64>(r#"19_i64"#).unwrap(), 19);
}
{
assert_eq!(de_from_str::<u8>(r#"11_u8"#).unwrap(), 11);
assert_eq!(de_from_str::<u16>(r#"13_u16"#).unwrap(), 13);
assert_eq!(de_from_str::<u32>(r#"17_u32"#).unwrap(), 17);
assert_eq!(de_from_str::<u64>(r#"19_u64"#).unwrap(), 19);
}
{
assert_eq!(de_from_str::<f32>(r#"123_f32"#).unwrap(), 123_f32);
assert_eq!(de_from_str::<f32>(r#"-4.56_f32"#).unwrap(), -4.56_f32);
assert_eq!(
de_from_str::<f32>(r#"3.1415927_f32"#).unwrap(),
std::f32::consts::PI
);
assert_eq!(de_from_str::<f32>(r#"0_f32"#).unwrap(), 0_f32);
assert_eq!(de_from_str::<f32>(r#"-0_f32"#).unwrap(), 0_f32); assert!(de_from_str::<f32>(r#"NaN_f32"#).unwrap().is_nan()); assert_eq!(de_from_str::<f32>(r#"Inf_f32"#).unwrap(), f32::INFINITY);
assert_eq!(
de_from_str::<f32>(r#"-Inf_f32"#).unwrap(),
f32::NEG_INFINITY
);
}
{
assert_eq!(de_from_str::<f64>(r#"123.0"#).unwrap(), 123_f64);
assert_eq!(de_from_str::<f64>(r#"123_f64"#).unwrap(), 123_f64);
assert_eq!(de_from_str::<f64>(r#"-4.56"#).unwrap(), -4.56_f64);
assert_eq!(
de_from_str::<f64>(r#"3.141592653589793"#).unwrap(),
std::f64::consts::PI
);
assert_eq!(de_from_str::<f64>(r#"0_f64"#).unwrap(), 0_f64);
assert_eq!(de_from_str::<f64>(r#"-0_f64"#).unwrap(), 0_f64); assert!(de_from_str::<f64>(r#"NaN"#).unwrap().is_nan()); assert!(de_from_str::<f64>(r#"NaN_f64"#).unwrap().is_nan()); assert_eq!(de_from_str::<f64>(r#"Inf"#).unwrap(), f64::INFINITY);
assert_eq!(de_from_str::<f64>(r#"-Inf"#).unwrap(), f64::NEG_INFINITY);
assert_eq!(de_from_str::<f64>(r#"Inf_f64"#).unwrap(), f64::INFINITY);
assert_eq!(
de_from_str::<f64>(r#"-Inf_f64"#).unwrap(),
f64::NEG_INFINITY
);
}
{
assert_eq!(de_from_str::<char>(r#"'a'"#).unwrap(), 'a');
assert_eq!(de_from_str::<char>(r#"'文'"#).unwrap(), '文');
assert_eq!(de_from_str::<char>(r#"'🍒'"#).unwrap(), '🍒');
assert_eq!(de_from_str::<char>(r#"'\\'"#).unwrap(), '\\');
assert_eq!(de_from_str::<char>(r#"'\''"#).unwrap(), '\'');
assert_eq!(de_from_str::<char>(r#"'\"'"#).unwrap(), '"');
assert_eq!(de_from_str::<char>(r#"'\t'"#).unwrap(), '\t');
assert_eq!(de_from_str::<char>(r#"'\r'"#).unwrap(), '\r');
assert_eq!(de_from_str::<char>(r#"'\n'"#).unwrap(), '\n');
assert_eq!(de_from_str::<char>(r#"'\0'"#).unwrap(), '\0');
assert_eq!(de_from_str::<char>(r#"'\u{8431}'"#).unwrap(), '萱');
}
{
assert_eq!(
de_from_str::<String>(r#""abc文字🍒""#).unwrap(),
"abc文字🍒".to_owned()
);
assert_eq!(
de_from_str::<String>(r#""abc\"\'\\\t\0xyz""#).unwrap(),
"abc\"\'\\\t\0xyz".to_owned()
);
assert_eq!(
de_from_str::<String>(r#""hello\r\nworld""#).unwrap(),
"hello\r\nworld".to_owned()
);
assert_eq!(
de_from_str::<String>(r#""\u{5c0f}\u{8431}脚本""#).unwrap(),
"小萱脚本".to_owned()
);
assert_eq!(
de_from_str::<String>("\"a\n b\n c\"").unwrap(),
"a\n b\n c".to_owned()
);
assert_eq!(
de_from_str::<String>("\"a\\\n b\\\n c\"").unwrap(),
"abc".to_owned()
);
assert_eq!(
de_from_str::<String>(
r#"
r"a\nb"
"#
)
.unwrap(),
"a\\nb".to_owned()
);
assert_eq!(
de_from_str::<String>(
r##"
r#"a\n"&"\nb"#
"##
)
.unwrap(),
"a\\n\"&\"\\nb".to_owned()
);
assert_eq!(
de_from_str::<String>(
r#"
"""
a
b
c
"""
"#
)
.unwrap(),
"a\n b\n c".to_owned()
);
}
}
#[test]
fn test_hexadecimal_byte_data() {
assert_eq!(
de_from_str::<ByteBuf>(r#"h"0d 0f 11 13""#).unwrap(),
ByteBuf::from(vec![0x0d, 0x0f, 0x11, 0x13])
);
assert_eq!(
de_from_str::<ByteBuf>(r#"h"61 62 63""#).unwrap(),
ByteBuf::from(b"abc")
);
}
#[test]
fn test_enum_option() {
assert_eq!(de_from_str::<Option<i32>>(r#"Option::None"#).unwrap(), None);
assert_eq!(
de_from_str::<Option<i32>>(r#"Option::Some(123)"#).unwrap(),
Some(123)
);
}
#[test]
fn test_list() {
assert_eq!(
de_from_str::<Vec<i32>>(r#"[11,13,17,19]"#).unwrap(),
vec![11, 13, 17, 19]
);
assert_eq!(
de_from_str::<Vec<i32>>(r#"[11,13,17,19,]"#).unwrap(),
vec![11, 13, 17, 19]
);
assert_eq!(
de_from_str::<Vec<i32>>(r#"[11 13 17 19]"#).unwrap(),
vec![11, 13, 17, 19]
);
assert_eq!(
de_from_str::<Vec<i32>>(
r#"[
11
13
17
19
]"#
)
.unwrap(),
vec![11, 13, 17, 19]
);
assert_eq!(
de_from_str::<Vec<i32>>(
r#"[
11,
13,
17,
19
]"#
)
.unwrap(),
vec![11, 13, 17, 19]
);
assert_eq!(
de_from_str::<Vec<i32>>(
r#"[
11,
13,
17,
19,
]"#
)
.unwrap(),
vec![11, 13, 17, 19]
);
assert_eq!(
de_from_str::<Vec<u8>>(
r#"[
97_u8
98_u8
99_u8
]"#
)
.unwrap(),
b"abc"
);
assert_eq!(
de_from_str::<Vec<String>>(
r#"[
"foo"
"bar"
"2024"
]"#
)
.unwrap(),
vec!["foo", "bar", "2024"]
);
assert_eq!(
de_from_str::<Vec<Vec<i32>>>(
r#"[
[11,13]
[17,19]
[23,29]
]"#
)
.unwrap(),
vec![vec![11, 13], vec![17, 19], vec![23, 29]]
);
assert!(matches!(
de_from_str::<Vec<i32>>(r#"[11,13"#),
Err(AsonError::UnexpectedEndOfDocument(_))
));
}
#[test]
fn test_tuple() {
assert_eq!(
de_from_str::<(i32, i32, i32, i32)>(r#"(11, 13, 17, 19)"#).unwrap(),
(11, 13, 17, 19)
);
assert_eq!(
de_from_str::<(i32, i32, i32, i32)>(r#"(11, 13, 17, 19,)"#).unwrap(),
(11, 13, 17, 19)
);
assert_eq!(
de_from_str::<(i32, i32, i32, i32)>(r#"(11 13 17 19)"#).unwrap(),
(11, 13, 17, 19)
);
assert_eq!(
de_from_str::<(i32, i32, i32, i32)>(
r#"(
11
13
17
19
)"#
)
.unwrap(),
(11, 13, 17, 19)
);
assert_eq!(
de_from_str::<(i32, i32, i32, i32)>(
r#"(
11,
13,
17,
19
)"#
)
.unwrap(),
(11, 13, 17, 19)
);
assert_eq!(
de_from_str::<(i32, i32, i32, i32)>(
r#"(
11,
13,
17,
19,
)"#
)
.unwrap(),
(11, 13, 17, 19)
);
assert_eq!(
de_from_str::<[u8; 3]>(
r#"(
97_u8
98_u8
99_u8
)"#
)
.unwrap(),
b"abc".to_owned()
);
assert_eq!(
de_from_str::<(String, String, String)>(
r#"(
"foo", "bar", "2024", )"#
)
.unwrap(),
("foo".to_owned(), "bar".to_owned(), "2024".to_owned())
);
assert_eq!(
de_from_str::<((i32, i32), (i32, i32), (i32, i32))>(
r#"((11, 13), (17, 19), (23, 29))"#
)
.unwrap(),
((11, 13), (17, 19), (23, 29))
);
assert!(matches!(
de_from_str::<(i32, i32, i32, i32)>(r#"(11, 13"#),
Err(AsonError::UnexpectedEndOfDocument(_))
));
}
#[test]
fn test_object() {
#[derive(Deserialize, Debug, PartialEq)]
struct Object {
id: i32,
name: String,
checked: bool,
}
assert_eq!(
de_from_str::<Object>(r#"{id: 123, name: "foo", checked: true}"#).unwrap(),
Object {
id: 123,
name: "foo".to_owned(),
checked: true
}
);
assert_eq!(
de_from_str::<Object>(r#"{id: 123, name: "foo", checked: true,}"#).unwrap(),
Object {
id: 123,
name: "foo".to_owned(),
checked: true
}
);
assert_eq!(
de_from_str::<Object>(r#"{id: 123 name: "foo" checked: true}"#).unwrap(),
Object {
id: 123,
name: "foo".to_owned(),
checked: true
}
);
assert_eq!(
de_from_str::<Object>(
r#"{
id: 123
name: "foo"
checked: true
}"#
)
.unwrap(),
Object {
id: 123,
name: "foo".to_owned(),
checked: true
}
);
assert_eq!(
de_from_str::<Object>(
r#"{
id: 123,
name: "foo",
checked: true
}"#
)
.unwrap(),
Object {
id: 123,
name: "foo".to_owned(),
checked: true
}
);
assert_eq!(
de_from_str::<Object>(
r#"{
id: 123,
name: "foo",
checked: true,
}"#
)
.unwrap(),
Object {
id: 123,
name: "foo".to_owned(),
checked: true
}
);
#[derive(Deserialize, Debug, PartialEq)]
struct Address {
code: i32,
city: String,
}
#[derive(Deserialize, Debug, PartialEq)]
struct NestedObject {
id: i32,
name: String,
address: Box<Address>,
}
assert_eq!(
de_from_str::<NestedObject>(
r#"{
id: 456
name: "bar"
address: {
code: 518000
city: "sz"
}
}"#
)
.unwrap(),
NestedObject {
id: 456,
name: "bar".to_owned(),
address: Box::new(Address {
code: 518000,
city: "sz".to_owned()
})
}
);
#[derive(Deserialize, Debug, PartialEq)]
struct Member {
name: String,
#[serde(default)]
age: u32,
}
assert_eq!(
de_from_str::<Member>(r#"{name: "foo"}"#).unwrap(),
Member {
name: "foo".to_owned(),
age: 0
}
);
assert!(matches!(
de_from_str::<Object>(r#"{id: 123"#),
Err(AsonError::UnexpectedEndOfDocument(_))
));
}
#[test]
fn test_named_list() {
let s0 = r#"
[
"red": 0xff0000
"green": 0x00ff00
"blue": 0x0000ff
]
"#;
let m0: HashMap<String, i32> = de_from_str(s0).unwrap();
assert_eq!(m0.get("red").unwrap(), &0xff0000);
assert_eq!(m0.get("green").unwrap(), &0x00ff00);
assert_eq!(m0.get("blue").unwrap(), &0x0000ff);
let s1 = r#"
[
223: Option::Some("hello")
227: Option::None
229: Option::Some("world")
]
"#;
let m1: HashMap<i32, Option<String>> = de_from_str(s1).unwrap();
assert_eq!(m1.get(&223).unwrap(), &Option::Some("hello".to_owned()));
assert_eq!(m1.get(&227).unwrap(), &Option::None);
assert_eq!(m1.get(&229).unwrap(), &Option::Some("world".to_owned()));
}
#[test]
fn test_enum() {
#[derive(Deserialize, Debug, PartialEq)]
enum Color {
Red,
Green,
Blue,
}
assert_eq!(de_from_str::<Color>(r#"Color::Red"#).unwrap(), Color::Red);
assert_eq!(
de_from_str::<Color>(r#"Color::Green"#).unwrap(),
Color::Green
);
assert_eq!(de_from_str::<Color>(r#"Color::Blue"#).unwrap(), Color::Blue);
}
#[test]
fn test_variant_with_primitive_value() {
#[derive(Deserialize, Debug, PartialEq)]
enum Color {
Red,
Green,
Blue,
Grey(u8),
}
assert_eq!(de_from_str::<Color>(r#"Color::Red"#).unwrap(), Color::Red);
assert_eq!(
de_from_str::<Color>(r#"Color::Grey(11_u8)"#).unwrap(),
Color::Grey(11)
);
#[derive(Deserialize, Debug, PartialEq)]
enum Apperance {
Transparent,
Color(Color),
}
assert_eq!(
de_from_str::<Apperance>(r#"Apperance::Transparent"#).unwrap(),
Apperance::Transparent
);
assert_eq!(
de_from_str::<Apperance>(r#"Apperance::Color(Color::Blue)"#).unwrap(),
Apperance::Color(Color::Blue)
);
assert_eq!(
de_from_str::<Apperance>(r#"Apperance::Color(Color::Grey(13_u8))"#).unwrap(),
Apperance::Color(Color::Grey(13))
);
}
#[test]
fn test_variant_with_list_value() {
#[derive(Deserialize, Debug, PartialEq)]
enum Item {
Empty,
List(Vec<i32>),
}
assert_eq!(
de_from_str::<Vec<Item>>(
r#"[
Item::Empty
Item::List([11,13])
]"#
)
.unwrap(),
vec![Item::Empty, Item::List(vec![11, 13]),]
);
}
#[test]
fn test_variant_with_object_value() {
#[derive(Deserialize, Debug, PartialEq)]
struct Object {
id: i32,
name: String,
}
#[derive(Deserialize, Debug, PartialEq)]
enum Item {
Empty,
Object(Object),
}
assert_eq!(
de_from_str::<Vec<Item>>(
r#"[
Item::Empty
Item::Object({
id: 13
name: "foo"
})
]"#
)
.unwrap(),
vec![
Item::Empty,
Item::Object(Object {
id: 13,
name: "foo".to_owned()
}),
]
);
}
#[test]
fn test_tuple_like_variant() {
#[allow(clippy::upper_case_acronyms)]
#[derive(Deserialize, Debug, PartialEq)]
enum Color {
Grey(u8),
RGB(u8, u8, u8),
}
assert_eq!(
de_from_str::<Color>(r#"Color::Grey(127_u8)"#).unwrap(),
Color::Grey(127)
);
assert_eq!(
de_from_str::<Color>(r#"Color::RGB(255_u8,127_u8,63_u8)"#).unwrap(),
Color::RGB(255, 127, 63)
);
assert_eq!(
de_from_str::<Color>(r#"Color::RGB(255_u8,127_u8,63_u8,)"#).unwrap(),
Color::RGB(255, 127, 63)
);
assert_eq!(
de_from_str::<Color>(r#"Color::RGB(255_u8 127_u8 63_u8)"#).unwrap(),
Color::RGB(255, 127, 63)
);
assert_eq!(
de_from_str::<Color>(
r#"Color::RGB(
255_u8
127_u8
63_u8
)"#
)
.unwrap(),
Color::RGB(255, 127, 63)
);
assert_eq!(
de_from_str::<Color>(
r#"Color::RGB(
255_u8,
127_u8,
63_u8
)"#
)
.unwrap(),
Color::RGB(255, 127, 63)
);
assert_eq!(
de_from_str::<Color>(
r#"Color::RGB(
255_u8,
127_u8,
63_u8,
)"#
)
.unwrap(),
Color::RGB(255, 127, 63)
);
assert!(matches!(
de_from_str::<Color>(r#"Color::RGB(255_u8"#),
Err(AsonError::UnexpectedEndOfDocument(_))
));
}
#[test]
fn test_object_like_variant() {
#[derive(Deserialize, Debug, PartialEq)]
enum Shape {
Circle(i32),
Rect { width: i32, height: i32 },
}
assert_eq!(
de_from_str::<Shape>(r#"Shape::Circle(127)"#).unwrap(),
Shape::Circle(127)
);
assert_eq!(
de_from_str::<Shape>(
r#"Shape::Rect{
width: 200
height: 100
}"#
)
.unwrap(),
Shape::Rect {
width: 200,
height: 100
}
);
assert_eq!(
de_from_str::<Shape>(r#"Shape::Rect{width: 200, height: 100}"#).unwrap(),
Shape::Rect {
width: 200,
height: 100
}
);
assert_eq!(
de_from_str::<Shape>(r#"Shape::Rect{width: 200, height: 100,}"#).unwrap(),
Shape::Rect {
width: 200,
height: 100
}
);
assert_eq!(
de_from_str::<Shape>(
r#"Shape::Rect{
width: 200,
height: 100
}"#
)
.unwrap(),
Shape::Rect {
width: 200,
height: 100
}
);
assert_eq!(
de_from_str::<Shape>(
r#"Shape::Rect{
width: 200,
height: 100,
}"#
)
.unwrap(),
Shape::Rect {
width: 200,
height: 100
}
);
assert!(matches!(
de_from_str::<Shape>(r#"Shape::Rect{width: 200"#),
Err(AsonError::UnexpectedEndOfDocument(_))
));
}
#[test]
fn test_list_with_tuple_elements() {
assert_eq!(
de_from_str::<Vec<(i32, String)>>(
r#"[
(1, "foo")
(2, "bar")
]"#
)
.unwrap(),
vec![(1, "foo".to_owned()), (2, "bar".to_owned())]
);
}
#[test]
fn test_tuple_with_list_elements() {
assert_eq!(
de_from_str::<(Vec<i32>, Vec<String>)>(
r#"([
11
13
], [
"foo"
"bar"
])"#
)
.unwrap(),
(vec![11, 13], vec!["foo".to_owned(), "bar".to_owned()])
);
}
#[test]
fn test_list_with_object_elements() {
#[derive(Deserialize, Debug, PartialEq)]
struct Object {
id: i32,
name: String,
}
assert_eq!(
de_from_str::<Vec<Object>>(
r#"[
{
id: 11
name: "foo"
}
{
id: 13
name: "bar"
}
]"#
)
.unwrap(),
vec![
Object {
id: 11,
name: "foo".to_owned()
},
Object {
id: 13,
name: "bar".to_owned()
}
]
);
}
#[test]
fn test_object_with_list_field() {
#[derive(Deserialize, Debug, PartialEq)]
struct ObjectList {
id: i32,
items: Vec<i32>,
}
assert_eq!(
de_from_str::<ObjectList>(
r#"{
id: 456
items: [
11
13
17
19
]
}"#
)
.unwrap(),
ObjectList {
id: 456,
items: vec![11, 13, 17, 19]
}
);
}
#[test]
fn test_tuple_with_object_elements() {
#[derive(Deserialize, Debug, PartialEq)]
struct Object {
id: i32,
name: String,
}
assert_eq!(
de_from_str::<(i32, Object)>(
r#"(123, {
id: 11
name: "foo"
})"#
)
.unwrap(),
(
123,
Object {
id: 11,
name: "foo".to_owned()
}
)
);
}
#[test]
fn test_object_with_tuple_field() {
#[derive(Deserialize, Debug, PartialEq)]
struct ObjectDetail {
id: i32,
address: (i32, String),
}
assert_eq!(
de_from_str::<ObjectDetail>(
r#"{
id: 456
address: (11, "sz")
}"#
)
.unwrap(),
ObjectDetail {
id: 456,
address: (11, "sz".to_owned())
}
);
}
#[test]
fn test_deserialize_stream_list() {
let s = r#"[11 13]"#;
let mut chars = s.chars();
let mut de = list_from_char_iterator(&mut chars).unwrap();
assert_eq!(11, de.next().unwrap().unwrap());
assert_eq!(13, de.next().unwrap().unwrap());
assert!(de.next().is_none());
#[derive(Deserialize, Debug, PartialEq)]
struct Object {
id: i32,
name: String,
}
let s = r#"[
{
id: 11
name: "foo"
}
{
id: 13
name: "bar"
}
]"#;
let data = s.as_bytes();
let mut char_iter = UTF8CharIterator::new(data);
let mut de = list_from_char_iterator(&mut char_iter).unwrap();
let o1: Object = de.next().unwrap().unwrap();
assert_eq!(
o1,
Object {
id: 11,
name: "foo".to_owned()
}
);
let o2: Object = de.next().unwrap().unwrap();
assert_eq!(
o2,
Object {
id: 13,
name: "bar".to_owned()
}
);
assert!(de.next().is_none());
}
}