Compare commits

...

37 Commits

Author SHA1 Message Date
David Tolnay 83537c95e1 Release 1.0.10 2017-07-11 21:19:24 -07:00
David Tolnay fa9057fa31 Merge pull request #949 from WiSaGaN/feature/support-system-time
Support std::time::SystemTime
2017-07-11 21:17:56 -07:00
Wangshan Lu 0084d82a50 Add tests for SystemTime 2017-07-12 12:01:40 +08:00
Wangshan Lu b504b08782 Fix SystemTime serde name 2017-07-12 12:01:29 +08:00
David Tolnay 775e8154e7 Fix libc dependency in no_std test 2017-07-09 10:19:19 -07:00
David Tolnay 9c679d9082 Test for serializing BTreeSet 2017-07-09 10:16:49 -07:00
David Tolnay b0f9d2a0ba Exclude macros file from being tested by itself 2017-07-09 09:24:29 -07:00
David Tolnay f39b1db96a Additional errors for some reason 2017-07-09 09:22:20 -07:00
David Tolnay 9ecb0839de Release 1.0.9 2017-06-29 20:21:29 -07:00
David Tolnay 8a4c116812 Merge pull request #971 from serde-rs/remotede
Fix deserializer bounds on remote derive
2017-06-29 20:19:36 -07:00
David Tolnay 1d3e921ba6 Fix deserializer bounds on remote derive 2017-06-29 20:12:44 -07:00
David Tolnay 4fdba725fe Revert "Support deserialization of struct keys from integers"
This is not as useful as expected because the Serializer does not know the real
index of each struct field being serialized. The best it can do is keep a
counter, which goes wrong if fields are conditionally skipped.

This reverts commit eec7101894.
2017-06-18 09:11:21 -07:00
David Tolnay 75eed8cdde Merge pull request #958 from serde-rs/unused
Fix unused seq and map macros
2017-06-17 19:14:39 -07:00
David Tolnay 6801a13650 Fix unused seq and map macros 2017-06-17 19:01:12 -07:00
David Tolnay 25ab84d4b9 Merge pull request #957 from serde-rs/alloc
Merge crate `collections` into `alloc`
2017-06-17 18:59:43 -07:00
David Tolnay e43d3f3e4f Merge crate collections into alloc 2017-06-17 18:35:56 -07:00
David Tolnay b37d47c987 Merge pull request #956 from sfackler/int-field
Support deserialization of struct keys from integers
2017-06-17 18:26:45 -07:00
Steven Fackler eec7101894 Support deserialization of struct keys from integers
serde-cbor supports a "packed" serialization flag which causes keys to
be serialized as their indices, but the deserializer currently has to
hardcode support for this format. We can simply support deserialization
of struct keys from integers as we already do for enum variants.
2017-06-17 18:12:07 -07:00
Wangshan Lu 5dd327fb02 Support std::time::SystemTime 2017-06-04 16:39:03 +08:00
David Tolnay fd3d1396d3 Release 1.0.8 2017-05-24 00:17:27 -07:00
David Tolnay c47b4c8e0b Release 1.0.7 2017-05-19 17:00:31 -07:00
David Tolnay 2d793b82f6 Merge pull request #940 from BurntSushi/ag-deser-borrowed
add borrowed value deserializers
2017-05-19 16:59:55 -07:00
Andrew Gallant 237be46e29 add borrowed value deserializers
This adds two new types to the `de::value` module,
`BorrowedStrDeserializer` and `BorrowedBytesDeserializer`. A
`BorrowedStrDeserializer` is just like `StrDeserializer`, except the
lifetime of the string is tied to the lifetime of the deserializer. This
can be useful when, for example, deserializing into a
`HashMap<&str, &str>` when the keys/values are tied to the deserializer
itself.

The `BorrowedBytesDeserializer` has no analog, but it's the same as
`BorrowedStrDeserialize` except for `&[u8]` instead of `&str`.
2017-05-19 19:55:34 -04:00
David Tolnay 3d7aad1e7b Release 1.0.6 2017-05-17 08:20:54 -07:00
David Tolnay e792874369 Merge pull request #935 from spikefoo/combined-skip
Add a combined skip attribute
2017-05-16 09:13:49 -07:00
spikefoo 1669c69714 Add a combined #serde[(skip)] field attribute 2017-05-16 12:33:26 +03:00
David Tolnay 4d5e450054 Release 1.0.5 2017-05-14 12:53:48 -07:00
David Tolnay 26b22e647d Merge pull request #933 from serde-rs/contentstr
Fix internally tagged struct variant containing unit variant containing borrowed string
2017-05-14 12:53:07 -07:00
David Tolnay cda1fc46b0 Fix internally tagged struct variant containing unit variant containing borrowed string 2017-05-14 12:39:42 -07:00
David Tolnay c68b959696 Release 1.0.4 2017-05-10 20:05:22 -07:00
David Tolnay eab80172e4 Merge pull request #926 from serde-rs/borrow
Support borrowing within internally tagged enum
2017-05-10 20:04:36 -07:00
David Tolnay c1259fbc87 Support borrowing within internally tagged enum 2017-05-10 19:56:05 -07:00
David Tolnay 58e30eaee4 Release 1.0.3 2017-05-10 10:15:39 -07:00
David Tolnay bafa941004 Merge pull request #924 from pshc/deserialize-borrowed-path
impl Deserialize for &'a Path
2017-05-10 10:14:25 -07:00
Paul Collier f347b2d363 impl Deserialize for &'a Path 2017-05-10 13:03:03 -04:00
David Tolnay 3f9fc49cca Merge pull request #922 from serde-rs/nonzero
Removed Deref impl for NonZero
2017-05-09 19:58:17 -07:00
David Tolnay c913527944 Removed Deref impl for NonZero 2017-05-09 19:48:54 -07:00
28 changed files with 747 additions and 230 deletions
+4 -11
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.2" # remember to update html_root_url version = "1.0.10" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
@@ -48,22 +48,15 @@ std = []
# https://github.com/serde-rs/serde/issues/812 # https://github.com/serde-rs/serde/issues/812
unstable = [] unstable = []
# Provide impls for types that require memory allocation like Box<T> and Rc<T>. # Provide impls for types in the Rust core allocation and collections library
# This is a subset of std but may be enabled without depending on all of std. # including String, Box<T>, Vec<T>, and Cow<T>. This is a subset of std but may
# be enabled without depending on all of std.
# #
# Requires a dependency on the unstable core allocation library: # Requires a dependency on the unstable core allocation library:
# #
# https://doc.rust-lang.org/alloc/ # https://doc.rust-lang.org/alloc/
alloc = ["unstable"] alloc = ["unstable"]
# Provide impls for collection types like String and Cow<T>. This is a subset of
# std but may be enabled without depending on all of std.
#
# Requires a dependency on the unstable collections library:
#
# https://doc.rust-lang.org/collections/
collections = ["alloc"]
# Opt into impls for Rc<T> and Arc<T>. Serializing and deserializing these types # Opt into impls for Rc<T> and Arc<T>. Serializing and deserializing these types
# does not preserve identity and may result in multiple copies of the same data. # does not preserve identity and may result in multiple copies of the same data.
# Be sure that this is what you want before enabling this feature. # Be sure that this is what you want before enabling this feature.
+180 -16
View File
@@ -11,12 +11,12 @@ use lib::*;
use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess,
Visitor}; Visitor};
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
use de::MapAccess; use de::MapAccess;
use de::from_primitive::FromPrimitive; use de::from_primitive::FromPrimitive;
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
use private::de::size_hint; use private::de::size_hint;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -208,10 +208,10 @@ impl<'de> Deserialize<'de> for char {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
struct StringVisitor; struct StringVisitor;
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Visitor<'de> for StringVisitor { impl<'de> Visitor<'de> for StringVisitor {
type Value = String; type Value = String;
@@ -254,7 +254,7 @@ impl<'de> Visitor<'de> for StringVisitor {
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for String { impl<'de> Deserialize<'de> for String {
fn deserialize<D>(deserializer: D) -> Result<String, D::Error> fn deserialize<D>(deserializer: D) -> Result<String, D::Error>
where where
@@ -497,7 +497,7 @@ impl<'de, T> Deserialize<'de> for PhantomData<T> {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! seq_impl { macro_rules! seq_impl {
( (
$ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
@@ -552,7 +552,7 @@ macro_rules! seq_impl {
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!( seq_impl!(
BinaryHeap<T: Ord>, BinaryHeap<T: Ord>,
seq, seq,
@@ -560,7 +560,7 @@ seq_impl!(
BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())), BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
BinaryHeap::push); BinaryHeap::push);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!( seq_impl!(
BTreeSet<T: Eq + Ord>, BTreeSet<T: Eq + Ord>,
seq, seq,
@@ -568,7 +568,7 @@ seq_impl!(
BTreeSet::new(), BTreeSet::new(),
BTreeSet::insert); BTreeSet::insert);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!( seq_impl!(
LinkedList<T>, LinkedList<T>,
seq, seq,
@@ -584,7 +584,7 @@ seq_impl!(
HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()), HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
HashSet::insert); HashSet::insert);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!( seq_impl!(
Vec<T>, Vec<T>,
seq, seq,
@@ -592,7 +592,7 @@ seq_impl!(
Vec::with_capacity(size_hint::cautious(seq.size_hint())), Vec::with_capacity(size_hint::cautious(seq.size_hint())),
Vec::push); Vec::push);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!( seq_impl!(
VecDeque<T>, VecDeque<T>,
seq, seq,
@@ -790,7 +790,7 @@ tuple_impls! {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! map_impl { macro_rules! map_impl {
( (
$ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >, $ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
@@ -846,7 +846,7 @@ macro_rules! map_impl {
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
map_impl!( map_impl!(
BTreeMap<K: Ord, V>, BTreeMap<K: Ord, V>,
map, map,
@@ -897,6 +897,44 @@ parse_impl!(net::SocketAddrV6);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
struct PathVisitor;
#[cfg(feature = "std")]
impl<'a> Visitor<'a> for PathVisitor {
type Value = &'a Path;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a borrowed path")
}
fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v.as_ref())
}
fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
where
E: Error,
{
str::from_utf8(v)
.map(AsRef::as_ref)
.map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self))
}
}
#[cfg(feature = "std")]
impl<'de: 'a, 'a> Deserialize<'de> for &'a Path {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(PathVisitor)
}
}
#[cfg(feature = "std")] #[cfg(feature = "std")]
struct PathBufVisitor; struct PathBufVisitor;
@@ -1072,7 +1110,7 @@ where
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, T> Deserialize<'de> for Box<[T]> impl<'de, T> Deserialize<'de> for Box<[T]>
where where
T: Deserialize<'de>, T: Deserialize<'de>,
@@ -1085,7 +1123,7 @@ where
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for Box<str> { impl<'de> Deserialize<'de> for Box<str> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@@ -1121,7 +1159,7 @@ where
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T> impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
where where
T: ToOwned, T: ToOwned,
@@ -1326,6 +1364,132 @@ impl<'de> Deserialize<'de> for Duration {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for SystemTime {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
// Reuse duration
enum Field {
Secs,
Nanos,
};
impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`secs_since_epoch` or `nanos_since_epoch`")
}
fn visit_str<E>(self, value: &str) -> Result<Field, E>
where
E: Error,
{
match value {
"secs_since_epoch" => Ok(Field::Secs),
"nanos_since_epoch" => Ok(Field::Nanos),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
where
E: Error,
{
match value {
b"secs_since_epoch" => Ok(Field::Secs),
b"nanos_since_epoch" => Ok(Field::Nanos),
_ => {
let value = String::from_utf8_lossy(value);
Err(Error::unknown_field(&value, FIELDS))
}
}
}
}
deserializer.deserialize_identifier(FieldVisitor)
}
}
struct DurationVisitor;
impl<'de> Visitor<'de> for DurationVisitor {
type Value = Duration;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct SystemTime")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Duration, A::Error>
where
A: SeqAccess<'de>,
{
let secs: u64 = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0, &self));
}
};
let nanos: u32 = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(1, &self));
}
};
Ok(Duration::new(secs, nanos))
}
fn visit_map<A>(self, mut map: A) -> Result<Duration, A::Error>
where
A: MapAccess<'de>,
{
let mut secs: Option<u64> = None;
let mut nanos: Option<u32> = None;
while let Some(key) = try!(map.next_key()) {
match key {
Field::Secs => {
if secs.is_some() {
return Err(<A::Error as Error>::duplicate_field("secs_since_epoch"));
}
secs = Some(try!(map.next_value()));
}
Field::Nanos => {
if nanos.is_some() {
return Err(<A::Error as Error>::duplicate_field("nanos_since_epoch"));
}
nanos = Some(try!(map.next_value()));
}
}
}
let secs = match secs {
Some(secs) => secs,
None => return Err(<A::Error as Error>::missing_field("secs_since_epoch")),
};
let nanos = match nanos {
Some(nanos) => nanos,
None => return Err(<A::Error as Error>::missing_field("nanos_since_epoch")),
};
Ok(Duration::new(secs, nanos))
}
}
const FIELDS: &'static [&'static str] = &["secs_since_epoch", "nanos_since_epoch"];
let duration = try!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor));
Ok(UNIX_EPOCH + duration)
}
}
////////////////////////////////////////////////////////////////////////////////
// Similar to: // Similar to:
// //
// #[derive(Deserialize)] // #[derive(Deserialize)]
+3 -2
View File
@@ -94,6 +94,7 @@
//! - OsString //! - OsString
//! - **Miscellaneous standard library types**: //! - **Miscellaneous standard library types**:
//! - Duration //! - Duration
//! - SystemTime
//! - Path //! - Path
//! - PathBuf //! - PathBuf
//! - Range\<T\> //! - Range\<T\>
@@ -1262,7 +1263,7 @@ pub trait Visitor<'de>: Sized {
/// The default implementation forwards to `visit_str` and then drops the /// The default implementation forwards to `visit_str` and then drops the
/// `String`. /// `String`.
#[inline] #[inline]
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
fn visit_string<E>(self, v: String) -> Result<Self::Value, E> fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where where
E: Error, E: Error,
@@ -1321,7 +1322,7 @@ pub trait Visitor<'de>: Sized {
/// ///
/// The default implementation forwards to `visit_bytes` and then drops the /// The default implementation forwards to `visit_bytes` and then drops the
/// `Vec<u8>`. /// `Vec<u8>`.
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where where
E: Error, E: Error,
+126 -17
View File
@@ -51,13 +51,13 @@ pub struct Error {
err: ErrorImpl, err: ErrorImpl,
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
type ErrorImpl = Box<str>; type ErrorImpl = Box<str>;
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
type ErrorImpl = (); type ErrorImpl = ();
impl de::Error for Error { impl de::Error for Error {
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
fn custom<T>(msg: T) -> Self fn custom<T>(msg: T) -> Self
where where
T: Display, T: Display,
@@ -65,7 +65,7 @@ impl de::Error for Error {
Error { err: msg.to_string().into_boxed_str() } Error { err: msg.to_string().into_boxed_str() }
} }
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
fn custom<T>(msg: T) -> Self fn custom<T>(msg: T) -> Self
where where
T: Display, T: Display,
@@ -85,12 +85,12 @@ impl ser::Error for Error {
} }
impl Display for Error { impl Display for Error {
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(&self.err) formatter.write_str(&self.err)
} }
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str("Serde deserialization error") formatter.write_str("Serde deserialization error")
} }
@@ -355,15 +355,84 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `&str` with a lifetime tied to another
/// deserializer.
#[derive(Clone, Debug)]
pub struct BorrowedStrDeserializer<'de, E> {
value: &'de str,
marker: PhantomData<E>,
}
impl<'de, E> BorrowedStrDeserializer<'de, E> {
/// Create a new borrowed deserializer from the given string.
pub fn new(value: &'de str) -> BorrowedStrDeserializer<'de, E> {
BorrowedStrDeserializer {
value: value,
marker: PhantomData,
}
}
}
impl<'de, E> de::Deserializer<'de> for BorrowedStrDeserializer<'de, E>
where
E: de::Error,
{
type Error = E;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_borrowed_str(self.value)
}
fn deserialize_enum<V>(
self,
name: &str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
let _ = name;
let _ = variants;
visitor.visit_enum(self)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
map struct identifier ignored_any
}
}
impl<'de, E> de::EnumAccess<'de> for BorrowedStrDeserializer<'de, E>
where
E: de::Error,
{
type Error = E;
type Variant = private::UnitOnly<E>;
fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
where
T: de::DeserializeSeed<'de>,
{
seed.deserialize(self).map(private::unit_only)
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `String`. /// A deserializer holding a `String`.
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct StringDeserializer<E> { pub struct StringDeserializer<E> {
value: String, value: String,
marker: PhantomData<E>, marker: PhantomData<E>,
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, E> IntoDeserializer<'de, E> for String impl<'de, E> IntoDeserializer<'de, E> for String
where where
E: de::Error, E: de::Error,
@@ -378,7 +447,7 @@ where
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, E> de::Deserializer<'de> for StringDeserializer<E> impl<'de, E> de::Deserializer<'de> for StringDeserializer<E>
where where
E: de::Error, E: de::Error,
@@ -413,7 +482,7 @@ where
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> de::EnumAccess<'de> for StringDeserializer<E> impl<'de, 'a, E> de::EnumAccess<'de> for StringDeserializer<E>
where where
E: de::Error, E: de::Error,
@@ -432,14 +501,14 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `Cow<str>`. /// A deserializer holding a `Cow<str>`.
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct CowStrDeserializer<'a, E> { pub struct CowStrDeserializer<'a, E> {
value: Cow<'a, str>, value: Cow<'a, str>,
marker: PhantomData<E>, marker: PhantomData<E>,
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str> impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str>
where where
E: de::Error, E: de::Error,
@@ -454,7 +523,7 @@ where
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E> impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E>
where where
E: de::Error, E: de::Error,
@@ -492,7 +561,7 @@ where
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> de::EnumAccess<'de> for CowStrDeserializer<'a, E> impl<'de, 'a, E> de::EnumAccess<'de> for CowStrDeserializer<'a, E>
where where
E: de::Error, E: de::Error,
@@ -510,6 +579,46 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `&[u8]` with a lifetime tied to another
/// deserializer.
#[derive(Clone, Debug)]
pub struct BorrowedBytesDeserializer<'de, E> {
value: &'de [u8],
marker: PhantomData<E>,
}
impl<'de, E> BorrowedBytesDeserializer<'de, E> {
/// Create a new borrowed deserializer from the given byte slice.
pub fn new(value: &'de [u8]) -> BorrowedBytesDeserializer<'de, E> {
BorrowedBytesDeserializer {
value: value,
marker: PhantomData,
}
}
}
impl<'de, E> de::Deserializer<'de> for BorrowedBytesDeserializer<'de, E>
where
E: de::Error,
{
type Error = E;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_borrowed_bytes(self.value)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
map struct identifier ignored_any enum
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer that iterates over a sequence. /// A deserializer that iterates over a sequence.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SeqDeserializer<I, E> { pub struct SeqDeserializer<I, E> {
@@ -618,7 +727,7 @@ impl Expected for ExpectedInSeq {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, T, E> IntoDeserializer<'de, E> for Vec<T> impl<'de, T, E> IntoDeserializer<'de, E> for Vec<T>
where where
T: IntoDeserializer<'de, E>, T: IntoDeserializer<'de, E>,
@@ -631,7 +740,7 @@ where
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, T, E> IntoDeserializer<'de, E> for BTreeSet<T> impl<'de, T, E> IntoDeserializer<'de, E> for BTreeSet<T>
where where
T: IntoDeserializer<'de, E> + Eq + Ord, T: IntoDeserializer<'de, E> + Eq + Ord,
@@ -1036,7 +1145,7 @@ impl Expected for ExpectedInMap {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap<K, V> impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap<K, V>
where where
K: IntoDeserializer<'de, E> + Eq + Ord, K: IntoDeserializer<'de, E> + Eq + Ord,
+2 -2
View File
@@ -19,7 +19,7 @@ pub use self::string::from_utf8_lossy;
mod string { mod string {
use lib::*; use lib::*;
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> { pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
String::from_utf8_lossy(bytes) String::from_utf8_lossy(bytes)
} }
@@ -31,7 +31,7 @@ mod string {
// //
// so it is okay for the return type to be different from the std case as long // so it is okay for the return type to be different from the std case as long
// as the above works. // as the above works.
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
pub fn from_utf8_lossy(bytes: &[u8]) -> &str { pub fn from_utf8_lossy(bytes: &[u8]) -> &str {
// Three unicode replacement characters if it fails. They look like a // Three unicode replacement characters if it fails. They look like a
// white-on-black question mark. The user will recognize it as invalid // white-on-black question mark. The user will recognize it as invalid
+13 -17
View File
@@ -79,7 +79,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here. // Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.2")] #![doc(html_root_url = "https://docs.rs/serde/1.0.10")]
// Support using Serde without the standard library! // Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
@@ -91,7 +91,6 @@
#![cfg_attr(feature = "unstable", feature(nonzero, specialization))] #![cfg_attr(feature = "unstable", feature(nonzero, specialization))]
#![cfg_attr(all(feature = "std", feature = "unstable"), feature(into_boxed_c_str))] #![cfg_attr(all(feature = "std", feature = "unstable"), feature(into_boxed_c_str))]
#![cfg_attr(feature = "alloc", feature(alloc))] #![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "collections", feature(collections))]
// Whitelisted clippy lints. // Whitelisted clippy lints.
#![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))] #![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))]
@@ -104,18 +103,15 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "collections")]
extern crate collections;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
extern crate alloc; extern crate alloc;
#[cfg(all(feature = "unstable", feature = "std"))] #[cfg(all(feature = "unstable", feature = "std"))]
extern crate core; extern crate core;
/// A facade around all the types we need from the `std`, `core`, `alloc`, and /// A facade around all the types we need from the `std`, `core`, and `alloc`
/// `collections` crates. This avoids elaborate import wrangling having to /// crates. This avoids elaborate import wrangling having to happen in every
/// happen in every module. /// module.
mod lib { mod lib {
mod core { mod core {
#[cfg(feature = "std")] #[cfg(feature = "std")]
@@ -140,18 +136,18 @@ mod lib {
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::borrow::{Cow, ToOwned}; pub use std::borrow::{Cow, ToOwned};
#[cfg(all(feature = "collections", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
pub use collections::borrow::{Cow, ToOwned}; pub use alloc::borrow::{Cow, ToOwned};
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::string::String; pub use std::string::String;
#[cfg(all(feature = "collections", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
pub use collections::string::{String, ToString}; pub use alloc::string::{String, ToString};
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::vec::Vec; pub use std::vec::Vec;
#[cfg(all(feature = "collections", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
pub use collections::vec::Vec; pub use alloc::vec::Vec;
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::boxed::Box; pub use std::boxed::Box;
@@ -170,8 +166,8 @@ mod lib {
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque}; pub use std::collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
#[cfg(all(feature = "collections", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
pub use collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque}; pub use alloc::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::{error, net}; pub use std::{error, net};
@@ -187,7 +183,7 @@ mod lib {
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::path::{Path, PathBuf}; pub use std::path::{Path, PathBuf};
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::time::Duration; pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::sync::{Mutex, RwLock}; pub use std::sync::{Mutex, RwLock};
+178 -120
View File
@@ -10,10 +10,10 @@ use lib::*;
use de::{Deserialize, Deserializer, IntoDeserializer, Error, Visitor}; use de::{Deserialize, Deserializer, IntoDeserializer, Error, Visitor};
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
use de::Unexpected; use de::Unexpected;
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub use self::content::{Content, ContentRefDeserializer, ContentDeserializer, pub use self::content::{Content, ContentRefDeserializer, ContentDeserializer,
TaggedContentVisitor, TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, TagOrContentField, TagOrContentFieldVisitor,
TagContentOtherField, TagContentOtherFieldVisitor, TagContentOtherField, TagContentOtherFieldVisitor,
@@ -59,7 +59,7 @@ where
Deserialize::deserialize(deserializer) Deserialize::deserialize(deserializer)
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, str>, D::Error> pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, str>, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
@@ -128,7 +128,7 @@ where
deserializer.deserialize_str(CowStrVisitor) deserializer.deserialize_str(CowStrVisitor)
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn borrow_cow_bytes<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, [u8]>, D::Error> pub fn borrow_cow_bytes<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, [u8]>, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
@@ -210,7 +210,7 @@ pub mod size_hint {
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
mod content { mod content {
// This module is private and nothing here should be used outside of // This module is private and nothing here should be used outside of
// generated code. // generated code.
@@ -233,7 +233,7 @@ mod content {
/// ///
/// Not public API. Use serde-value instead. /// Not public API. Use serde-value instead.
#[derive(Debug)] #[derive(Debug)]
pub enum Content { pub enum Content<'de> {
Bool(bool), Bool(bool),
U8(u8), U8(u8),
@@ -251,18 +251,20 @@ mod content {
Char(char), Char(char),
String(String), String(String),
Bytes(Vec<u8>), Str(&'de str),
ByteBuf(Vec<u8>),
Bytes(&'de [u8]),
None, None,
Some(Box<Content>), Some(Box<Content<'de>>),
Unit, Unit,
Newtype(Box<Content>), Newtype(Box<Content<'de>>),
Seq(Vec<Content>), Seq(Vec<Content<'de>>),
Map(Vec<(Content, Content)>), Map(Vec<(Content<'de>, Content<'de>)>),
} }
impl Content { impl<'de> Content<'de> {
fn unexpected(&self) -> Unexpected { fn unexpected(&self) -> Unexpected {
match *self { match *self {
Content::Bool(b) => Unexpected::Bool(b), Content::Bool(b) => Unexpected::Bool(b),
@@ -278,7 +280,9 @@ mod content {
Content::F64(f) => Unexpected::Float(f), Content::F64(f) => Unexpected::Float(f),
Content::Char(c) => Unexpected::Char(c), Content::Char(c) => Unexpected::Char(c),
Content::String(ref s) => Unexpected::Str(s), Content::String(ref s) => Unexpected::Str(s),
Content::Bytes(ref b) => Unexpected::Bytes(b), Content::Str(s) => Unexpected::Str(s),
Content::ByteBuf(ref b) => Unexpected::Bytes(b),
Content::Bytes(b) => Unexpected::Bytes(b),
Content::None | Content::Some(_) => Unexpected::Option, Content::None | Content::Some(_) => Unexpected::Option,
Content::Unit => Unexpected::Unit, Content::Unit => Unexpected::Unit,
Content::Newtype(_) => Unexpected::NewtypeStruct, Content::Newtype(_) => Unexpected::NewtypeStruct,
@@ -288,21 +292,30 @@ mod content {
} }
} }
impl<'de> Deserialize<'de> for Content { impl<'de> Deserialize<'de> for Content<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
// Untagged and internally tagged enums are only supported in // Untagged and internally tagged enums are only supported in
// self-describing formats. // self-describing formats.
deserializer.deserialize_any(ContentVisitor) let visitor = ContentVisitor { value: PhantomData };
deserializer.deserialize_any(visitor)
} }
} }
struct ContentVisitor; struct ContentVisitor<'de> {
value: PhantomData<Content<'de>>,
}
impl<'de> Visitor<'de> for ContentVisitor { impl<'de> ContentVisitor<'de> {
type Value = Content; fn new() -> Self {
ContentVisitor { value: PhantomData }
}
}
impl<'de> Visitor<'de> for ContentVisitor<'de> {
type Value = Content<'de>;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str("any value") fmt.write_str("any value")
@@ -399,6 +412,13 @@ mod content {
Ok(Content::String(value.into())) Ok(Content::String(value.into()))
} }
fn visit_borrowed_str<F>(self, value: &'de str) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Str(value))
}
fn visit_string<F>(self, value: String) -> Result<Self::Value, F> fn visit_string<F>(self, value: String) -> Result<Self::Value, F>
where where
F: de::Error, F: de::Error,
@@ -410,14 +430,21 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
Ok(Content::Bytes(value.into())) Ok(Content::ByteBuf(value.into()))
}
fn visit_borrowed_bytes<F>(self, value: &'de [u8]) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Bytes(value))
} }
fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F> fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F>
where where
F: de::Error, F: de::Error,
{ {
Ok(Content::Bytes(value)) Ok(Content::ByteBuf(value))
} }
fn visit_unit<F>(self) -> Result<Self::Value, F> fn visit_unit<F>(self) -> Result<Self::Value, F>
@@ -481,23 +508,24 @@ mod content {
/// This is the type of the map keys in an internally tagged enum. /// This is the type of the map keys in an internally tagged enum.
/// ///
/// Not public API. /// Not public API.
pub enum TagOrContent { pub enum TagOrContent<'de> {
Tag, Tag,
Content(Content), Content(Content<'de>),
} }
struct TagOrContentVisitor { struct TagOrContentVisitor<'de> {
name: &'static str, name: &'static str,
value: PhantomData<TagOrContent<'de>>,
} }
impl TagOrContentVisitor { impl<'de> TagOrContentVisitor<'de> {
fn new(name: &'static str) -> Self { fn new(name: &'static str) -> Self {
TagOrContentVisitor { name: name } TagOrContentVisitor { name: name, value: PhantomData }
} }
} }
impl<'de> DeserializeSeed<'de> for TagOrContentVisitor { impl<'de> DeserializeSeed<'de> for TagOrContentVisitor<'de> {
type Value = TagOrContent; type Value = TagOrContent<'de>;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where where
@@ -509,8 +537,8 @@ mod content {
} }
} }
impl<'de> Visitor<'de> for TagOrContentVisitor { impl<'de> Visitor<'de> for TagOrContentVisitor<'de> {
type Value = TagOrContent; type Value = TagOrContent<'de>;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "a type tag `{}` or any other value", self.name) write!(fmt, "a type tag `{}` or any other value", self.name)
@@ -520,7 +548,7 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor ContentVisitor::new()
.visit_bool(value) .visit_bool(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -529,14 +557,14 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor.visit_i8(value).map(TagOrContent::Content) ContentVisitor::new().visit_i8(value).map(TagOrContent::Content)
} }
fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F> fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F>
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor ContentVisitor::new()
.visit_i16(value) .visit_i16(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -545,7 +573,7 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor ContentVisitor::new()
.visit_i32(value) .visit_i32(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -554,7 +582,7 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor ContentVisitor::new()
.visit_i64(value) .visit_i64(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -563,14 +591,14 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor.visit_u8(value).map(TagOrContent::Content) ContentVisitor::new().visit_u8(value).map(TagOrContent::Content)
} }
fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F> fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F>
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor ContentVisitor::new()
.visit_u16(value) .visit_u16(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -579,7 +607,7 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor ContentVisitor::new()
.visit_u32(value) .visit_u32(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -588,7 +616,7 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor ContentVisitor::new()
.visit_u64(value) .visit_u64(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -597,7 +625,7 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor ContentVisitor::new()
.visit_f32(value) .visit_f32(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -606,7 +634,7 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor ContentVisitor::new()
.visit_f64(value) .visit_f64(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -615,7 +643,7 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor ContentVisitor::new()
.visit_char(value) .visit_char(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -627,12 +655,25 @@ mod content {
if value == self.name { if value == self.name {
Ok(TagOrContent::Tag) Ok(TagOrContent::Tag)
} else { } else {
ContentVisitor ContentVisitor::new()
.visit_str(value) .visit_str(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
} }
fn visit_borrowed_str<F>(self, value: &'de str) -> Result<Self::Value, F>
where
F: de::Error,
{
if value == self.name {
Ok(TagOrContent::Tag)
} else {
ContentVisitor::new()
.visit_borrowed_str(value)
.map(TagOrContent::Content)
}
}
fn visit_string<F>(self, value: String) -> Result<Self::Value, F> fn visit_string<F>(self, value: String) -> Result<Self::Value, F>
where where
F: de::Error, F: de::Error,
@@ -640,7 +681,7 @@ mod content {
if value == self.name { if value == self.name {
Ok(TagOrContent::Tag) Ok(TagOrContent::Tag)
} else { } else {
ContentVisitor ContentVisitor::new()
.visit_string(value) .visit_string(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -653,12 +694,25 @@ mod content {
if value == self.name.as_bytes() { if value == self.name.as_bytes() {
Ok(TagOrContent::Tag) Ok(TagOrContent::Tag)
} else { } else {
ContentVisitor ContentVisitor::new()
.visit_bytes(value) .visit_bytes(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
} }
fn visit_borrowed_bytes<F>(self, value: &'de [u8]) -> Result<Self::Value, F>
where
F: de::Error,
{
if value == self.name.as_bytes() {
Ok(TagOrContent::Tag)
} else {
ContentVisitor::new()
.visit_borrowed_bytes(value)
.map(TagOrContent::Content)
}
}
fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F> fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F>
where where
F: de::Error, F: de::Error,
@@ -666,7 +720,7 @@ mod content {
if value == self.name.as_bytes() { if value == self.name.as_bytes() {
Ok(TagOrContent::Tag) Ok(TagOrContent::Tag)
} else { } else {
ContentVisitor ContentVisitor::new()
.visit_byte_buf(value) .visit_byte_buf(value)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -676,21 +730,21 @@ mod content {
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor.visit_unit().map(TagOrContent::Content) ContentVisitor::new().visit_unit().map(TagOrContent::Content)
} }
fn visit_none<F>(self) -> Result<Self::Value, F> fn visit_none<F>(self) -> Result<Self::Value, F>
where where
F: de::Error, F: de::Error,
{ {
ContentVisitor.visit_none().map(TagOrContent::Content) ContentVisitor::new().visit_none().map(TagOrContent::Content)
} }
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error> fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
ContentVisitor ContentVisitor::new()
.visit_some(deserializer) .visit_some(deserializer)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -699,7 +753,7 @@ mod content {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
ContentVisitor ContentVisitor::new()
.visit_newtype_struct(deserializer) .visit_newtype_struct(deserializer)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -708,7 +762,7 @@ mod content {
where where
V: SeqAccess<'de>, V: SeqAccess<'de>,
{ {
ContentVisitor ContentVisitor::new()
.visit_seq(visitor) .visit_seq(visitor)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -717,7 +771,7 @@ mod content {
where where
V: MapAccess<'de>, V: MapAccess<'de>,
{ {
ContentVisitor ContentVisitor::new()
.visit_map(visitor) .visit_map(visitor)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -726,7 +780,7 @@ mod content {
where where
V: EnumAccess<'de>, V: EnumAccess<'de>,
{ {
ContentVisitor ContentVisitor::new()
.visit_enum(visitor) .visit_enum(visitor)
.map(TagOrContent::Content) .map(TagOrContent::Content)
} }
@@ -735,33 +789,33 @@ mod content {
/// Used by generated code to deserialize an internally tagged enum. /// Used by generated code to deserialize an internally tagged enum.
/// ///
/// Not public API. /// Not public API.
pub struct TaggedContent<T> { pub struct TaggedContent<'de, T> {
pub tag: T, pub tag: T,
pub content: Content, pub content: Content<'de>,
} }
/// Not public API. /// Not public API.
pub struct TaggedContentVisitor<T> { pub struct TaggedContentVisitor<'de, T> {
tag_name: &'static str, tag_name: &'static str,
tag: PhantomData<T>, value: PhantomData<TaggedContent<'de, T>>,
} }
impl<T> TaggedContentVisitor<T> { impl<'de, T> TaggedContentVisitor<'de, T> {
/// Visitor for the content of an internally tagged enum with the given tag /// Visitor for the content of an internally tagged enum with the given tag
/// name. /// name.
pub fn new(name: &'static str) -> Self { pub fn new(name: &'static str) -> Self {
TaggedContentVisitor { TaggedContentVisitor {
tag_name: name, tag_name: name,
tag: PhantomData, value: PhantomData,
} }
} }
} }
impl<'de, T> DeserializeSeed<'de> for TaggedContentVisitor<T> impl<'de, T> DeserializeSeed<'de> for TaggedContentVisitor<'de, T>
where where
T: Deserialize<'de>, T: Deserialize<'de>,
{ {
type Value = TaggedContent<T>; type Value = TaggedContent<'de, T>;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where where
@@ -773,11 +827,11 @@ mod content {
} }
} }
impl<'de, T> Visitor<'de> for TaggedContentVisitor<T> impl<'de, T> Visitor<'de> for TaggedContentVisitor<'de, T>
where where
T: Deserialize<'de>, T: Deserialize<'de>,
{ {
type Value = TaggedContent<T>; type Value = TaggedContent<'de, T>;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str("any value") fmt.write_str("any value")
@@ -913,14 +967,14 @@ mod content {
} }
/// Not public API /// Not public API
pub struct ContentDeserializer<E> { pub struct ContentDeserializer<'de, E> {
content: Content, content: Content<'de>,
err: PhantomData<E>, err: PhantomData<E>,
} }
/// Used when deserializing an internally tagged enum because the content will /// Used when deserializing an internally tagged enum because the content will
/// be used exactly once. /// be used exactly once.
impl<'de, E> Deserializer<'de> for ContentDeserializer<E> impl<'de, E> Deserializer<'de> for ContentDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -944,6 +998,9 @@ mod content {
Content::F64(v) => visitor.visit_f64(v), Content::F64(v) => visitor.visit_f64(v),
Content::Char(v) => visitor.visit_char(v), Content::Char(v) => visitor.visit_char(v),
Content::String(v) => visitor.visit_string(v), Content::String(v) => visitor.visit_string(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(v) => visitor.visit_byte_buf(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::Unit => visitor.visit_unit(), Content::Unit => visitor.visit_unit(),
Content::None => visitor.visit_none(), Content::None => visitor.visit_none(),
Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)), Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)),
@@ -965,7 +1022,6 @@ mod content {
try!(map_visitor.end()); try!(map_visitor.end());
Ok(value) Ok(value)
} }
Content::Bytes(v) => visitor.visit_byte_buf(v),
} }
} }
@@ -1026,7 +1082,7 @@ mod content {
} }
(variant, Some(value)) (variant, Some(value))
} }
Content::String(variant) => (Content::String(variant), None), s @ Content::String(_) | s @ Content::Str(_) => (s, None),
other => { other => {
return Err(de::Error::invalid_type(other.unexpected(), &"string or map"),); return Err(de::Error::invalid_type(other.unexpected(), &"string or map"),);
} }
@@ -1048,9 +1104,9 @@ mod content {
} }
} }
impl<E> ContentDeserializer<E> { impl<'de, E> ContentDeserializer<'de, E> {
/// private API, don't use /// private API, don't use
pub fn new(content: Content) -> Self { pub fn new(content: Content<'de>) -> Self {
ContentDeserializer { ContentDeserializer {
content: content, content: content,
err: PhantomData, err: PhantomData,
@@ -1058,21 +1114,21 @@ mod content {
} }
} }
struct EnumDeserializer<E> struct EnumDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
variant: Content, variant: Content<'de>,
value: Option<Content>, value: Option<Content<'de>>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<'de, E> de::EnumAccess<'de> for EnumDeserializer<E> impl<'de, E> de::EnumAccess<'de> for EnumDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
type Error = E; type Error = E;
type Variant = VariantDeserializer<Self::Error>; type Variant = VariantDeserializer<'de, Self::Error>;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), E> fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), E>
where where
@@ -1087,15 +1143,15 @@ mod content {
} }
} }
struct VariantDeserializer<E> struct VariantDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
value: Option<Content>, value: Option<Content<'de>>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<'de, E> de::VariantAccess<'de> for VariantDeserializer<E> impl<'de, E> de::VariantAccess<'de> for VariantDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1151,19 +1207,19 @@ mod content {
} }
} }
struct SeqDeserializer<E> struct SeqDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
iter: <Vec<Content> as IntoIterator>::IntoIter, iter: <Vec<Content<'de>> as IntoIterator>::IntoIter,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<E> SeqDeserializer<E> impl<'de, E> SeqDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
fn new(vec: Vec<Content>) -> Self { fn new(vec: Vec<Content<'de>>) -> Self {
SeqDeserializer { SeqDeserializer {
iter: vec.into_iter(), iter: vec.into_iter(),
err: PhantomData, err: PhantomData,
@@ -1171,7 +1227,7 @@ mod content {
} }
} }
impl<'de, E> de::Deserializer<'de> for SeqDeserializer<E> impl<'de, E> de::Deserializer<'de> for SeqDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1203,7 +1259,7 @@ mod content {
} }
} }
impl<'de, E> de::SeqAccess<'de> for SeqDeserializer<E> impl<'de, E> de::SeqAccess<'de> for SeqDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1227,20 +1283,20 @@ mod content {
} }
} }
struct MapDeserializer<E> struct MapDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
iter: <Vec<(Content, Content)> as IntoIterator>::IntoIter, iter: <Vec<(Content<'de>, Content<'de>)> as IntoIterator>::IntoIter,
value: Option<Content>, value: Option<Content<'de>>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<E> MapDeserializer<E> impl<'de, E> MapDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
fn new(map: Vec<(Content, Content)>) -> Self { fn new(map: Vec<(Content<'de>, Content<'de>)>) -> Self {
MapDeserializer { MapDeserializer {
iter: map.into_iter(), iter: map.into_iter(),
value: None, value: None,
@@ -1249,7 +1305,7 @@ mod content {
} }
} }
impl<'de, E> de::MapAccess<'de> for MapDeserializer<E> impl<'de, E> de::MapAccess<'de> for MapDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1283,7 +1339,7 @@ mod content {
} }
} }
impl<'de, E> de::Deserializer<'de> for MapDeserializer<E> impl<'de, E> de::Deserializer<'de> for MapDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1305,14 +1361,14 @@ mod content {
} }
/// Not public API. /// Not public API.
pub struct ContentRefDeserializer<'a, E> { pub struct ContentRefDeserializer<'a, 'de: 'a, E> {
content: &'a Content, content: &'a Content<'de>,
err: PhantomData<E>, err: PhantomData<E>,
} }
/// Used when deserializing an untagged enum because the content may need to be /// Used when deserializing an untagged enum because the content may need to be
/// used more than once. /// used more than once.
impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, E> impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, 'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1336,6 +1392,9 @@ mod content {
Content::F64(v) => visitor.visit_f64(v), Content::F64(v) => visitor.visit_f64(v),
Content::Char(v) => visitor.visit_char(v), Content::Char(v) => visitor.visit_char(v),
Content::String(ref v) => visitor.visit_str(v), Content::String(ref v) => visitor.visit_str(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(ref v) => visitor.visit_bytes(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::Unit => visitor.visit_unit(), Content::Unit => visitor.visit_unit(),
Content::None => visitor.visit_none(), Content::None => visitor.visit_none(),
Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)), Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)),
@@ -1361,7 +1420,6 @@ mod content {
try!(map_visitor.end()); try!(map_visitor.end());
Ok(value) Ok(value)
} }
Content::Bytes(ref v) => visitor.visit_bytes(v),
} }
} }
@@ -1418,7 +1476,7 @@ mod content {
} }
(variant, Some(value)) (variant, Some(value))
} }
ref s @ Content::String(_) => (s, None), ref s @ Content::String(_) | ref s @ Content::Str(_) => (s, None),
ref other => { ref other => {
return Err(de::Error::invalid_type(other.unexpected(), &"string or map"),); return Err(de::Error::invalid_type(other.unexpected(), &"string or map"),);
} }
@@ -1440,9 +1498,9 @@ mod content {
} }
} }
impl<'a, E> ContentRefDeserializer<'a, E> { impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> {
/// private API, don't use /// private API, don't use
pub fn new(content: &'a Content) -> Self { pub fn new(content: &'a Content<'de>) -> Self {
ContentRefDeserializer { ContentRefDeserializer {
content: content, content: content,
err: PhantomData, err: PhantomData,
@@ -1450,21 +1508,21 @@ mod content {
} }
} }
struct EnumRefDeserializer<'a, E> struct EnumRefDeserializer<'a, 'de: 'a, E>
where where
E: de::Error, E: de::Error,
{ {
variant: &'a Content, variant: &'a Content<'de>,
value: Option<&'a Content>, value: Option<&'a Content<'de>>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<'de, 'a, E> de::EnumAccess<'de> for EnumRefDeserializer<'a, E> impl<'de, 'a, E> de::EnumAccess<'de> for EnumRefDeserializer<'a, 'de, E>
where where
E: de::Error, E: de::Error,
{ {
type Error = E; type Error = E;
type Variant = VariantRefDeserializer<'a, Self::Error>; type Variant = VariantRefDeserializer<'a, 'de, Self::Error>;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
where where
@@ -1479,15 +1537,15 @@ mod content {
} }
} }
struct VariantRefDeserializer<'a, E> struct VariantRefDeserializer<'a, 'de: 'a, E>
where where
E: de::Error, E: de::Error,
{ {
value: Option<&'a Content>, value: Option<&'a Content<'de>>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<'de, 'a, E> de::VariantAccess<'de> for VariantRefDeserializer<'a, E> impl<'de, 'a, E> de::VariantAccess<'de> for VariantRefDeserializer<'a, 'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1543,19 +1601,19 @@ mod content {
} }
} }
struct SeqRefDeserializer<'a, E> struct SeqRefDeserializer<'a, 'de: 'a, E>
where where
E: de::Error, E: de::Error,
{ {
iter: <&'a [Content] as IntoIterator>::IntoIter, iter: <&'a [Content<'de>] as IntoIterator>::IntoIter,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<'a, E> SeqRefDeserializer<'a, E> impl<'a, 'de, E> SeqRefDeserializer<'a, 'de, E>
where where
E: de::Error, E: de::Error,
{ {
fn new(vec: &'a [Content]) -> Self { fn new(vec: &'a [Content<'de>]) -> Self {
SeqRefDeserializer { SeqRefDeserializer {
iter: vec.into_iter(), iter: vec.into_iter(),
err: PhantomData, err: PhantomData,
@@ -1563,7 +1621,7 @@ mod content {
} }
} }
impl<'de, 'a, E> de::Deserializer<'de> for SeqRefDeserializer<'a, E> impl<'de, 'a, E> de::Deserializer<'de> for SeqRefDeserializer<'a, 'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1595,7 +1653,7 @@ mod content {
} }
} }
impl<'de, 'a, E> de::SeqAccess<'de> for SeqRefDeserializer<'a, E> impl<'de, 'a, E> de::SeqAccess<'de> for SeqRefDeserializer<'a, 'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1619,20 +1677,20 @@ mod content {
} }
} }
struct MapRefDeserializer<'a, E> struct MapRefDeserializer<'a, 'de: 'a, E>
where where
E: de::Error, E: de::Error,
{ {
iter: <&'a [(Content, Content)] as IntoIterator>::IntoIter, iter: <&'a [(Content<'de>, Content<'de>)] as IntoIterator>::IntoIter,
value: Option<&'a Content>, value: Option<&'a Content<'de>>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<'a, E> MapRefDeserializer<'a, E> impl<'a, 'de, E> MapRefDeserializer<'a, 'de, E>
where where
E: de::Error, E: de::Error,
{ {
fn new(map: &'a [(Content, Content)]) -> Self { fn new(map: &'a [(Content<'de>, Content<'de>)]) -> Self {
MapRefDeserializer { MapRefDeserializer {
iter: map.into_iter(), iter: map.into_iter(),
value: None, value: None,
@@ -1641,7 +1699,7 @@ mod content {
} }
} }
impl<'de, 'a, E> de::MapAccess<'de> for MapRefDeserializer<'a, E> impl<'de, 'a, E> de::MapAccess<'de> for MapRefDeserializer<'a, 'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1676,7 +1734,7 @@ mod content {
} }
} }
impl<'de, 'a, E> de::Deserializer<'de> for MapRefDeserializer<'a, E> impl<'de, 'a, E> de::Deserializer<'de> for MapRefDeserializer<'a, 'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1697,7 +1755,7 @@ mod content {
} }
} }
impl<'de, E> de::IntoDeserializer<'de, E> for ContentDeserializer<E> impl<'de, E> de::IntoDeserializer<'de, E> for ContentDeserializer<'de, E>
where where
E: de::Error, E: de::Error,
{ {
@@ -1708,7 +1766,7 @@ mod content {
} }
} }
impl<'de, 'a, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'a, E> impl<'de, 'a, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'a, 'de, E>
where where
E: de::Error, E: de::Error,
{ {
+13 -13
View File
@@ -10,7 +10,7 @@ use lib::*;
use ser::{self, Serialize, Serializer, SerializeMap, SerializeStruct, Impossible}; use ser::{self, Serialize, Serializer, SerializeMap, SerializeStruct, Impossible};
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
use self::content::{SerializeTupleVariantAsMapValue, SerializeStructVariantAsMapValue}; use self::content::{SerializeTupleVariantAsMapValue, SerializeStructVariantAsMapValue};
/// Used to check that serde(getter) attributes return the expected type. /// Used to check that serde(getter) attributes return the expected type.
@@ -64,7 +64,7 @@ enum Unsupported {
Sequence, Sequence,
Tuple, Tuple,
TupleStruct, TupleStruct,
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
Enum, Enum,
} }
@@ -83,7 +83,7 @@ impl Display for Unsupported {
Unsupported::Sequence => formatter.write_str("a sequence"), Unsupported::Sequence => formatter.write_str("a sequence"),
Unsupported::Tuple => formatter.write_str("a tuple"), Unsupported::Tuple => formatter.write_str("a tuple"),
Unsupported::TupleStruct => formatter.write_str("a tuple struct"), Unsupported::TupleStruct => formatter.write_str("a tuple struct"),
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
Unsupported::Enum => formatter.write_str("an enum"), Unsupported::Enum => formatter.write_str("an enum"),
} }
} }
@@ -117,14 +117,14 @@ where
type SerializeMap = S::SerializeMap; type SerializeMap = S::SerializeMap;
type SerializeStruct = S::SerializeStruct; type SerializeStruct = S::SerializeStruct;
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
type SerializeTupleVariant = Impossible<S::Ok, S::Error>; type SerializeTupleVariant = Impossible<S::Ok, S::Error>;
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
type SerializeTupleVariant = SerializeTupleVariantAsMapValue<S::SerializeMap>; type SerializeTupleVariant = SerializeTupleVariantAsMapValue<S::SerializeMap>;
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
type SerializeStructVariant = Impossible<S::Ok, S::Error>; type SerializeStructVariant = Impossible<S::Ok, S::Error>;
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
type SerializeStructVariant = SerializeStructVariantAsMapValue<S::SerializeMap>; type SerializeStructVariant = SerializeStructVariantAsMapValue<S::SerializeMap>;
fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> { fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
@@ -257,7 +257,7 @@ where
Err(self.bad_type(Unsupported::TupleStruct)) Err(self.bad_type(Unsupported::TupleStruct))
} }
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
fn serialize_tuple_variant( fn serialize_tuple_variant(
self, self,
_: &'static str, _: &'static str,
@@ -270,7 +270,7 @@ where
Err(self.bad_type(Unsupported::Enum)) Err(self.bad_type(Unsupported::Enum))
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
fn serialize_tuple_variant( fn serialize_tuple_variant(
self, self,
_: &'static str, _: &'static str,
@@ -300,7 +300,7 @@ where
Ok(state) Ok(state)
} }
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
fn serialize_struct_variant( fn serialize_struct_variant(
self, self,
_: &'static str, _: &'static str,
@@ -313,7 +313,7 @@ where
Err(self.bad_type(Unsupported::Enum)) Err(self.bad_type(Unsupported::Enum))
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
fn serialize_struct_variant( fn serialize_struct_variant(
self, self,
_: &'static str, _: &'static str,
@@ -327,7 +327,7 @@ where
Ok(SerializeStructVariantAsMapValue::new(map, inner_variant, len),) Ok(SerializeStructVariantAsMapValue::new(map, inner_variant, len),)
} }
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
fn collect_str<T: ?Sized>(self, _: &T) -> Result<Self::Ok, Self::Error> fn collect_str<T: ?Sized>(self, _: &T) -> Result<Self::Ok, Self::Error>
where where
T: Display, T: Display,
@@ -363,7 +363,7 @@ impl Display for Error {
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
mod content { mod content {
use lib::*; use lib::*;
+40 -11
View File
@@ -56,7 +56,7 @@ impl Serialize for str {
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl Serialize for String { impl Serialize for String {
#[inline] #[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -177,6 +177,7 @@ where
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! seq_impl { macro_rules! seq_impl {
($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => { ($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => {
impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*> impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
@@ -195,22 +196,22 @@ macro_rules! seq_impl {
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(BinaryHeap<T: Ord>); seq_impl!(BinaryHeap<T: Ord>);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(BTreeSet<T: Ord>); seq_impl!(BTreeSet<T: Ord>);
#[cfg(feature = "std")] #[cfg(feature = "std")]
seq_impl!(HashSet<T: Eq + Hash, H: BuildHasher>); seq_impl!(HashSet<T: Eq + Hash, H: BuildHasher>);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(LinkedList<T>); seq_impl!(LinkedList<T>);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(Vec<T>); seq_impl!(Vec<T>);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(VecDeque<T>); seq_impl!(VecDeque<T>);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -290,6 +291,7 @@ tuple_impls! {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! map_impl { macro_rules! map_impl {
($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => { ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => {
impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*> impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
@@ -309,7 +311,7 @@ macro_rules! map_impl {
} }
} }
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
map_impl!(BTreeMap<K: Ord, V>); map_impl!(BTreeMap<K: Ord, V>);
#[cfg(feature = "std")] #[cfg(feature = "std")]
@@ -343,14 +345,24 @@ deref_impl!(<T> Serialize for Rc<T> where T: Serialize);
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))] #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
deref_impl!(<T> Serialize for Arc<T> where T: Serialize); deref_impl!(<T> Serialize for Arc<T> where T: Serialize);
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned); deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned);
#[cfg(feature = "unstable")]
deref_impl!(<T> Serialize for NonZero<T> where T: Serialize + Zeroable);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "unstable")]
impl<T> Serialize for NonZero<T>
where
T: Serialize + Zeroable + Clone,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.clone().get().serialize(serializer)
}
}
impl<T> Serialize for Cell<T> impl<T> Serialize for Cell<T>
where where
T: Serialize + Copy, T: Serialize + Copy,
@@ -445,6 +457,23 @@ impl Serialize for Duration {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
impl Serialize for SystemTime {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use super::SerializeStruct;
let duration_since_epoch = self.duration_since(UNIX_EPOCH).expect("SystemTime must be later than UNIX_EPOCH");
let mut state = try!(serializer.serialize_struct("SystemTime", 2));
try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
state.end()
}
}
////////////////////////////////////////////////////////////////////////////////
/// Serialize a value that implements `Display` as a string, when that string is /// Serialize a value that implements `Display` as a string, when that string is
/// statically known to never have more than a constant `MAX_LEN` bytes. /// statically known to never have more than a constant `MAX_LEN` bytes.
/// ///
+3 -2
View File
@@ -89,6 +89,7 @@
//! - OsString //! - OsString
//! - **Miscellaneous standard library types**: //! - **Miscellaneous standard library types**:
//! - Duration //! - Duration
//! - SystemTime
//! - Path //! - Path
//! - PathBuf //! - PathBuf
//! - Range\<T\> //! - Range\<T\>
@@ -1321,7 +1322,7 @@ pub trait Serializer: Sized {
/// ///
/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
/// [`serialize_str`]: #tymethod.serialize_str /// [`serialize_str`]: #tymethod.serialize_str
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "alloc"))]
fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where where
T: Display, T: Display,
@@ -1358,7 +1359,7 @@ pub trait Serializer: Sized {
/// } /// }
/// } /// }
/// ``` /// ```
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "alloc")))]
fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where where
T: Display; T: Display;
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.2" # remember to update html_root_url version = "1.0.10" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -20,5 +20,5 @@ proc-macro = true
[dependencies] [dependencies]
quote = "0.3.8" quote = "0.3.8"
serde_derive_internals = { version = "=0.15.0", default-features = false, path = "../serde_derive_internals" } serde_derive_internals = { version = "=0.15.1", default-features = false, path = "../serde_derive_internals" }
syn = { version = "0.11", features = ["visit"] } syn = { version = "0.11", features = ["visit"] }
+3 -5
View File
@@ -23,15 +23,14 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
let ident = &cont.ident; let ident = &cont.ident;
let params = Parameters::new(&cont); let params = Parameters::new(&cont);
let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params);
let dummy_const = Ident::new(format!("_IMPL_DESERIALIZE_FOR_{}", ident)); let dummy_const = Ident::new(format!("_IMPL_DESERIALIZE_FOR_{}", ident));
let body = Stmts(deserialize_body(&cont, &params)); let body = Stmts(deserialize_body(&cont, &params));
let impl_block = if let Some(remote) = cont.attrs.remote() { let impl_block = if let Some(remote) = cont.attrs.remote() {
let (impl_generics, ty_generics, where_clause) = cont.generics.split_for_impl();
let de_lifetime = params.de_lifetime_def();
quote! { quote! {
impl #impl_generics #ident #ty_generics #where_clause { impl #de_impl_generics #ident #ty_generics #where_clause {
fn deserialize<#de_lifetime, __D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error> fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
where __D: _serde::Deserializer<'de> where __D: _serde::Deserializer<'de>
{ {
#body #body
@@ -39,7 +38,6 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
} }
} }
} else { } else {
let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params);
quote! { quote! {
#[automatically_derived] #[automatically_derived]
impl #de_impl_generics _serde::Deserialize<'de> for #ident #ty_generics #where_clause { impl #de_impl_generics _serde::Deserialize<'de> for #ident #ty_generics #where_clause {
+1 -1
View File
@@ -16,7 +16,7 @@
//! //!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.2")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.10")]
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))] #![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
#![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))] #![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))]
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive_internals" name = "serde_derive_internals"
version = "0.15.0" # remember to update html_root_url version = "0.15.1" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "AST representation used by Serde derive macros. Unstable." description = "AST representation used by Serde derive macros. Unstable."
+6
View File
@@ -719,6 +719,12 @@ impl Field {
skip_deserializing.set_true(); skip_deserializing.set_true();
} }
// Parse `#[serde(skip)]`
MetaItem(Word(ref name)) if name == "skip" => {
skip_serializing.set_true();
skip_deserializing.set_true();
},
// Parse `#[serde(skip_serializing_if = "...")]` // Parse `#[serde(skip_serializing_if = "...")]`
MetaItem(NameValue(ref name, ref lit)) if name == "skip_serializing_if" => { MetaItem(NameValue(ref name, ref lit)) if name == "skip_serializing_if" => {
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) { if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+1 -1
View File
@@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.15.0")] #![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.15.1")]
extern crate syn; extern crate syn;
#[macro_use] #[macro_use]
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "1.0.2" # remember to update html_root_url version = "1.0.10" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations" description = "Token De/Serializer for testing De/Serialize implementations"
+1 -1
View File
@@ -155,7 +155,7 @@
//! # } //! # }
//! ``` //! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.2")] #![doc(html_root_url = "https://docs.rs/serde_test/1.0.10")]
#[macro_use] #[macro_use]
extern crate serde; extern crate serde;
+1
View File
@@ -4,5 +4,6 @@ version = "0.0.0"
publish = false publish = false
[dependencies] [dependencies]
libc = { version = "0.2", default-features = false }
serde = { path = "../../serde", default-features = false } serde = { path = "../../serde", default-features = false }
serde_derive = { path = "../../serde_derive" } serde_derive = { path = "../../serde_derive" }
+1 -1
View File
@@ -1,4 +1,4 @@
#![feature(lang_items, start, libc, compiler_builtins_lib)] #![feature(lang_items, start, compiler_builtins_lib)]
#![no_std] #![no_std]
extern crate libc; extern crate libc;
@@ -18,7 +18,9 @@ mod remote {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(remote = "remote::S")] #[serde(remote = "remote::S")]
struct S { struct S {
b: u8, //~^^^ ERROR: no field `b` on type `&remote::S` //~^^^ ERROR: struct `remote::S` has no field named `b`
//~^^^^ ERROR: struct `remote::S` has no field named `b`
b: u8, //~^^^^^ ERROR: no field `b` on type `&remote::S`
} }
fn main() {} fn main() {}
+35
View File
@@ -580,6 +580,41 @@ fn test_skip_serializing_struct() {
); );
} }
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct SkipStruct<B>
{
a: i8,
#[serde(skip)]
b: B,
}
#[test]
fn test_skip_struct() {
assert_ser_tokens(
&SkipStruct { a: 1, b: 2 },
&[
Token::Struct { name: "SkipStruct", len: 1 },
Token::Str("a"),
Token::I8(1),
Token::StructEnd,
],
);
assert_de_tokens(
&SkipStruct { a: 1, b: 0 },
&[
Token::Struct { name: "SkipStruct", len: 1 },
Token::Str("a"),
Token::I8(1),
Token::StructEnd,
],
);
}
#[derive(Debug, PartialEq, Serialize)] #[derive(Debug, PartialEq, Serialize)]
enum SkipSerializingEnum<'a, B, C> enum SkipSerializingEnum<'a, B, C>
where where
+24 -2
View File
@@ -13,8 +13,8 @@ extern crate serde_derive;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::net; use std::net;
use std::path::PathBuf; use std::path::{Path, PathBuf};
use std::time::Duration; use std::time::{Duration, UNIX_EPOCH};
use std::default::Default; use std::default::Default;
use std::ffi::{CString, OsString}; use std::ffi::{CString, OsString};
@@ -682,6 +682,23 @@ declare_tests! {
Token::SeqEnd, Token::SeqEnd,
], ],
} }
test_system_time {
UNIX_EPOCH + Duration::new(1, 2) => &[
Token::Struct { name: "SystemTime", len: 2 },
Token::Str("secs_since_epoch"),
Token::U64(1),
Token::Str("nanos_since_epoch"),
Token::U32(2),
Token::StructEnd,
],
UNIX_EPOCH + Duration::new(1, 2) => &[
Token::Seq { len: Some(2) },
Token::I64(1),
Token::I64(2),
Token::SeqEnd,
],
}
test_range { test_range {
1u32..2u32 => &[ 1u32..2u32 => &[
Token::Struct { name: "Range", len: 2 }, Token::Struct { name: "Range", len: 2 },
@@ -710,6 +727,11 @@ declare_tests! {
"1.2.3.4:1234".parse::<net::SocketAddrV4>().unwrap() => &[Token::Str("1.2.3.4:1234")], "1.2.3.4:1234".parse::<net::SocketAddrV4>().unwrap() => &[Token::Str("1.2.3.4:1234")],
"[::1]:1234".parse::<net::SocketAddrV6>().unwrap() => &[Token::Str("[::1]:1234")], "[::1]:1234".parse::<net::SocketAddrV6>().unwrap() => &[Token::Str("[::1]:1234")],
} }
test_path {
Path::new("/usr/local/lib") => &[
Token::BorrowedStr("/usr/local/lib"),
],
}
test_path_buf { test_path_buf {
PathBuf::from("/usr/local/lib") => &[ PathBuf::from("/usr/local/lib") => &[
Token::String("/usr/local/lib"), Token::String("/usr/local/lib"),
+28
View File
@@ -330,6 +330,34 @@ fn test_gen() {
struct EmptyArray { struct EmptyArray {
empty: [X; 0], empty: [X; 0],
} }
enum Or<A, B> {
A(A),
B(B),
}
#[derive(Serialize, Deserialize)]
#[serde(untagged, remote = "Or")]
enum OrDef<A, B> {
#[allow(dead_code)]
A(A),
#[allow(dead_code)]
B(B),
}
struct Str<'a>(&'a str);
#[derive(Serialize, Deserialize)]
#[serde(remote = "Str")]
struct StrDef<'a>(&'a str);
#[derive(Serialize, Deserialize)]
struct Remote<'a> {
#[serde(with = "OrDef")]
or: Or<u8, bool>,
#[serde(borrow, with = "StrDef")]
s: Str<'a>,
}
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
+53
View File
@@ -695,6 +695,59 @@ fn test_internally_tagged_enum() {
); );
} }
#[test]
fn test_internally_tagged_struct_variant_containing_unit_variant() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub enum Level {
Info,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "action")]
pub enum Message {
Log { level: Level },
}
assert_de_tokens(
&Message::Log { level: Level::Info },
&[
Token::Struct { name: "Message", len: 2 },
Token::Str("action"),
Token::Str("Log"),
Token::Str("level"),
Token::BorrowedStr("Info"),
Token::StructEnd,
],
);
}
#[test]
fn test_internally_tagged_borrow() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum Input<'a> {
Package { name: &'a str },
}
assert_tokens(
&Input::Package { name: "borrowed" },
&[
Token::Struct { name: "Input", len: 2 },
Token::BorrowedStr("type"),
Token::BorrowedStr("Package"),
Token::BorrowedStr("name"),
Token::BorrowedStr("borrowed"),
Token::StructEnd,
],
);
}
#[test] #[test]
fn test_adjacently_tagged_enum() { fn test_adjacently_tagged_enum() {
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
+24 -2
View File
@@ -9,10 +9,10 @@
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
use std::collections::{BTreeMap, HashMap, HashSet}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::net; use std::net;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::time::Duration; use std::time::{Duration, UNIX_EPOCH};
use std::ffi::CString; use std::ffi::CString;
#[cfg(unix)] #[cfg(unix)]
@@ -170,6 +170,17 @@ declare_tests! {
Token::SeqEnd, Token::SeqEnd,
], ],
} }
test_btreeset {
BTreeSet::<isize>::new() => &[
Token::Seq { len: Some(0) },
Token::SeqEnd,
],
btreeset![1] => &[
Token::Seq { len: Some(1) },
Token::I32(1),
Token::SeqEnd,
],
}
test_hashset { test_hashset {
HashSet::<isize>::new() => &[ HashSet::<isize>::new() => &[
Token::Seq { len: Some(0) }, Token::Seq { len: Some(0) },
@@ -319,6 +330,17 @@ declare_tests! {
Token::StructEnd, Token::StructEnd,
], ],
} }
test_system_time {
UNIX_EPOCH + Duration::new(1, 2) => &[
Token::Struct { name: "SystemTime", len: 2 },
Token::Str("secs_since_epoch"),
Token::U64(1),
Token::Str("nanos_since_epoch"),
Token::U32(2),
Token::StructEnd,
],
}
test_range { test_range {
1u32..2u32 => &[ 1u32..2u32 => &[
Token::Struct { name: "Range", len: 2 }, Token::Struct { name: "Range", len: 2 },
-1
View File
@@ -46,7 +46,6 @@ else
channel build channel build
channel build --no-default-features channel build --no-default-features
channel build --no-default-features --features alloc channel build --no-default-features --features alloc
channel build --no-default-features --features collections
channel test --features 'rc unstable' channel test --features 'rc unstable'
cd "$DIR/test_suite/deps" cd "$DIR/test_suite/deps"
channel build channel build