Merge pull request #2533 from dtolnay/test

Move serde_test out to serde-rs/test
This commit is contained in:
David Tolnay 2023-07-25 22:52:36 -07:00 committed by GitHub
commit 11677ad926
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 4 additions and 3097 deletions

View File

@ -46,8 +46,6 @@ jobs:
toolchain: ${{matrix.rust}} toolchain: ${{matrix.rust}}
- run: cd serde && cargo build --features rc - run: cd serde && cargo build --features rc
- run: cd serde && cargo build --no-default-features - run: cd serde && cargo build --no-default-features
- run: cd serde_test && cargo build
- run: cd serde_test && cargo test --features serde/derive,serde/rc
nightly: nightly:
name: Rust nightly ${{matrix.os == 'windows' && '(windows)' || ''}} name: Rust nightly ${{matrix.os == 'windows' && '(windows)' || ''}}
@ -88,7 +86,6 @@ jobs:
- run: cd serde && cargo build --features rc - run: cd serde && cargo build --features rc
- run: cd serde && cargo build --no-default-features - run: cd serde && cargo build --no-default-features
- run: cd serde && cargo build - run: cd serde && cargo build
- run: cd serde_test && cargo build
more: more:
name: Rust ${{matrix.rust}} name: Rust ${{matrix.rust}}
@ -149,7 +146,6 @@ jobs:
- run: cd serde && cargo clippy --features rc,unstable -- -Dclippy::all -Dclippy::pedantic - run: cd serde && cargo clippy --features rc,unstable -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_derive && cargo clippy -- -Dclippy::all -Dclippy::pedantic - run: cd serde_derive && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_derive_internals && cargo clippy -- -Dclippy::all -Dclippy::pedantic - run: cd serde_derive_internals && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_test && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd test_suite && cargo clippy --tests --features unstable -- -Dclippy::all -Dclippy::pedantic - run: cd test_suite && cargo clippy --tests --features unstable -- -Dclippy::all -Dclippy::pedantic
- run: cd test_suite/no_std && cargo clippy -- -Dclippy::all -Dclippy::pedantic - run: cd test_suite/no_std && cargo clippy -- -Dclippy::all -Dclippy::pedantic

View File

@ -3,6 +3,8 @@ members = [
"serde", "serde",
"serde_derive", "serde_derive",
"serde_derive_internals", "serde_derive_internals",
"serde_test",
"test_suite", "test_suite",
] ]
[patch.crates-io]
serde = { path = "serde" }

View File

@ -1,28 +0,0 @@
[package]
name = "serde_test"
version = "1.0.175" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs"
categories = ["development-tools::testing"]
description = "Token De/Serializer for testing De/Serialize implementations"
documentation = "https://docs.rs/serde_test"
homepage = "https://serde.rs"
keywords = ["serde", "serialization", "testing", "dev-dependencies"]
license = "MIT OR Apache-2.0"
readme = "crates-io.md"
repository = "https://github.com/serde-rs/serde"
rust-version = "1.19"
[dependencies]
serde = { version = "1.0.60", path = "../serde" }
[dev-dependencies]
serde = { version = "1", path = "../serde", features = ["rc"] }
serde_derive = { version = "1", path = "../serde_derive" }
[lib]
doc-scrape-examples = false
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = ["--generate-link-to-definition"]

View File

@ -1 +0,0 @@
../LICENSE-APACHE

View File

@ -1 +0,0 @@
../LICENSE-MIT

View File

@ -1 +0,0 @@
../README.md

View File

@ -1,50 +0,0 @@
use std::env;
use std::process::Command;
use std::str::{self, FromStr};
// The rustc-cfg strings below are *not* public API. Please let us know by
// opening a GitHub issue if your build environment requires some way to enable
// these cfgs other than by executing our build script.
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let minor = match rustc_minor_version() {
Some(minor) => minor,
None => return,
};
// #[track_caller] stabilized in Rust 1.46:
// https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html#track_caller
if minor < 46 {
println!("cargo:rustc-cfg=no_track_caller");
}
}
fn rustc_minor_version() -> Option<u32> {
let rustc = match env::var_os("RUSTC") {
Some(rustc) => rustc,
None => return None,
};
let output = match Command::new(rustc).arg("--version").output() {
Ok(output) => output,
Err(_) => return None,
};
let version = match str::from_utf8(&output.stdout) {
Ok(version) => version,
Err(_) => return None,
};
let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return None;
}
let next = match pieces.next() {
Some(next) => next,
None => return None,
};
u32::from_str(next).ok()
}

View File

@ -1 +0,0 @@
../crates-io.md

View File

@ -1,237 +0,0 @@
use serde::{Deserialize, Serialize};
use de::Deserializer;
use ser::Serializer;
use token::Token;
use std::fmt::Debug;
/// Runs both `assert_ser_tokens` and `assert_de_tokens`.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct S {
/// a: u8,
/// b: u8,
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_tokens(
/// &s,
/// &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ],
/// );
/// ```
#[cfg_attr(not(no_track_caller), track_caller)]
pub fn assert_tokens<'de, T>(value: &T, tokens: &'de [Token])
where
T: Serialize + Deserialize<'de> + PartialEq + Debug,
{
assert_ser_tokens(value, tokens);
assert_de_tokens(value, tokens);
}
/// Asserts that `value` serializes to the given `tokens`.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_ser_tokens, Token};
/// #
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct S {
/// a: u8,
/// b: u8,
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_ser_tokens(
/// &s,
/// &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ],
/// );
/// ```
#[cfg_attr(not(no_track_caller), track_caller)]
pub fn assert_ser_tokens<T: ?Sized>(value: &T, tokens: &[Token])
where
T: Serialize,
{
let mut ser = Serializer::new(tokens);
match value.serialize(&mut ser) {
Ok(_) => {}
Err(err) => panic!("value failed to serialize: {}", err),
}
if ser.remaining() > 0 {
panic!("{} remaining tokens", ser.remaining());
}
}
/// Asserts that `value` serializes to the given `tokens`, and then yields
/// `error`.
///
/// ```edition2021
/// use serde_derive::Serialize;
/// use serde_test::{assert_ser_tokens_error, Token};
/// use std::sync::{Arc, Mutex};
/// use std::thread;
///
/// #[derive(Serialize)]
/// struct Example {
/// lock: Arc<Mutex<u32>>,
/// }
///
/// fn main() {
/// let example = Example {
/// lock: Arc::new(Mutex::new(0)),
/// };
/// let lock = example.lock.clone();
///
/// let thread = thread::spawn(move || {
/// // This thread will acquire the mutex first, unwrapping the result
/// // of `lock` because the lock has not been poisoned.
/// let _guard = lock.lock().unwrap();
///
/// // This panic while holding the lock (`_guard` is in scope) will
/// // poison the mutex.
/// panic!()
/// });
/// thread.join();
///
/// let expected = &[
/// Token::Struct {
/// name: "Example",
/// len: 1,
/// },
/// Token::Str("lock"),
/// ];
/// let error = "lock poison error while serializing";
/// assert_ser_tokens_error(&example, expected, error);
/// }
/// ```
#[cfg_attr(not(no_track_caller), track_caller)]
pub fn assert_ser_tokens_error<T: ?Sized>(value: &T, tokens: &[Token], error: &str)
where
T: Serialize,
{
let mut ser = Serializer::new(tokens);
match value.serialize(&mut ser) {
Ok(_) => panic!("value serialized successfully"),
Err(e) => assert_eq!(e, *error),
}
if ser.remaining() > 0 {
panic!("{} remaining tokens", ser.remaining());
}
}
/// Asserts that the given `tokens` deserialize into `value`.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_de_tokens, Token};
/// #
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct S {
/// a: u8,
/// b: u8,
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_de_tokens(
/// &s,
/// &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ],
/// );
/// ```
#[cfg_attr(not(no_track_caller), track_caller)]
pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
where
T: Deserialize<'de> + PartialEq + Debug,
{
let mut de = Deserializer::new(tokens);
let mut deserialized_val = match T::deserialize(&mut de) {
Ok(v) => {
assert_eq!(v, *value);
v
}
Err(e) => panic!("tokens failed to deserialize: {}", e),
};
if de.remaining() > 0 {
panic!("{} remaining tokens", de.remaining());
}
// Do the same thing for deserialize_in_place. This isn't *great* because a
// no-op impl of deserialize_in_place can technically succeed here. Still,
// this should catch a lot of junk.
let mut de = Deserializer::new(tokens);
match T::deserialize_in_place(&mut de, &mut deserialized_val) {
Ok(()) => {
assert_eq!(deserialized_val, *value);
}
Err(e) => panic!("tokens failed to deserialize_in_place: {}", e),
}
if de.remaining() > 0 {
panic!("{} remaining tokens", de.remaining());
}
}
/// Asserts that the given `tokens` yield `error` when deserializing.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_de_tokens_error, Token};
/// #
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// #[serde(deny_unknown_fields)]
/// struct S {
/// a: u8,
/// b: u8,
/// }
///
/// assert_de_tokens_error::<S>(
/// &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("x"),
/// ],
/// "unknown field `x`, expected `a` or `b`",
/// );
/// ```
#[cfg_attr(not(no_track_caller), track_caller)]
pub fn assert_de_tokens_error<'de, T>(tokens: &'de [Token], error: &str)
where
T: Deserialize<'de>,
{
let mut de = Deserializer::new(tokens);
match T::deserialize(&mut de) {
Ok(_) => panic!("tokens deserialized successfully"),
Err(e) => assert_eq!(e, *error),
}
// There may be one token left if a peek caused the error
de.next_token_opt();
if de.remaining() > 0 {
panic!("{} remaining tokens", de.remaining());
}
}

View File

@ -1,847 +0,0 @@
use std::fmt;
use serde::ser::{
SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
SerializeTupleStruct, SerializeTupleVariant,
};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Readable<T: ?Sized>(T);
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Compact<T: ?Sized>(T);
/// Trait to determine whether a value is represented in human-readable or
/// compact form.
///
/// ```edition2021
/// use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// use serde_test::{assert_tokens, Configure, Token};
///
/// #[derive(Debug, PartialEq)]
/// struct Example(u8, u8);
///
/// impl Serialize for Example {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where
/// S: Serializer,
/// {
/// if serializer.is_human_readable() {
/// format!("{}.{}", self.0, self.1).serialize(serializer)
/// } else {
/// (self.0, self.1).serialize(serializer)
/// }
/// }
/// }
///
/// impl<'de> Deserialize<'de> for Example {
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
/// where
/// D: Deserializer<'de>,
/// {
/// use serde::de::Error;
/// if deserializer.is_human_readable() {
/// let s = String::deserialize(deserializer)?;
/// let parts: Vec<_> = s.split('.').collect();
/// Ok(Example(
/// parts[0].parse().map_err(D::Error::custom)?,
/// parts[1].parse().map_err(D::Error::custom)?,
/// ))
/// } else {
/// let (x, y) = Deserialize::deserialize(deserializer)?;
/// Ok(Example(x, y))
/// }
/// }
/// }
///
/// fn main() {
/// assert_tokens(
/// &Example(1, 0).compact(),
/// &[
/// Token::Tuple { len: 2 },
/// Token::U8(1),
/// Token::U8(0),
/// Token::TupleEnd,
/// ],
/// );
/// assert_tokens(&Example(1, 0).readable(), &[Token::Str("1.0")]);
/// }
/// ```
pub trait Configure {
/// Marks `self` as using `is_human_readable == true`
fn readable(self) -> Readable<Self>
where
Self: Sized,
{
Readable(self)
}
/// Marks `self` as using `is_human_readable == false`
fn compact(self) -> Compact<Self>
where
Self: Sized,
{
Compact(self)
}
}
impl<T: ?Sized> Configure for T {}
impl<T: ?Sized> Serialize for Readable<T>
where
T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(Readable(serializer))
}
}
impl<T: ?Sized> Serialize for Compact<T>
where
T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(Compact(serializer))
}
}
impl<'de, T> Deserialize<'de> for Readable<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(Readable(deserializer)).map(Readable)
}
}
impl<'de, T> Deserialize<'de> for Compact<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(Compact(deserializer)).map(Compact)
}
}
impl<'de, T> DeserializeSeed<'de> for Readable<T>
where
T: DeserializeSeed<'de>,
{
type Value = T::Value;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
self.0.deserialize(Readable(deserializer))
}
}
impl<'de, T> DeserializeSeed<'de> for Compact<T>
where
T: DeserializeSeed<'de>,
{
type Value = T::Value;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
self.0.deserialize(Compact(deserializer))
}
}
macro_rules! forward_method {
($name: ident (self $(, $arg: ident : $arg_type: ty)* ) -> $return_type: ty) => {
fn $name (self $(, $arg : $arg_type)* ) -> $return_type {
(self.0).$name( $($arg),* )
}
};
}
macro_rules! forward_serialize_methods {
( $( $name: ident $arg_type: ty ),* ) => {
$(
forward_method!($name(self, v : $arg_type) -> Result<Self::Ok, Self::Error>);
)*
};
}
macro_rules! impl_serializer {
($wrapper:ident, $is_human_readable:expr) => {
impl<S> Serializer for $wrapper<S>
where
S: Serializer,
{
type Ok = S::Ok;
type Error = S::Error;
type SerializeSeq = $wrapper<S::SerializeSeq>;
type SerializeTuple = $wrapper<S::SerializeTuple>;
type SerializeTupleStruct = $wrapper<S::SerializeTupleStruct>;
type SerializeTupleVariant = $wrapper<S::SerializeTupleVariant>;
type SerializeMap = $wrapper<S::SerializeMap>;
type SerializeStruct = $wrapper<S::SerializeStruct>;
type SerializeStructVariant = $wrapper<S::SerializeStructVariant>;
fn is_human_readable(&self) -> bool {
$is_human_readable
}
forward_serialize_methods! {
serialize_bool bool,
serialize_i8 i8,
serialize_i16 i16,
serialize_i32 i32,
serialize_i64 i64,
serialize_u8 u8,
serialize_u16 u16,
serialize_u32 u32,
serialize_u64 u64,
serialize_f32 f32,
serialize_f64 f64,
serialize_char char,
serialize_str &str,
serialize_bytes &[u8],
serialize_unit_struct &'static str
}
fn serialize_unit(self) -> Result<S::Ok, S::Error> {
self.0.serialize_unit()
}
fn serialize_unit_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
) -> Result<S::Ok, S::Error> {
self.0.serialize_unit_variant(name, variant_index, variant)
}
fn serialize_newtype_struct<T: ?Sized>(
self,
name: &'static str,
value: &T,
) -> Result<S::Ok, S::Error>
where
T: Serialize,
{
self.0.serialize_newtype_struct(name, &$wrapper(value))
}
fn serialize_newtype_variant<T: ?Sized>(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<S::Ok, S::Error>
where
T: Serialize,
{
self.0
.serialize_newtype_variant(name, variant_index, variant, &$wrapper(value))
}
fn serialize_none(self) -> Result<S::Ok, Self::Error> {
self.0.serialize_none()
}
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<S::Ok, Self::Error>
where
T: Serialize,
{
self.0.serialize_some(&$wrapper(value))
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
self.0.serialize_seq(len).map($wrapper)
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
self.0.serialize_tuple(len).map($wrapper)
}
fn serialize_tuple_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
self.0.serialize_tuple_struct(name, len).map($wrapper)
}
fn serialize_tuple_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
self.0
.serialize_tuple_variant(name, variant_index, variant, len)
.map($wrapper)
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
self.0.serialize_map(len).map($wrapper)
}
fn serialize_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
self.0.serialize_struct(name, len).map($wrapper)
}
fn serialize_struct_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
self.0
.serialize_struct_variant(name, variant_index, variant, len)
.map($wrapper)
}
}
impl<S> SerializeSeq for $wrapper<S>
where
S: SerializeSeq,
{
type Ok = S::Ok;
type Error = S::Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), S::Error>
where
T: Serialize,
{
self.0.serialize_element(&$wrapper(value))
}
fn end(self) -> Result<S::Ok, S::Error> {
self.0.end()
}
}
impl<S> SerializeTuple for $wrapper<S>
where
S: SerializeTuple,
{
type Ok = S::Ok;
type Error = S::Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), S::Error>
where
T: Serialize,
{
self.0.serialize_element(&$wrapper(value))
}
fn end(self) -> Result<S::Ok, S::Error> {
self.0.end()
}
}
impl<S> SerializeTupleStruct for $wrapper<S>
where
S: SerializeTupleStruct,
{
type Ok = S::Ok;
type Error = S::Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), S::Error>
where
T: Serialize,
{
self.0.serialize_field(&$wrapper(value))
}
fn end(self) -> Result<S::Ok, S::Error> {
self.0.end()
}
}
impl<S> SerializeTupleVariant for $wrapper<S>
where
S: SerializeTupleVariant,
{
type Ok = S::Ok;
type Error = S::Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), S::Error>
where
T: Serialize,
{
self.0.serialize_field(&$wrapper(value))
}
fn end(self) -> Result<S::Ok, S::Error> {
self.0.end()
}
}
impl<S> SerializeMap for $wrapper<S>
where
S: SerializeMap,
{
type Ok = S::Ok;
type Error = S::Error;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), S::Error>
where
T: Serialize,
{
self.0.serialize_key(&$wrapper(key))
}
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), S::Error>
where
T: Serialize,
{
self.0.serialize_value(&$wrapper(value))
}
fn serialize_entry<K: ?Sized, V: ?Sized>(
&mut self,
key: &K,
value: &V,
) -> Result<(), S::Error>
where
K: Serialize,
V: Serialize,
{
self.0.serialize_entry(key, &$wrapper(value))
}
fn end(self) -> Result<S::Ok, S::Error> {
self.0.end()
}
}
impl<S> SerializeStruct for $wrapper<S>
where
S: SerializeStruct,
{
type Ok = S::Ok;
type Error = S::Error;
fn serialize_field<T: ?Sized>(
&mut self,
name: &'static str,
field: &T,
) -> Result<(), S::Error>
where
T: Serialize,
{
self.0.serialize_field(name, &$wrapper(field))
}
fn end(self) -> Result<S::Ok, S::Error> {
self.0.end()
}
}
impl<S> SerializeStructVariant for $wrapper<S>
where
S: SerializeStructVariant,
{
type Ok = S::Ok;
type Error = S::Error;
fn serialize_field<T: ?Sized>(
&mut self,
name: &'static str,
field: &T,
) -> Result<(), S::Error>
where
T: Serialize,
{
self.0.serialize_field(name, &$wrapper(field))
}
fn end(self) -> Result<S::Ok, S::Error> {
self.0.end()
}
}
};
}
impl_serializer!(Readable, true);
impl_serializer!(Compact, false);
use serde::de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor};
macro_rules! forward_deserialize_methods {
( $wrapper : ident ( $( $name: ident ),* ) ) => {
$(
fn $name<V>(self, visitor: V) -> Result<V::Value, D::Error>
where
V: Visitor<'de>,
{
(self.0).$name($wrapper(visitor))
}
)*
};
}
macro_rules! impl_deserializer {
($wrapper:ident, $is_human_readable:expr) => {
impl<'de, D> Deserializer<'de> for $wrapper<D>
where
D: Deserializer<'de>,
{
type Error = D::Error;
forward_deserialize_methods! {
$wrapper (
deserialize_any,
deserialize_bool,
deserialize_u8,
deserialize_u16,
deserialize_u32,
deserialize_u64,
deserialize_i8,
deserialize_i16,
deserialize_i32,
deserialize_i64,
deserialize_f32,
deserialize_f64,
deserialize_char,
deserialize_str,
deserialize_string,
deserialize_bytes,
deserialize_byte_buf,
deserialize_option,
deserialize_unit,
deserialize_seq,
deserialize_map,
deserialize_identifier,
deserialize_ignored_any
)
}
fn deserialize_unit_struct<V>(
self,
name: &'static str,
visitor: V,
) -> Result<V::Value, D::Error>
where
V: Visitor<'de>,
{
self.0.deserialize_unit_struct(name, $wrapper(visitor))
}
fn deserialize_newtype_struct<V>(
self,
name: &'static str,
visitor: V,
) -> Result<V::Value, D::Error>
where
V: Visitor<'de>,
{
self.0.deserialize_newtype_struct(name, $wrapper(visitor))
}
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, D::Error>
where
V: Visitor<'de>,
{
self.0.deserialize_tuple(len, $wrapper(visitor))
}
fn deserialize_tuple_struct<V>(
self,
name: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value, D::Error>
where
V: Visitor<'de>,
{
self.0
.deserialize_tuple_struct(name, len, $wrapper(visitor))
}
fn deserialize_struct<V>(
self,
name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, D::Error>
where
V: Visitor<'de>,
{
self.0.deserialize_struct(name, fields, $wrapper(visitor))
}
fn deserialize_enum<V>(
self,
name: &'static str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, D::Error>
where
V: Visitor<'de>,
{
self.0.deserialize_enum(name, variants, $wrapper(visitor))
}
fn is_human_readable(&self) -> bool {
$is_human_readable
}
}
impl<'de, D> Visitor<'de> for $wrapper<D>
where
D: Visitor<'de>,
{
type Value = D::Value;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
self.0.expecting(formatter)
}
fn visit_bool<E>(self, v: bool) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_bool(v)
}
fn visit_i8<E>(self, v: i8) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_i8(v)
}
fn visit_i16<E>(self, v: i16) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_i16(v)
}
fn visit_i32<E>(self, v: i32) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_i32(v)
}
fn visit_i64<E>(self, v: i64) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_i64(v)
}
fn visit_u8<E>(self, v: u8) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_u8(v)
}
fn visit_u16<E>(self, v: u16) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_u16(v)
}
fn visit_u32<E>(self, v: u32) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_u32(v)
}
fn visit_u64<E>(self, v: u64) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_u64(v)
}
fn visit_f32<E>(self, v: f32) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_f32(v)
}
fn visit_f64<E>(self, v: f64) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_f64(v)
}
fn visit_char<E>(self, v: char) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_char(v)
}
fn visit_str<E>(self, v: &str) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_str(v)
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_borrowed_str(v)
}
fn visit_string<E>(self, v: String) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_string(v)
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_bytes(v)
}
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_borrowed_bytes(v)
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_byte_buf(v)
}
fn visit_none<E>(self) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_none()
}
fn visit_some<D2>(self, deserializer: D2) -> Result<Self::Value, D2::Error>
where
D2: Deserializer<'de>,
{
self.0.visit_some($wrapper(deserializer))
}
fn visit_unit<E>(self) -> Result<D::Value, E>
where
E: Error,
{
self.0.visit_unit()
}
fn visit_newtype_struct<D2>(self, deserializer: D2) -> Result<Self::Value, D2::Error>
where
D2: Deserializer<'de>,
{
self.0.visit_newtype_struct($wrapper(deserializer))
}
fn visit_seq<V>(self, seq: V) -> Result<D::Value, V::Error>
where
V: SeqAccess<'de>,
{
self.0.visit_seq($wrapper(seq))
}
fn visit_map<V>(self, map: V) -> Result<D::Value, V::Error>
where
V: MapAccess<'de>,
{
self.0.visit_map($wrapper(map))
}
fn visit_enum<V>(self, data: V) -> Result<D::Value, V::Error>
where
V: EnumAccess<'de>,
{
self.0.visit_enum($wrapper(data))
}
}
impl<'de, D> SeqAccess<'de> for $wrapper<D>
where
D: SeqAccess<'de>,
{
type Error = D::Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, D::Error>
where
T: DeserializeSeed<'de>,
{
self.0.next_element_seed($wrapper(seed))
}
fn size_hint(&self) -> Option<usize> {
self.0.size_hint()
}
}
impl<'de, D> MapAccess<'de> for $wrapper<D>
where
D: MapAccess<'de>,
{
type Error = D::Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, D::Error>
where
K: DeserializeSeed<'de>,
{
self.0.next_key_seed($wrapper(seed))
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, D::Error>
where
V: DeserializeSeed<'de>,
{
self.0.next_value_seed($wrapper(seed))
}
fn next_entry_seed<K, V>(
&mut self,
kseed: K,
vseed: V,
) -> Result<Option<(K::Value, V::Value)>, D::Error>
where
K: DeserializeSeed<'de>,
V: DeserializeSeed<'de>,
{
self.0.next_entry_seed($wrapper(kseed), $wrapper(vseed))
}
fn size_hint(&self) -> Option<usize> {
self.0.size_hint()
}
}
impl<'de, D> EnumAccess<'de> for $wrapper<D>
where
D: EnumAccess<'de>,
{
type Error = D::Error;
type Variant = $wrapper<D::Variant>;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
where
V: DeserializeSeed<'de>,
{
self.0
.variant_seed($wrapper(seed))
.map(|(value, variant)| (value, $wrapper(variant)))
}
}
impl<'de, D> VariantAccess<'de> for $wrapper<D>
where
D: VariantAccess<'de>,
{
type Error = D::Error;
fn unit_variant(self) -> Result<(), D::Error> {
self.0.unit_variant()
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, D::Error>
where
T: DeserializeSeed<'de>,
{
self.0.newtype_variant_seed($wrapper(seed))
}
fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, D::Error>
where
V: Visitor<'de>,
{
self.0.tuple_variant(len, $wrapper(visitor))
}
fn struct_variant<V>(
self,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, D::Error>
where
V: Visitor<'de>,
{
self.0.struct_variant(fields, $wrapper(visitor))
}
}
};
}
impl_deserializer!(Readable, true);
impl_deserializer!(Compact, false);

View File

@ -1,671 +0,0 @@
use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer};
use serde::de::{
self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess,
VariantAccess, Visitor,
};
use error::Error;
use token::Token;
#[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: tokens }
}
fn peek_token_opt(&self) -> Option<Token> {
self.tokens.first().cloned()
}
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: len,
end: 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: len,
end: 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: 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: 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: 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: 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: 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: de,
variant: Some(variant),
format: 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
}
}

View File

@ -1,43 +0,0 @@
use std::error;
use std::fmt::{self, Display};
use serde::{de, ser};
#[derive(Clone, Debug)]
pub struct Error {
msg: String,
}
impl ser::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Error {
msg: msg.to_string(),
}
}
}
impl de::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Error {
msg: msg.to_string(),
}
}
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(&self.msg)
}
}
impl error::Error for Error {
fn description(&self) -> &str {
&self.msg
}
}
impl PartialEq<str> for Error {
fn eq(&self, other: &str) -> bool {
self.msg == other
}
}

View File

@ -1,188 +0,0 @@
//! This crate provides a convenient concise way to write unit tests for
//! implementations of [`Serialize`] and [`Deserialize`].
//!
//! [`Serialize`]: serde::ser::Serialize
//! [`Deserialize`]: serde::de::Deserialize
//!
//! The `Serialize` impl for a value can be characterized by the sequence of
//! [`Serializer`] calls that are made in the course of serializing the value,
//! so `serde_test` provides a [`Token`] abstraction which corresponds roughly
//! to `Serializer` method calls. There is an [`assert_ser_tokens`] function to
//! test that a value serializes to a particular sequence of method calls, an
//! [`assert_de_tokens`] function to test that a value can be deserialized from
//! a particular sequence of method calls, and an [`assert_tokens`] function to
//! test both directions. There are also functions to test expected failure
//! conditions.
//!
//! [`Serializer`]: serde::ser::Serializer
//!
//! Here is an example from the [`linked-hash-map`] crate.
//!
//! [`linked-hash-map`]: https://github.com/contain-rs/linked-hash-map
//!
//! ```edition2021
//! # const IGNORE: &str = stringify! {
//! use linked_hash_map::LinkedHashMap;
//! # };
//! use serde_test::{assert_tokens, Token};
//!
//! # use std::fmt;
//! # use std::marker::PhantomData;
//! #
//! # use serde::ser::{Serialize, Serializer, SerializeMap};
//! # use serde::de::{Deserialize, Deserializer, Visitor, MapAccess};
//! #
//! # // Dumb imitation of LinkedHashMap.
//! # #[derive(PartialEq, Debug)]
//! # struct LinkedHashMap<K, V>(Vec<(K, V)>);
//! #
//! # impl<K, V> LinkedHashMap<K, V> {
//! # fn new() -> Self {
//! # LinkedHashMap(Vec::new())
//! # }
//! #
//! # fn insert(&mut self, k: K, v: V) {
//! # self.0.push((k, v));
//! # }
//! # }
//! #
//! # impl<K, V> Serialize for LinkedHashMap<K, V>
//! # where
//! # K: Serialize,
//! # V: Serialize,
//! # {
//! # fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
//! # where
//! # S: Serializer,
//! # {
//! # let mut map = serializer.serialize_map(Some(self.0.len()))?;
//! # for &(ref k, ref v) in &self.0 {
//! # map.serialize_entry(k, v)?;
//! # }
//! # map.end()
//! # }
//! # }
//! #
//! # struct LinkedHashMapVisitor<K, V>(PhantomData<(K, V)>);
//! #
//! # impl<'de, K, V> Visitor<'de> for LinkedHashMapVisitor<K, V>
//! # where
//! # K: Deserialize<'de>,
//! # V: Deserialize<'de>,
//! # {
//! # type Value = LinkedHashMap<K, V>;
//! #
//! # fn expecting(&self, _: &mut fmt::Formatter) -> fmt::Result {
//! # unimplemented!()
//! # }
//! #
//! # fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
//! # where
//! # M: MapAccess<'de>,
//! # {
//! # let mut map = LinkedHashMap::new();
//! # while let Some((key, value)) = access.next_entry()? {
//! # map.insert(key, value);
//! # }
//! # Ok(map)
//! # }
//! # }
//! #
//! # impl<'de, K, V> Deserialize<'de> for LinkedHashMap<K, V>
//! # where
//! # K: Deserialize<'de>,
//! # V: Deserialize<'de>,
//! # {
//! # fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
//! # where
//! # D: Deserializer<'de>,
//! # {
//! # deserializer.deserialize_map(LinkedHashMapVisitor(PhantomData))
//! # }
//! # }
//! #
//! #[test]
//! # fn not_a_test_ser_de_empty() {}
//! fn test_ser_de_empty() {
//! let map = LinkedHashMap::<char, u32>::new();
//!
//! assert_tokens(
//! &map,
//! &[
//! Token::Map { len: Some(0) },
//! Token::MapEnd,
//! ],
//! );
//! }
//!
//! #[test]
//! # fn not_a_test_ser_de() {}
//! fn test_ser_de() {
//! let mut map = LinkedHashMap::new();
//! map.insert('b', 20);
//! map.insert('a', 10);
//! map.insert('c', 30);
//!
//! assert_tokens(
//! &map,
//! &[
//! Token::Map { len: Some(3) },
//! Token::Char('b'),
//! Token::I32(20),
//! Token::Char('a'),
//! Token::I32(10),
//! Token::Char('c'),
//! Token::I32(30),
//! Token::MapEnd,
//! ],
//! );
//! }
//! #
//! # fn main() {
//! # test_ser_de_empty();
//! # test_ser_de();
//! # }
//! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.175")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
// Ignored clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))]
// Ignored clippy_pedantic lints
#![cfg_attr(
feature = "cargo-clippy",
allow(
cloned_instead_of_copied,
doc_link_with_quotes, // https://github.com/rust-lang/rust-clippy/issues/8961
empty_line_after_outer_attr,
manual_assert,
missing_docs_in_private_items,
missing_panics_doc,
module_name_repetitions,
must_use_candidate,
redundant_field_names,
too_many_lines,
type_repetition_in_bounds, // https://github.com/rust-lang/rust-clippy/issues/8772
use_debug,
use_self
)
)]
#[macro_use]
extern crate serde;
mod de;
mod error;
mod ser;
mod assert;
mod configure;
mod token;
pub use assert::{
assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error,
assert_tokens,
};
pub use token::Token;
pub use configure::{Compact, Configure, Readable};

View File

@ -1,462 +0,0 @@
use serde::{ser, Serialize};
use error::Error;
use token::Token;
/// A `Serializer` that ensures that a value serializes to a given list of
/// tokens.
#[derive(Debug)]
pub struct Serializer<'a> {
tokens: &'a [Token],
}
impl<'a> Serializer<'a> {
/// Creates the serializer.
pub fn new(tokens: &'a [Token]) -> Self {
Serializer { tokens: tokens }
}
/// Pulls the next token off of the serializer, ignoring it.
fn next_token(&mut self) -> Option<Token> {
if let Some((&first, rest)) = self.tokens.split_first() {
self.tokens = rest;
Some(first)
} else {
None
}
}
pub fn remaining(&self) -> usize {
self.tokens.len()
}
}
macro_rules! assert_next_token {
($ser:expr, $actual:ident) => {{
assert_next_token!($ser, stringify!($actual), Token::$actual, true);
}};
($ser:expr, $actual:ident($v:expr)) => {{
assert_next_token!(
$ser,
format_args!(concat!(stringify!($actual), "({:?})"), $v),
Token::$actual(v),
v == $v
);
}};
($ser:expr, $actual:ident { $($k:ident),* }) => {{
let compare = ($($k,)*);
let field_format = || {
use std::fmt::Write;
let mut buffer = String::new();
$(
write!(&mut buffer, concat!(stringify!($k), ": {:?}, "), $k).unwrap();
)*
buffer
};
assert_next_token!(
$ser,
format_args!(concat!(stringify!($actual), " {{ {}}}"), field_format()),
Token::$actual { $($k),* },
($($k,)*) == compare
);
}};
($ser:expr, $actual:expr, $pat:pat, $guard:expr) => {
match $ser.next_token() {
Some($pat) if $guard => {}
Some(expected) => return Err(ser::Error::custom(
format!("expected Token::{} but serialized as {}", expected, $actual)
)),
None => return Err(ser::Error::custom(
format!("expected end of tokens, but {} was serialized", $actual)
)),
}
};
}
impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleStruct = Self;
type SerializeTupleVariant = Variant<'s, 'a>;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = Variant<'s, 'a>;
fn serialize_bool(self, v: bool) -> Result<(), Error> {
assert_next_token!(self, Bool(v));
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<(), Error> {
assert_next_token!(self, I8(v));
Ok(())
}
fn serialize_i16(self, v: i16) -> Result<(), Error> {
assert_next_token!(self, I16(v));
Ok(())
}
fn serialize_i32(self, v: i32) -> Result<(), Error> {
assert_next_token!(self, I32(v));
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<(), Error> {
assert_next_token!(self, I64(v));
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<(), Error> {
assert_next_token!(self, U8(v));
Ok(())
}
fn serialize_u16(self, v: u16) -> Result<(), Error> {
assert_next_token!(self, U16(v));
Ok(())
}
fn serialize_u32(self, v: u32) -> Result<(), Error> {
assert_next_token!(self, U32(v));
Ok(())
}
fn serialize_u64(self, v: u64) -> Result<(), Error> {
assert_next_token!(self, U64(v));
Ok(())
}
fn serialize_f32(self, v: f32) -> Result<(), Error> {
assert_next_token!(self, F32(v));
Ok(())
}
fn serialize_f64(self, v: f64) -> Result<(), Error> {
assert_next_token!(self, F64(v));
Ok(())
}
fn serialize_char(self, v: char) -> Result<(), Error> {
assert_next_token!(self, Char(v));
Ok(())
}
fn serialize_str(self, v: &str) -> Result<(), Error> {
match self.tokens.first() {
Some(&Token::BorrowedStr(_)) => assert_next_token!(self, BorrowedStr(v)),
Some(&Token::String(_)) => assert_next_token!(self, String(v)),
_ => assert_next_token!(self, Str(v)),
}
Ok(())
}
fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
match self.tokens.first() {
Some(&Token::BorrowedBytes(_)) => assert_next_token!(self, BorrowedBytes(v)),
Some(&Token::ByteBuf(_)) => assert_next_token!(self, ByteBuf(v)),
_ => assert_next_token!(self, Bytes(v)),
}
Ok(())
}
fn serialize_unit(self) -> Result<(), Error> {
assert_next_token!(self, Unit);
Ok(())
}
fn serialize_unit_struct(self, name: &'static str) -> Result<(), Error> {
assert_next_token!(self, UnitStruct { name });
Ok(())
}
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<(), Error> {
if self.tokens.first() == Some(&Token::Enum { name: name }) {
self.next_token();
assert_next_token!(self, Str(variant));
assert_next_token!(self, Unit);
} else {
assert_next_token!(self, UnitVariant { name, variant });
}
Ok(())
}
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<(), Error>
where
T: Serialize,
{
assert_next_token!(self, NewtypeStruct { name });
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<(), Error>
where
T: Serialize,
{
if self.tokens.first() == Some(&Token::Enum { name: name }) {
self.next_token();
assert_next_token!(self, Str(variant));
} else {
assert_next_token!(self, NewtypeVariant { name, variant });
}
value.serialize(self)
}
fn serialize_none(self) -> Result<(), Error> {
assert_next_token!(self, None);
Ok(())
}
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
assert_next_token!(self, Some);
value.serialize(self)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self, Error> {
assert_next_token!(self, Seq { len });
Ok(self)
}
fn serialize_tuple(self, len: usize) -> Result<Self, Error> {
assert_next_token!(self, Tuple { len });
Ok(self)
}
fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
assert_next_token!(self, TupleStruct { name, len });
Ok(self)
}
fn serialize_tuple_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Error> {
if self.tokens.first() == Some(&Token::Enum { name: name }) {
self.next_token();
assert_next_token!(self, Str(variant));
let len = Some(len);
assert_next_token!(self, Seq { len });
Ok(Variant {
ser: self,
end: Token::SeqEnd,
})
} else {
assert_next_token!(self, TupleVariant { name, variant, len });
Ok(Variant {
ser: self,
end: Token::TupleVariantEnd,
})
}
}
fn serialize_map(self, len: Option<usize>) -> Result<Self, Error> {
assert_next_token!(self, Map { len });
Ok(self)
}
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
assert_next_token!(self, Struct { name, len });
Ok(self)
}
fn serialize_struct_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Error> {
if self.tokens.first() == Some(&Token::Enum { name: name }) {
self.next_token();
assert_next_token!(self, Str(variant));
let len = Some(len);
assert_next_token!(self, Map { len });
Ok(Variant {
ser: self,
end: Token::MapEnd,
})
} else {
assert_next_token!(self, StructVariant { name, variant, len });
Ok(Variant {
ser: self,
end: Token::StructVariantEnd,
})
}
}
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`"
);
}
}
pub struct Variant<'s, 'a: 's> {
ser: &'s mut Serializer<'a>,
end: Token,
}
impl<'s, 'a> ser::SerializeSeq for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<(), Error> {
assert_next_token!(self, SeqEnd);
Ok(())
}
}
impl<'s, 'a> ser::SerializeTuple for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<(), Error> {
assert_next_token!(self, TupleEnd);
Ok(())
}
}
impl<'s, 'a> ser::SerializeTupleStruct for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<(), Error> {
assert_next_token!(self, TupleStructEnd);
Ok(())
}
}
impl<'s, 'a> ser::SerializeTupleVariant for Variant<'s, 'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<(), Error> {
match self.end {
Token::TupleVariantEnd => assert_next_token!(self.ser, TupleVariantEnd),
Token::SeqEnd => assert_next_token!(self.ser, SeqEnd),
_ => unreachable!(),
}
Ok(())
}
}
impl<'s, 'a> ser::SerializeMap for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
key.serialize(&mut **self)
}
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<(), Self::Error> {
assert_next_token!(self, MapEnd);
Ok(())
}
}
impl<'s, 'a> ser::SerializeStruct for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: Serialize,
{
key.serialize(&mut **self)?;
value.serialize(&mut **self)
}
fn end(self) -> Result<(), Self::Error> {
assert_next_token!(self, StructEnd);
Ok(())
}
}
impl<'s, 'a> ser::SerializeStructVariant for Variant<'s, 'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: Serialize,
{
key.serialize(&mut *self.ser)?;
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<(), Self::Error> {
match self.end {
Token::StructVariantEnd => assert_next_token!(self.ser, StructVariantEnd),
Token::MapEnd => assert_next_token!(self.ser, MapEnd),
_ => unreachable!(),
}
Ok(())
}
}

View File

@ -1,561 +0,0 @@
use std::fmt::{self, Debug, Display};
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Token {
/// A serialized `bool`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&true, &[Token::Bool(true)]);
/// ```
Bool(bool),
/// A serialized `i8`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i8, &[Token::I8(0)]);
/// ```
I8(i8),
/// A serialized `i16`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i16, &[Token::I16(0)]);
/// ```
I16(i16),
/// A serialized `i32`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i32, &[Token::I32(0)]);
/// ```
I32(i32),
/// A serialized `i64`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i64, &[Token::I64(0)]);
/// ```
I64(i64),
/// A serialized `u8`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u8, &[Token::U8(0)]);
/// ```
U8(u8),
/// A serialized `u16`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u16, &[Token::U16(0)]);
/// ```
U16(u16),
/// A serialized `u32`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u32, &[Token::U32(0)]);
/// ```
U32(u32),
/// A serialized `u64`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u64, &[Token::U64(0)]);
/// ```
U64(u64),
/// A serialized `f32`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0f32, &[Token::F32(0.0)]);
/// ```
F32(f32),
/// A serialized `f64`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0f64, &[Token::F64(0.0)]);
/// ```
F64(f64),
/// A serialized `char`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&'\n', &[Token::Char('\n')]);
/// ```
Char(char),
/// A serialized `str`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let s = String::from("transient");
/// assert_tokens(&s, &[Token::Str("transient")]);
/// ```
Str(&'static str),
/// A borrowed `str`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let s: &str = "borrowed";
/// assert_tokens(&s, &[Token::BorrowedStr("borrowed")]);
/// ```
BorrowedStr(&'static str),
/// A serialized `String`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let s = String::from("owned");
/// assert_tokens(&s, &[Token::String("owned")]);
/// ```
String(&'static str),
/// A serialized `[u8]`
Bytes(&'static [u8]),
/// A borrowed `[u8]`.
BorrowedBytes(&'static [u8]),
/// A serialized `ByteBuf`
ByteBuf(&'static [u8]),
/// A serialized `Option<T>` containing none.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let opt = None::<char>;
/// assert_tokens(&opt, &[Token::None]);
/// ```
None,
/// The header to a serialized `Option<T>` containing some value.
///
/// The tokens of the value follow after this header.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let opt = Some('c');
/// assert_tokens(&opt, &[Token::Some, Token::Char('c')]);
/// ```
Some,
/// A serialized `()`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&(), &[Token::Unit]);
/// ```
Unit,
/// A serialized unit struct of the given name.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct X;
///
/// assert_tokens(&X, &[Token::UnitStruct { name: "X" }]);
/// # }
/// ```
UnitStruct { name: &'static str },
/// A unit variant of an enum.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// enum E {
/// A,
/// }
///
/// let a = E::A;
/// assert_tokens(
/// &a,
/// &[Token::UnitVariant {
/// name: "E",
/// variant: "A",
/// }],
/// );
/// # }
/// ```
UnitVariant {
name: &'static str,
variant: &'static str,
},
/// The header to a serialized newtype struct of the given name.
///
/// After this header is the value contained in the newtype struct.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct N(String);
///
/// let n = N("newtype".to_owned());
/// assert_tokens(
/// &n,
/// &[Token::NewtypeStruct { name: "N" }, Token::String("newtype")],
/// );
/// # }
/// ```
NewtypeStruct { name: &'static str },
/// The header to a newtype variant of an enum.
///
/// After this header is the value contained in the newtype variant.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// enum E {
/// B(u8),
/// }
///
/// let b = E::B(0);
/// assert_tokens(
/// &b,
/// &[
/// Token::NewtypeVariant {
/// name: "E",
/// variant: "B",
/// },
/// Token::U8(0),
/// ],
/// );
/// # }
/// ```
NewtypeVariant {
name: &'static str,
variant: &'static str,
},
/// The header to a sequence.
///
/// After this header are the elements of the sequence, followed by
/// `SeqEnd`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let vec = vec!['a', 'b', 'c'];
/// assert_tokens(
/// &vec,
/// &[
/// Token::Seq { len: Some(3) },
/// Token::Char('a'),
/// Token::Char('b'),
/// Token::Char('c'),
/// Token::SeqEnd,
/// ],
/// );
/// ```
Seq { len: Option<usize> },
/// An indicator of the end of a sequence.
SeqEnd,
/// The header to a tuple.
///
/// After this header are the elements of the tuple, followed by `TupleEnd`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let tuple = ('a', 100);
/// assert_tokens(
/// &tuple,
/// &[
/// Token::Tuple { len: 2 },
/// Token::Char('a'),
/// Token::I32(100),
/// Token::TupleEnd,
/// ],
/// );
/// ```
Tuple { len: usize },
/// An indicator of the end of a tuple.
TupleEnd,
/// The header to a tuple struct.
///
/// After this header are the fields of the tuple struct, followed by
/// `TupleStructEnd`.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct T(u8, u8);
///
/// let t = T(0, 0);
/// assert_tokens(
/// &t,
/// &[
/// Token::TupleStruct { name: "T", len: 2 },
/// Token::U8(0),
/// Token::U8(0),
/// Token::TupleStructEnd,
/// ],
/// );
/// # }
/// ```
TupleStruct { name: &'static str, len: usize },
/// An indicator of the end of a tuple struct.
TupleStructEnd,
/// The header to a tuple variant of an enum.
///
/// After this header are the fields of the tuple variant, followed by
/// `TupleVariantEnd`.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// enum E {
/// C(u8, u8),
/// }
///
/// let c = E::C(0, 0);
/// assert_tokens(
/// &c,
/// &[
/// Token::TupleVariant {
/// name: "E",
/// variant: "C",
/// len: 2,
/// },
/// Token::U8(0),
/// Token::U8(0),
/// Token::TupleVariantEnd,
/// ],
/// );
/// # }
/// ```
TupleVariant {
name: &'static str,
variant: &'static str,
len: usize,
},
/// An indicator of the end of a tuple variant.
TupleVariantEnd,
/// The header to a map.
///
/// After this header are the entries of the map, followed by `MapEnd`.
///
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// use std::collections::BTreeMap;
///
/// let mut map = BTreeMap::new();
/// map.insert('A', 65);
/// map.insert('Z', 90);
///
/// assert_tokens(
/// &map,
/// &[
/// Token::Map { len: Some(2) },
/// Token::Char('A'),
/// Token::I32(65),
/// Token::Char('Z'),
/// Token::I32(90),
/// Token::MapEnd,
/// ],
/// );
/// ```
Map { len: Option<usize> },
/// An indicator of the end of a map.
MapEnd,
/// The header of a struct.
///
/// After this header are the fields of the struct, followed by `StructEnd`.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct S {
/// a: u8,
/// b: u8,
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_tokens(
/// &s,
/// &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ],
/// );
/// # }
/// ```
Struct { name: &'static str, len: usize },
/// An indicator of the end of a struct.
StructEnd,
/// The header of a struct variant of an enum.
///
/// After this header are the fields of the struct variant, followed by
/// `StructVariantEnd`.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// enum E {
/// D { d: u8 },
/// }
///
/// let d = E::D { d: 0 };
/// assert_tokens(
/// &d,
/// &[
/// Token::StructVariant {
/// name: "E",
/// variant: "D",
/// len: 1,
/// },
/// Token::Str("d"),
/// Token::U8(0),
/// Token::StructVariantEnd,
/// ],
/// );
/// # }
/// ```
StructVariant {
name: &'static str,
variant: &'static str,
len: usize,
},
/// An indicator of the end of a struct variant.
StructVariantEnd,
/// The header to an enum of the given name.
///
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// enum E {
/// A,
/// B(u8),
/// C(u8, u8),
/// D { d: u8 },
/// }
///
/// let a = E::A;
/// assert_tokens(
/// &a,
/// &[Token::Enum { name: "E" }, Token::Str("A"), Token::Unit],
/// );
///
/// let b = E::B(0);
/// assert_tokens(
/// &b,
/// &[Token::Enum { name: "E" }, Token::Str("B"), Token::U8(0)],
/// );
///
/// let c = E::C(0, 0);
/// assert_tokens(
/// &c,
/// &[
/// Token::Enum { name: "E" },
/// Token::Str("C"),
/// Token::Seq { len: Some(2) },
/// Token::U8(0),
/// Token::U8(0),
/// Token::SeqEnd,
/// ],
/// );
///
/// let d = E::D { d: 0 };
/// assert_tokens(
/// &d,
/// &[
/// Token::Enum { name: "E" },
/// Token::Str("D"),
/// Token::Map { len: Some(1) },
/// Token::Str("d"),
/// Token::U8(0),
/// Token::MapEnd,
/// ],
/// );
/// # }
/// ```
Enum { name: &'static str },
}
impl Display for Token {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(self, formatter)
}
}

View File

@ -17,5 +17,5 @@ fnv = "1.0"
rustversion = "1.0" rustversion = "1.0"
serde = { path = "../serde", features = ["rc"] } serde = { path = "../serde", features = ["rc"] }
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] } serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
serde_test = { path = "../serde_test" } serde_test = "1.0.176"
trybuild = { version = "1.0.66", features = ["diff"] } trybuild = { version = "1.0.66", features = ["diff"] }