use alloc::{
boxed::Box,
slice,
string::String,
vec,
vec::Vec,
};
use core::{
fmt,
fmt::Debug,
marker::PhantomData,
mem::ManuallyDrop,
ptr::NonNull,
};
use serde::de::Unexpected;
#[derive(Clone, Debug)]
pub enum Token {
Bool(bool),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
I128(i128),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
U128(u128),
F32(f32),
F64(f64),
Char(char),
Str(String),
Bytes(Vec<u8>),
None,
Some,
Unit,
UnitStruct { name: &'static str },
UnitVariant {
name: &'static str,
variant_index: u32,
variant: &'static str,
},
NewtypeStruct { name: &'static str },
NewtypeVariant {
name: &'static str,
variant_index: u32,
variant: &'static str,
},
Seq { len: Option<usize> },
SeqEnd,
Tuple { len: usize },
TupleEnd,
TupleStruct { name: &'static str, len: usize },
TupleStructEnd,
TupleVariant {
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
},
TupleVariantEnd,
Map { len: Option<usize> },
MapEnd,
Field(&'static str),
SkippedField(&'static str),
Struct { name: &'static str, len: usize },
StructEnd,
StructVariant {
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
},
StructVariantEnd,
Unordered(&'static [&'static [Token]]),
}
#[derive(Clone, Debug, PartialEq)]
pub(crate) enum CanonicalToken {
Bool(bool),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
I128(i128),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
U128(u128),
F32(f32),
F64(f64),
Char(char),
Str(String),
Bytes(Vec<u8>),
None,
Some,
Unit,
UnitStruct {
name: &'static str,
},
UnitVariant {
name: &'static str,
variant_index: u32,
variant: &'static str,
},
NewtypeStruct {
name: &'static str,
},
NewtypeVariant {
name: &'static str,
variant_index: u32,
variant: &'static str,
},
Seq {
len: Option<usize>,
},
SeqEnd,
Tuple {
len: usize,
},
TupleEnd,
TupleStruct {
name: &'static str,
len: usize,
},
TupleStructEnd,
TupleVariant {
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
},
TupleVariantEnd,
Map {
len: Option<usize>,
},
MapEnd,
Field(&'static str),
SkippedField(&'static str),
Struct {
name: &'static str,
len: usize,
},
StructEnd,
StructVariant {
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
},
StructVariantEnd,
}
pub(crate) struct UnorderedTokens(pub(crate) &'static [&'static [Token]]);
impl TryFrom<Token> for CanonicalToken {
type Error = UnorderedTokens;
fn try_from(token: Token) -> Result<Self, Self::Error> {
match token {
Token::Bool(value) => Ok(CanonicalToken::Bool(value)),
Token::I8(value) => Ok(CanonicalToken::I8(value)),
Token::I16(value) => Ok(CanonicalToken::I16(value)),
Token::I32(value) => Ok(CanonicalToken::I32(value)),
Token::I64(value) => Ok(CanonicalToken::I64(value)),
Token::I128(value) => Ok(CanonicalToken::I128(value)),
Token::U8(value) => Ok(CanonicalToken::U8(value)),
Token::U16(value) => Ok(CanonicalToken::U16(value)),
Token::U32(value) => Ok(CanonicalToken::U32(value)),
Token::U64(value) => Ok(CanonicalToken::U64(value)),
Token::U128(value) => Ok(CanonicalToken::U128(value)),
Token::F32(value) => Ok(CanonicalToken::F32(value)),
Token::F64(value) => Ok(CanonicalToken::F64(value)),
Token::Char(value) => Ok(CanonicalToken::Char(value)),
Token::Str(value) => Ok(CanonicalToken::Str(value)),
Token::Bytes(value) => Ok(CanonicalToken::Bytes(value)),
Token::None => Ok(CanonicalToken::None),
Token::Some => Ok(CanonicalToken::Some),
Token::Unit => Ok(CanonicalToken::Unit),
Token::UnitStruct { name } => Ok(CanonicalToken::UnitStruct { name }),
Token::UnitVariant {
name,
variant_index,
variant,
} => Ok(CanonicalToken::UnitVariant {
name,
variant_index,
variant,
}),
Token::NewtypeStruct { name } => Ok(CanonicalToken::NewtypeStruct { name }),
Token::NewtypeVariant {
name,
variant_index,
variant,
} => Ok(CanonicalToken::NewtypeVariant {
name,
variant_index,
variant,
}),
Token::Seq { len } => Ok(CanonicalToken::Seq { len }),
Token::SeqEnd => Ok(CanonicalToken::SeqEnd),
Token::Tuple { len } => Ok(CanonicalToken::Tuple { len }),
Token::TupleEnd => Ok(CanonicalToken::TupleEnd),
Token::TupleStruct { name, len } => Ok(CanonicalToken::TupleStruct { name, len }),
Token::TupleStructEnd => Ok(CanonicalToken::TupleStructEnd),
Token::TupleVariant {
name,
variant_index,
variant,
len,
} => Ok(CanonicalToken::TupleVariant {
name,
variant_index,
variant,
len,
}),
Token::TupleVariantEnd => Ok(CanonicalToken::TupleVariantEnd),
Token::Map { len } => Ok(CanonicalToken::Map { len }),
Token::MapEnd => Ok(CanonicalToken::MapEnd),
Token::Field(value) => Ok(CanonicalToken::Field(value)),
Token::SkippedField(value) => Ok(CanonicalToken::SkippedField(value)),
Token::Struct { name, len } => Ok(CanonicalToken::Struct { name, len }),
Token::StructEnd => Ok(CanonicalToken::StructEnd),
Token::StructVariant {
name,
variant_index,
variant,
len,
} => Ok(CanonicalToken::StructVariant {
name,
variant_index,
variant,
len,
}),
Token::StructVariantEnd => Ok(CanonicalToken::StructVariantEnd),
Token::Unordered(tokens) => Err(UnorderedTokens(tokens)),
}
}
}
impl From<CanonicalToken> for Token {
fn from(token: CanonicalToken) -> Self {
match token {
CanonicalToken::Bool(value) => Token::Bool(value),
CanonicalToken::I8(value) => Token::I8(value),
CanonicalToken::I16(value) => Token::I16(value),
CanonicalToken::I32(value) => Token::I32(value),
CanonicalToken::I64(value) => Token::I64(value),
CanonicalToken::I128(value) => Token::I128(value),
CanonicalToken::U8(value) => Token::U8(value),
CanonicalToken::U16(value) => Token::U16(value),
CanonicalToken::U32(value) => Token::U32(value),
CanonicalToken::U64(value) => Token::U64(value),
CanonicalToken::U128(value) => Token::U128(value),
CanonicalToken::F32(value) => Token::F32(value),
CanonicalToken::F64(value) => Token::F64(value),
CanonicalToken::Char(value) => Token::Char(value),
CanonicalToken::Str(value) => Token::Str(value),
CanonicalToken::Bytes(value) => Token::Bytes(value),
CanonicalToken::None => Token::None,
CanonicalToken::Some => Token::Some,
CanonicalToken::Unit => Token::Unit,
CanonicalToken::UnitStruct { name } => Token::UnitStruct { name },
CanonicalToken::UnitVariant {
name,
variant_index,
variant,
} => Token::UnitVariant {
name,
variant_index,
variant,
},
CanonicalToken::NewtypeStruct { name } => Token::NewtypeStruct { name },
CanonicalToken::NewtypeVariant {
name,
variant_index,
variant,
} => Token::NewtypeVariant {
name,
variant_index,
variant,
},
CanonicalToken::Seq { len } => Token::Seq { len },
CanonicalToken::SeqEnd => Token::SeqEnd,
CanonicalToken::Tuple { len } => Token::Tuple { len },
CanonicalToken::TupleEnd => Token::TupleEnd,
CanonicalToken::TupleStruct { name, len } => Token::TupleStruct { name, len },
CanonicalToken::TupleStructEnd => Token::TupleStructEnd,
CanonicalToken::TupleVariant {
name,
variant_index,
variant,
len,
} => Token::TupleVariant {
name,
variant_index,
variant,
len,
},
CanonicalToken::TupleVariantEnd => Token::TupleVariantEnd,
CanonicalToken::Map { len } => Token::Map { len },
CanonicalToken::MapEnd => Token::MapEnd,
CanonicalToken::Field(value) => Token::Field(value),
CanonicalToken::SkippedField(value) => Token::SkippedField(value),
CanonicalToken::Struct { name, len } => Token::Struct { name, len },
CanonicalToken::StructEnd => Token::StructEnd,
CanonicalToken::StructVariant {
name,
variant_index,
variant,
len,
} => Token::StructVariant {
name,
variant_index,
variant,
len,
},
CanonicalToken::StructVariantEnd => Token::StructVariantEnd,
}
}
}
impl<'a> From<&'a mut CanonicalToken> for Unexpected<'a> {
fn from(token: &'a mut CanonicalToken) -> Self {
match token {
CanonicalToken::Bool(v) => Unexpected::Bool(*v),
CanonicalToken::I8(v) => Unexpected::Signed((*v).into()),
CanonicalToken::I16(v) => Unexpected::Signed((*v).into()),
CanonicalToken::I32(v) => Unexpected::Signed((*v).into()),
CanonicalToken::I64(v) => Unexpected::Signed(*v),
CanonicalToken::I128(..) => Unexpected::Other("i128"),
CanonicalToken::U8(v) => Unexpected::Unsigned((*v).into()),
CanonicalToken::U16(v) => Unexpected::Unsigned((*v).into()),
CanonicalToken::U32(v) => Unexpected::Unsigned((*v).into()),
CanonicalToken::U64(v) => Unexpected::Unsigned(*v),
CanonicalToken::U128(..) => Unexpected::Other("u128"),
CanonicalToken::F32(v) => Unexpected::Float((*v).into()),
CanonicalToken::F64(v) => Unexpected::Float(*v),
CanonicalToken::Char(v) => Unexpected::Char(*v),
CanonicalToken::Str(v) => Unexpected::Str(v),
CanonicalToken::Bytes(v) => Unexpected::Bytes(v),
CanonicalToken::Some | CanonicalToken::None => Unexpected::Option,
CanonicalToken::Unit | CanonicalToken::UnitStruct { .. } => Unexpected::Unit,
CanonicalToken::UnitVariant { .. } => Unexpected::UnitVariant,
CanonicalToken::NewtypeStruct { .. } => Unexpected::NewtypeStruct,
CanonicalToken::NewtypeVariant { .. } => Unexpected::NewtypeVariant,
CanonicalToken::Seq { .. } | CanonicalToken::Tuple { .. } => Unexpected::Seq,
CanonicalToken::SeqEnd => Unexpected::Other("SeqEnd"),
CanonicalToken::TupleEnd => Unexpected::Other("TupleEnd"),
CanonicalToken::TupleStruct { .. } => Unexpected::Other("TupleStruct"),
CanonicalToken::TupleStructEnd => Unexpected::Other("TupleStructEnd"),
CanonicalToken::TupleVariant { .. } => Unexpected::TupleVariant,
CanonicalToken::TupleVariantEnd => Unexpected::Other("TupleVariantEnd"),
CanonicalToken::Map { .. } => Unexpected::Map,
CanonicalToken::MapEnd => Unexpected::Other("MapEnd"),
CanonicalToken::Field(..) => Unexpected::Other("Field"),
CanonicalToken::SkippedField(..) => Unexpected::Other("SkippedField"),
CanonicalToken::Struct { .. } => Unexpected::Other("Struct"),
CanonicalToken::StructEnd => Unexpected::Other("StructEnd"),
CanonicalToken::StructVariant { .. } => Unexpected::StructVariant,
CanonicalToken::StructVariantEnd => Unexpected::Other("StructVariantEnd"),
}
}
}
#[derive(Clone, Debug)]
pub struct Tokens(pub(crate) Vec<CanonicalToken>);
#[derive(Clone, Debug)]
struct Context {
current: slice::Iter<'static, Token>,
remaining: Vec<&'static [Token]>,
#[allow(clippy::struct_field_names)] nested_context: Option<Box<Context>>,
}
impl Context {
fn new(current: slice::Iter<'static, Token>, remaining: Vec<&'static [Token]>) -> Self {
Self {
current,
remaining,
nested_context: None,
}
}
fn nest(self, mut split: Split) -> Vec<Self> {
for context in &mut split.contexts {
context.nested_context = Some(Box::new(self.clone()));
}
split.contexts
}
}
impl Iterator for Context {
type Item = &'static Token;
fn next(&mut self) -> Option<Self::Item> {
self.current.next()
}
}
#[derive(Debug)]
struct Split {
contexts: Vec<Context>,
}
impl Split {
fn search<'a, I>(mut self, mut tokens: I) -> bool
where
I: Iterator<Item = &'a CanonicalToken>,
{
while let Some(canonical_tokens) = self.next() {
if canonical_tokens.is_empty() {
return false;
}
if let Some(token) = tokens.next() {
self.contexts = self
.contexts
.into_iter()
.zip(canonical_tokens)
.filter_map(|(context, canonical_token)| {
if *token == canonical_token {
Some(context)
} else {
None
}
})
.collect();
} else {
return false;
}
}
true
}
}
impl Iterator for Split {
type Item = Vec<CanonicalToken>;
fn next(&mut self) -> Option<Self::Item> {
if self.contexts.is_empty() {
return Some(Vec::new());
}
let mut result = Vec::with_capacity(self.contexts.len());
let mut index = 0;
while index < self.contexts.len() {
match self.contexts[index]
.next()
.cloned()
.map(CanonicalToken::try_from)
{
Some(Ok(canonical_token)) => {
result.push(canonical_token);
index += 1;
}
Some(Err(unordered_tokens)) => {
let context = self.contexts.swap_remove(index);
if let Ok(split) = unordered_tokens.try_into() {
self.contexts.extend(context.nest(split));
}
}
None => {
let context = self.contexts.swap_remove(index);
if let Ok(split) = Split::try_from(context) {
self.contexts.extend(split.contexts);
}
}
}
}
if result.is_empty() {
None
} else {
Some(result)
}
}
}
impl<'a> TryFrom<&'a [&'static [Token]]> for Split {
type Error = ();
fn try_from(value: &'a [&'static [Token]]) -> Result<Self, Self::Error> {
if value.is_empty() {
Err(())
} else {
Ok(Self {
contexts: (0..value.len())
.map(|index| {
Context::new(
value[index].iter(),
value
.iter()
.enumerate()
.filter_map(
|(i, tokens)| if i == index { None } else { Some(*tokens) },
)
.collect(),
)
})
.collect(),
})
}
}
}
impl TryFrom<Context> for Split {
type Error = ();
fn try_from(value: Context) -> Result<Self, Self::Error> {
if let Ok(mut split) = Split::try_from(value.remaining.as_slice()) {
for context in &mut split.contexts {
context.nested_context.clone_from(&value.nested_context);
}
Ok(split)
} else if let Some(nested_context) = value.nested_context {
Ok(Split {
contexts: vec![*nested_context],
})
} else {
Err(())
}
}
}
impl TryFrom<UnorderedTokens> for Split {
type Error = ();
fn try_from(value: UnorderedTokens) -> Result<Self, Self::Error> {
value.0.try_into()
}
}
impl<T> PartialEq<T> for Tokens
where
for<'a> &'a T: IntoIterator<Item = &'a Token>,
{
fn eq(&self, other: &T) -> bool {
let mut self_iter = self.0.iter();
for token in other {
if !match CanonicalToken::try_from(token.clone()) {
Ok(canonical_token) => {
if let Some(self_token) = self_iter.next() {
canonical_token == *self_token
} else {
false
}
}
Err(unordered_tokens) => Split::try_from(unordered_tokens)
.map(|split| split.search(&mut self_iter))
.unwrap_or(true),
} {
return false;
}
}
if self_iter.next().is_some() {
return false;
}
true
}
}
impl IntoIterator for Tokens {
type Item = Token;
type IntoIter = IntoIter;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
token_iter: self.0.into_iter(),
}
}
}
pub struct IntoIter {
token_iter: vec::IntoIter<CanonicalToken>,
}
impl Iterator for IntoIter {
type Item = Token;
fn next(&mut self) -> Option<Self::Item> {
self.token_iter.next().map(From::from)
}
}
pub(crate) struct OwningIter<'a> {
buf: NonNull<CanonicalToken>,
ptr: *mut CanonicalToken,
end: *mut CanonicalToken,
cap: usize,
lifetime: PhantomData<&'a ()>,
}
impl OwningIter<'_> {
pub(crate) fn new(tokens: Tokens) -> Self {
let mut tokens = ManuallyDrop::new(tokens);
Self {
buf: unsafe { NonNull::new_unchecked(tokens.0.as_mut_ptr()) },
ptr: tokens.0.as_mut_ptr(),
end: unsafe { tokens.0.as_mut_ptr().add(tokens.0.len()) },
cap: tokens.0.capacity(),
lifetime: PhantomData,
}
}
fn as_slice(&self) -> &[CanonicalToken] {
unsafe {
slice::from_raw_parts(
self.ptr,
#[allow(clippy::cast_sign_loss)]
{
self.end.offset_from(self.ptr) as usize
},
)
}
}
}
impl<'a> Iterator for OwningIter<'a> {
type Item = &'a mut CanonicalToken;
fn next(&mut self) -> Option<Self::Item> {
if self.ptr == self.end {
None
} else {
let current = self.ptr;
self.ptr = unsafe { self.ptr.add(1) };
Some(unsafe { &mut *current })
}
}
}
impl Debug for OwningIter<'_> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_tuple("OwningIter")
.field(&self.as_slice())
.finish()
}
}
impl Drop for OwningIter<'_> {
fn drop(&mut self) {
unsafe {
Vec::from_raw_parts(
self.buf.as_ptr(),
#[allow(clippy::cast_sign_loss)]
{
self.end.offset_from(self.buf.as_ptr()) as usize
},
self.cap,
)
};
}
}
#[cfg(test)]
mod tests {
use super::{
CanonicalToken,
OwningIter,
Token,
Tokens,
};
use alloc::{
borrow::ToOwned,
format,
vec,
vec::Vec,
};
use claims::{
assert_matches,
assert_none,
assert_some,
assert_some_eq,
};
use serde::de::Unexpected;
#[test]
fn tokens_bool_eq() {
assert_eq!(
Tokens(vec![CanonicalToken::Bool(true)]),
[Token::Bool(true)]
);
}
#[test]
fn tokens_bool_ne() {
assert_ne!(
Tokens(vec![CanonicalToken::Bool(true)]),
[Token::Bool(false)]
);
}
#[test]
fn tokens_variant_ne() {
assert_ne!(Tokens(vec![CanonicalToken::Bool(true)]), [Token::U16(42)]);
}
#[test]
fn tokens_empty_eq() {
assert_eq!(Tokens(vec![]), []);
}
#[test]
fn tokens_multiple_eq() {
assert_eq!(
Tokens(vec![CanonicalToken::Bool(true), CanonicalToken::U8(42)]),
[Token::Bool(true), Token::U8(42)]
);
}
#[test]
fn tokens_multiple_ne_values() {
assert_ne!(
Tokens(vec![CanonicalToken::Bool(true), CanonicalToken::U8(42)]),
[Token::Bool(false), Token::U8(42)]
);
}
#[test]
fn tokens_multiple_ne_shorter() {
assert_ne!(
Tokens(vec![CanonicalToken::Bool(true), CanonicalToken::U8(42)]),
[Token::Bool(true)]
);
}
#[test]
fn tokens_multiple_ne_longer() {
assert_ne!(
Tokens(vec![CanonicalToken::Bool(true), CanonicalToken::U8(42)]),
[Token::Bool(true), Token::U8(42), Token::U8(42)]
);
}
#[test]
fn tokens_unordered_eq_same_order() {
assert_eq!(
Tokens(vec![CanonicalToken::Bool(true), CanonicalToken::U8(42)]),
[Token::Unordered(&[&[Token::Bool(true)], &[Token::U8(42)]])],
);
}
#[test]
fn tokens_unordered_eq_different_order() {
assert_eq!(
Tokens(vec![CanonicalToken::U8(42), CanonicalToken::Bool(true)]),
[Token::Unordered(&[&[Token::Bool(true)], &[Token::U8(42)]])],
);
}
#[test]
fn tokens_unordered_eq_within_other_tokens() {
assert_eq!(
Tokens(vec![
CanonicalToken::Char('a'),
CanonicalToken::U8(42),
CanonicalToken::Bool(true),
CanonicalToken::I16(-42)
]),
[
Token::Char('a'),
Token::Unordered(&[&[Token::Bool(true)], &[Token::U8(42)]]),
Token::I16(-42)
],
);
}
#[test]
fn tokens_unordered_eq_multiple_tokens() {
assert_eq!(
Tokens(vec![
CanonicalToken::U8(42),
CanonicalToken::Bool(true),
CanonicalToken::Char('a')
]),
[Token::Unordered(&[
&[Token::Bool(true), Token::Char('a')],
&[Token::U8(42)]
])],
);
}
#[test]
fn tokens_unordered_ne_empty() {
assert_ne!(
Tokens(vec![CanonicalToken::Bool(true)]),
[Token::Unordered(&[])],
);
}
#[test]
fn tokens_unordered_ne_variant() {
assert_ne!(
Tokens(vec![CanonicalToken::Bool(true)]),
[Token::Unordered(&[&[Token::I8(42)]])],
);
}
#[test]
fn tokens_unordered_ne_value() {
assert_ne!(
Tokens(vec![CanonicalToken::Bool(true)]),
[Token::Unordered(&[&[Token::Bool(false)]])],
);
}
#[test]
fn tokens_unordered_nested() {
assert_eq!(
Tokens(vec![
CanonicalToken::Unit,
CanonicalToken::U8(4),
CanonicalToken::U8(3),
CanonicalToken::U8(1),
CanonicalToken::U8(2),
CanonicalToken::Bool(true)
]),
[Token::Unordered(&[
&[Token::Bool(true)],
&[Token::Unordered(&[
&[Token::U8(1), Token::U8(2)],
&[Token::U8(3)],
])],
&[Token::Unit, Token::U8(4)],
])]
);
}
#[test]
fn tokens_unordered_empty() {
assert_eq!(
Tokens(vec![CanonicalToken::Unit,]),
[Token::Unordered(&[]), Token::Unit]
);
}
#[test]
fn tokens_unordered_empty_nested() {
assert_eq!(
Tokens(vec![CanonicalToken::Unit,]),
[Token::Unordered(&[&[Token::Unordered(&[])]]), Token::Unit]
);
}
#[test]
fn tokens_unordered_empty_at_end() {
assert_eq!(
Tokens(vec![CanonicalToken::Unit,]),
[Token::Unit, Token::Unordered(&[])]
);
}
#[test]
fn tokens_unordered_nonempty_at_end() {
assert_ne!(
Tokens(vec![CanonicalToken::Unit,]),
[Token::Unit, Token::Unordered(&[&[Token::Unit]])]
);
}
#[test]
fn tokens_end_within_unordered() {
assert_ne!(
Tokens(vec![CanonicalToken::Unit,]),
[Token::Unordered(&[&[Token::Unit,], &[Token::Unit]])]
);
}
#[test]
fn tokens_end_within_unordered_more_tokens() {
assert_ne!(
Tokens(vec![CanonicalToken::Unit,]),
[Token::Unordered(&[&[Token::Unit, Token::Unit]])]
);
}
#[test]
fn tokens_end_within_unordered_nested_empty() {
assert_eq!(
Tokens(vec![CanonicalToken::Unit,]),
[Token::Unordered(&[&[Token::Unit, Token::Unordered(&[])]])]
);
}
#[test]
fn tokens_end_within_unordered_nested_nonempty() {
assert_ne!(
Tokens(vec![CanonicalToken::Unit,]),
[Token::Unordered(&[&[
Token::Unit,
Token::Unordered(&[&[Token::Unit, Token::Unit], &[Token::Unit]])
]])]
);
}
#[test]
fn token_from_canonical_token_bool() {
assert_matches!(Token::from(CanonicalToken::Bool(true)), Token::Bool(true))
}
#[test]
fn token_from_canonical_token_i8() {
assert_matches!(Token::from(CanonicalToken::I8(42)), Token::I8(42))
}
#[test]
fn token_from_canonical_token_i16() {
assert_matches!(Token::from(CanonicalToken::I16(42)), Token::I16(42))
}
#[test]
fn token_from_canonical_token_i32() {
assert_matches!(Token::from(CanonicalToken::I32(42)), Token::I32(42))
}
#[test]
fn token_from_canonical_token_i64() {
assert_matches!(Token::from(CanonicalToken::I64(42)), Token::I64(42))
}
#[test]
fn token_from_canonical_token_i128() {
assert_matches!(Token::from(CanonicalToken::I128(42)), Token::I128(42))
}
#[test]
fn token_from_canonical_token_u8() {
assert_matches!(Token::from(CanonicalToken::U8(42)), Token::U8(42))
}
#[test]
fn token_from_canonical_token_u16() {
assert_matches!(Token::from(CanonicalToken::U16(42)), Token::U16(42))
}
#[test]
fn token_from_canonical_token_u32() {
assert_matches!(Token::from(CanonicalToken::U32(42)), Token::U32(42))
}
#[test]
fn token_from_canonical_token_u64() {
assert_matches!(Token::from(CanonicalToken::U64(42)), Token::U64(42))
}
#[test]
fn token_from_canonical_token_u128() {
assert_matches!(Token::from(CanonicalToken::U128(42)), Token::U128(42))
}
#[test]
fn token_from_canonical_token_f32() {
assert_matches!(Token::from(CanonicalToken::F32(42.9)), Token::F32(_))
}
#[test]
fn token_from_canonical_token_f64() {
assert_matches!(Token::from(CanonicalToken::F64(42.9)), Token::F64(_))
}
#[test]
fn token_from_canonical_token_char() {
assert_matches!(Token::from(CanonicalToken::Char('a')), Token::Char('a'))
}
#[test]
fn token_from_canonical_token_str() {
assert_matches!(
Token::from(CanonicalToken::Str("foo".to_owned())),
Token::Str(_)
)
}
#[test]
fn token_from_canonical_token_bytes() {
assert_matches!(
Token::from(CanonicalToken::Bytes(b"foo".to_vec())),
Token::Bytes(_)
)
}
#[test]
fn token_from_canonical_token_none() {
assert_matches!(Token::from(CanonicalToken::None), Token::None)
}
#[test]
fn token_from_canonical_token_some() {
assert_matches!(Token::from(CanonicalToken::Some), Token::Some)
}
#[test]
fn token_from_canonical_token_unit() {
assert_matches!(Token::from(CanonicalToken::Unit), Token::Unit)
}
#[test]
fn token_from_canonical_token_unit_struct() {
assert_matches!(
Token::from(CanonicalToken::UnitStruct { name: "foo" }),
Token::UnitStruct { name: "foo" }
)
}
#[test]
fn token_from_canonical_token_unit_variant() {
assert_matches!(
Token::from(CanonicalToken::UnitVariant {
name: "foo",
variant_index: 42,
variant: "bar"
}),
Token::UnitVariant {
name: "foo",
variant_index: 42,
variant: "bar"
}
)
}
#[test]
fn token_from_canonical_token_newtype_struct() {
assert_matches!(
Token::from(CanonicalToken::NewtypeStruct { name: "foo" }),
Token::NewtypeStruct { name: "foo" }
)
}
#[test]
fn token_from_canonical_token_newtype_variant() {
assert_matches!(
Token::from(CanonicalToken::NewtypeVariant {
name: "foo",
variant_index: 42,
variant: "bar"
}),
Token::NewtypeVariant {
name: "foo",
variant_index: 42,
variant: "bar"
}
)
}
#[test]
fn token_from_canonical_token_seq() {
assert_matches!(
Token::from(CanonicalToken::Seq { len: Some(42) }),
Token::Seq { len: Some(42) }
)
}
#[test]
fn token_from_canonical_token_seq_end() {
assert_matches!(Token::from(CanonicalToken::SeqEnd), Token::SeqEnd)
}
#[test]
fn token_from_canonical_token_tuple() {
assert_matches!(
Token::from(CanonicalToken::Tuple { len: 42 }),
Token::Tuple { len: 42 }
)
}
#[test]
fn token_from_canonical_token_tuple_end() {
assert_matches!(Token::from(CanonicalToken::TupleEnd), Token::TupleEnd)
}
#[test]
fn token_from_canonical_token_tuple_struct() {
assert_matches!(
Token::from(CanonicalToken::TupleStruct {
name: "foo",
len: 42
}),
Token::TupleStruct {
name: "foo",
len: 42
}
)
}
#[test]
fn token_from_canonical_token_tuple_struct_end() {
assert_matches!(
Token::from(CanonicalToken::TupleStructEnd),
Token::TupleStructEnd
)
}
#[test]
fn token_from_canonical_token_tuple_variant() {
assert_matches!(
Token::from(CanonicalToken::TupleVariant {
name: "foo",
variant_index: 42,
variant: "bar",
len: 42
}),
Token::TupleVariant {
name: "foo",
variant_index: 42,
variant: "bar",
len: 42
}
)
}
#[test]
fn token_from_canonical_token_tuple_variant_end() {
assert_matches!(
Token::from(CanonicalToken::TupleVariantEnd),
Token::TupleVariantEnd
)
}
#[test]
fn token_from_canonical_token_map() {
assert_matches!(
Token::from(CanonicalToken::Map { len: Some(42) }),
Token::Map { len: Some(42) }
)
}
#[test]
fn token_from_canonical_token_map_end() {
assert_matches!(Token::from(CanonicalToken::MapEnd), Token::MapEnd)
}
#[test]
fn token_from_canonical_token_field() {
assert_matches!(
Token::from(CanonicalToken::Field("foo")),
Token::Field("foo")
)
}
#[test]
fn token_from_canonical_token_skipped_field() {
assert_matches!(
Token::from(CanonicalToken::SkippedField("foo")),
Token::SkippedField("foo")
)
}
#[test]
fn token_from_canonical_token_struct() {
assert_matches!(
Token::from(CanonicalToken::Struct {
name: "foo",
len: 42
}),
Token::Struct {
name: "foo",
len: 42
}
)
}
#[test]
fn token_from_canonical_token_struct_end() {
assert_matches!(Token::from(CanonicalToken::StructEnd), Token::StructEnd)
}
#[test]
fn token_from_canonical_token_struct_variant() {
assert_matches!(
Token::from(CanonicalToken::StructVariant {
name: "foo",
variant_index: 42,
variant: "bar",
len: 42
}),
Token::StructVariant {
name: "foo",
variant_index: 42,
variant: "bar",
len: 42
}
)
}
#[test]
fn token_from_canonical_token_struct_variant_end() {
assert_matches!(
Token::from(CanonicalToken::StructVariantEnd),
Token::StructVariantEnd
)
}
#[test]
fn unexpected_from_canonical_token_bool() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::Bool(true)),
Unexpected::Bool(true)
)
}
#[test]
fn unexpected_from_canonical_token_i8() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::I8(42)),
Unexpected::Signed(42)
)
}
#[test]
fn unexpected_from_canonical_token_i16() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::I16(42)),
Unexpected::Signed(42)
)
}
#[test]
fn unexpected_from_canonical_token_i32() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::I32(42)),
Unexpected::Signed(42)
)
}
#[test]
fn unexpected_from_canonical_token_i64() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::I64(42)),
Unexpected::Signed(42)
)
}
#[test]
fn unexpected_from_canonical_token_i128() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::I128(42)),
Unexpected::Other("i128")
)
}
#[test]
fn unexpected_from_canonical_token_u8() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::U8(42)),
Unexpected::Unsigned(42)
)
}
#[test]
fn unexpected_from_canonical_token_u16() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::U16(42)),
Unexpected::Unsigned(42)
)
}
#[test]
fn unexpected_from_canonical_token_u32() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::U32(42)),
Unexpected::Unsigned(42)
)
}
#[test]
fn unexpected_from_canonical_token_u64() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::U64(42)),
Unexpected::Unsigned(42)
)
}
#[test]
fn unexpected_from_canonical_token_u128() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::U128(42)),
Unexpected::Other("u128")
)
}
#[test]
fn unexpected_from_canonical_token_f32() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::F32(42.)),
Unexpected::Float(42.)
)
}
#[test]
fn unexpected_from_canonical_token_f64() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::F64(42.)),
Unexpected::Float(42.)
)
}
#[test]
fn unexpected_from_canonical_token_char() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::Char('a')),
Unexpected::Char('a')
)
}
#[test]
fn unexpected_from_canonical_token_str() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::Str("foo".to_owned())),
Unexpected::Str("foo")
)
}
#[test]
fn unexpected_from_canonical_token_bytes() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::Bytes(b"foo".to_vec())),
Unexpected::Bytes(b"foo")
)
}
#[test]
fn unexpected_from_canonical_token_some() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::Some),
Unexpected::Option
)
}
#[test]
fn unexpected_from_canonical_token_none() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::None),
Unexpected::Option
)
}
#[test]
fn unexpected_from_canonical_token_unit() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::Unit),
Unexpected::Unit
)
}
#[test]
fn unexpected_from_canonical_token_unit_struct() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::UnitStruct { name: "foo" }),
Unexpected::Unit
)
}
#[test]
fn unexpected_from_canonical_token_unit_variant() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::UnitVariant {
name: "foo",
variant_index: 0,
variant: "bar"
}),
Unexpected::UnitVariant
)
}
#[test]
fn unexpected_from_canonical_token_newtype_struct() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::NewtypeStruct { name: "foo" }),
Unexpected::NewtypeStruct
)
}
#[test]
fn unexpected_from_canonical_token_newtype_variant() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::NewtypeVariant {
name: "foo",
variant_index: 0,
variant: "bar"
}),
Unexpected::NewtypeVariant
)
}
#[test]
fn unexpected_from_canonical_token_seq() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::Seq { len: None }),
Unexpected::Seq
)
}
#[test]
fn unexpected_from_canonical_token_tuple() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::Tuple { len: 0 }),
Unexpected::Seq
)
}
#[test]
fn unexpected_from_canonical_token_seq_end() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::SeqEnd),
Unexpected::Other("SeqEnd")
)
}
#[test]
fn unexpected_from_canonical_token_tuple_end() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::TupleEnd),
Unexpected::Other("TupleEnd")
)
}
#[test]
fn unexpected_from_canonical_token_tuple_struct() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::TupleStruct {
name: "foo",
len: 0
}),
Unexpected::Other("TupleStruct")
)
}
#[test]
fn unexpected_from_canonical_token_tuple_struct_end() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::TupleStructEnd),
Unexpected::Other("TupleStructEnd")
)
}
#[test]
fn unexpected_from_canonical_token_tuple_variant() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::TupleVariant {
name: "foo",
variant_index: 0,
variant: "bar",
len: 0
}),
Unexpected::TupleVariant
)
}
#[test]
fn unexpected_from_canonical_token_tuple_variant_end() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::TupleVariantEnd),
Unexpected::Other("TupleVariantEnd")
)
}
#[test]
fn unexpected_from_canonical_token_map() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::Map { len: None }),
Unexpected::Map
)
}
#[test]
fn unexpected_from_canonical_token_map_end() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::MapEnd),
Unexpected::Other("MapEnd")
)
}
#[test]
fn unexpected_from_canonical_token_field() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::Field("foo")),
Unexpected::Other("Field")
)
}
#[test]
fn unexpected_from_canonical_token_skipped_field() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::SkippedField("foo")),
Unexpected::Other("SkippedField")
)
}
#[test]
fn unexpected_from_canonical_token_struct() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::Struct {
name: "foo",
len: 0
}),
Unexpected::Other("Struct")
)
}
#[test]
fn unexpected_from_canonical_token_struct_end() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::StructEnd),
Unexpected::Other("StructEnd")
)
}
#[test]
fn unexpected_from_canonical_token_struct_variant() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::StructVariant {
name: "foo",
variant_index: 0,
variant: "bar",
len: 0
}),
Unexpected::StructVariant
)
}
#[test]
fn unexpected_from_canonical_token_struct_variant_end() {
assert_eq!(
Unexpected::from(&mut CanonicalToken::StructVariantEnd),
Unexpected::Other("StructVariantEnd")
)
}
#[test]
fn owning_iter_empty() {
let mut iter = OwningIter::new(Tokens(Vec::new()));
assert_none!(iter.next());
}
#[test]
fn owning_iter_one_token() {
let mut iter = OwningIter::new(Tokens(vec![CanonicalToken::Bool(true)]));
assert_some_eq!(iter.next(), &mut CanonicalToken::Bool(true));
assert_none!(iter.next());
}
#[test]
fn owning_iter_multiple_tokens() {
let mut iter = OwningIter::new(Tokens(vec![
CanonicalToken::Bool(true),
CanonicalToken::U64(42),
CanonicalToken::Str("foo".to_owned()),
]));
assert_some_eq!(iter.next(), &mut CanonicalToken::Bool(true));
assert_some_eq!(iter.next(), &mut CanonicalToken::U64(42));
assert_some_eq!(iter.next(), &mut CanonicalToken::Str("foo".to_owned()));
assert_none!(iter.next());
}
#[test]
fn owning_iter_empty_debug() {
let iter = OwningIter::new(Tokens(Vec::new()));
assert_eq!(format!("{:?}", iter), "OwningIter([])")
}
#[test]
fn owning_iter_uniterated_debug() {
let iter = OwningIter::new(Tokens(vec![
CanonicalToken::Bool(true),
CanonicalToken::U64(42),
CanonicalToken::Str("foo".to_owned()),
]));
assert_eq!(
format!("{:?}", iter),
"OwningIter([Bool(true), U64(42), Str(\"foo\")])"
)
}
#[test]
fn owning_iter_partially_iterated_debug() {
let mut iter = OwningIter::new(Tokens(vec![
CanonicalToken::Bool(true),
CanonicalToken::U64(42),
CanonicalToken::Str("foo".to_owned()),
]));
assert_some!(iter.next());
assert_eq!(format!("{:?}", iter), "OwningIter([U64(42), Str(\"foo\")])")
}
#[test]
fn owning_iter_fully_iterated_debug() {
let mut iter = OwningIter::new(Tokens(vec![
CanonicalToken::Bool(true),
CanonicalToken::U64(42),
CanonicalToken::Str("foo".to_owned()),
]));
assert_some!(iter.next());
assert_some!(iter.next());
assert_some!(iter.next());
assert_eq!(format!("{:?}", iter), "OwningIter([])")
}
}