Compare commits

...

34 Commits

Author SHA1 Message Date
David Tolnay 26098ed877 Release 1.0.11 2017-07-27 00:56:28 -07:00
David Tolnay 42ed62cf24 Merge pull request #1003 from serde-rs/newnonzero
NonZero constructor now returns Option
2017-07-27 00:54:23 -07:00
David Tolnay 9f0973aff7 NonZero constructor now returns Option 2017-07-27 00:35:56 -07:00
David Tolnay ccec002bf3 Merge pull request #1001 from serde-rs/remotevis
Inherit the visibility of remote struct definition
2017-07-27 00:29:57 -07:00
David Tolnay f36a1e0895 Inherit the visibility of remote struct definition 2017-07-25 23:52:06 -07:00
David Tolnay e6487cf6fa Merge pull request #995 from serde-rs/nobin
Workaround for "no bin target named serde_derive_tests_no_std"
2017-07-21 00:17:25 -07:00
David Tolnay 4f2e8d5dbb Workaround for "no bin target named serde_derive_tests_no_std" 2017-07-21 00:05:30 -07:00
David Tolnay 1c2a4bff1c Merge pull request #991 from Marwes/test_systemtime
Fix SystemTime serialization test on Windows
2017-07-16 06:10:43 -07:00
Markus Westerlind 85bccf42b6 Fix SystemTime serialization test on Windows
Windows's `SystemTime` do not have nanosecond resolution which caused the test duration to be truncated https://github.com/rust-lang/rust/blob/b1363a73ede57ae595f3a1be2bb75d308ba4f7f6/src/libstd/sys/windows/time.rs#L177
2017-07-16 12:16:07 +02:00
David Tolnay 959fee024f Merge pull request #986 from Marwes/simplify_seed
refactor: Implement Deserialize of wrapper types with a macro
2017-07-12 20:36:48 -07:00
Markus Westerlind 8ede8c8e2a refactor: Implement Deserialize of wrapper types with a macro 2017-07-13 00:02:29 +02:00
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
27 changed files with 471 additions and 213 deletions
-1
View File
@@ -5,5 +5,4 @@ members = [
"serde_derive_internals",
"serde_test",
"test_suite",
"test_suite/no_std",
]
+4 -11
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.6" # remember to update html_root_url
version = "1.0.11" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
@@ -48,22 +48,15 @@ std = []
# https://github.com/serde-rs/serde/issues/812
unstable = []
# Provide impls for types that require memory allocation like Box<T> and Rc<T>.
# This is a subset of std but may be enabled without depending on all of std.
# Provide impls for types in the Rust core allocation and collections library
# 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:
#
# https://doc.rust-lang.org/alloc/
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
# 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.
+166 -116
View File
@@ -11,12 +11,12 @@ use lib::*;
use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess,
Visitor};
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
use de::MapAccess;
use de::from_primitive::FromPrimitive;
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
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;
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Visitor<'de> for StringVisitor {
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 {
fn deserialize<D>(deserializer: D) -> Result<String, D::Error>
where
@@ -400,16 +400,22 @@ impl<'de> Deserialize<'de> for CString {
}
}
#[cfg(all(feature = "std", feature = "unstable"))]
impl<'de> Deserialize<'de> for Box<CStr> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
CString::deserialize(deserializer).map(CString::into_boxed_c_str)
macro_rules! forwarded_impl {
(( $($id: ident),* ), $ty: ty, $func: expr) => {
impl<'de $(, $id : Deserialize<'de>,)*> Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map($func)
}
}
}
}
#[cfg(all(feature = "std", feature = "unstable"))]
forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str);
////////////////////////////////////////////////////////////////////////////////
struct OptionVisitor<T> {
@@ -497,7 +503,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 {
(
$ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
@@ -552,7 +558,7 @@ macro_rules! seq_impl {
}
}
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
BinaryHeap<T: Ord>,
seq,
@@ -560,7 +566,7 @@ seq_impl!(
BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
BinaryHeap::push);
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
BTreeSet<T: Eq + Ord>,
seq,
@@ -568,7 +574,7 @@ seq_impl!(
BTreeSet::new(),
BTreeSet::insert);
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
LinkedList<T>,
seq,
@@ -584,7 +590,7 @@ seq_impl!(
HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
HashSet::insert);
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
Vec<T>,
seq,
@@ -592,7 +598,7 @@ seq_impl!(
Vec::with_capacity(size_hint::cautious(seq.size_hint())),
Vec::push);
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
VecDeque<T>,
seq,
@@ -790,7 +796,7 @@ tuple_impls! {
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! map_impl {
(
$ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
@@ -846,7 +852,7 @@ macro_rules! map_impl {
}
}
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
map_impl!(
BTreeMap<K: Ord, V>,
map,
@@ -1098,68 +1104,21 @@ impl<'de> Deserialize<'de> for OsString {
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, T> Deserialize<'de> for Box<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Box<T>, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(Box::new)
}
}
forwarded_impl!((T), Box<T>, Box::new);
#[cfg(any(feature = "std", feature = "collections"))]
impl<'de, T> Deserialize<'de> for Box<[T]>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Box<[T]>, D::Error>
where
D: Deserializer<'de>,
{
Vec::<T>::deserialize(deserializer).map(Vec::into_boxed_slice)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice);
#[cfg(any(feature = "std", feature = "collections"))]
impl<'de> Deserialize<'de> for Box<str> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
String::deserialize(deserializer).map(String::into_boxed_str)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
forwarded_impl!((), Box<str>, String::into_boxed_str);
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
impl<'de, T> Deserialize<'de> for Arc<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Arc<T>, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(Arc::new)
}
}
forwarded_impl!((T), Arc<T>, Arc::new);
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
impl<'de, T> Deserialize<'de> for Rc<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Rc<T>, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(Rc::new)
}
}
forwarded_impl!((T), Rc<T>, Rc::new);
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
where
T: ToOwned,
@@ -1188,43 +1147,13 @@ where
}
}
impl<'de, T> Deserialize<'de> for RefCell<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<RefCell<T>, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(RefCell::new)
}
}
forwarded_impl!((T), RefCell<T>, RefCell::new);
#[cfg(feature = "std")]
impl<'de, T> Deserialize<'de> for Mutex<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Mutex<T>, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(Mutex::new)
}
}
forwarded_impl!((T), Mutex<T>, Mutex::new);
#[cfg(feature = "std")]
impl<'de, T> Deserialize<'de> for RwLock<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<RwLock<T>, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(RwLock::new)
}
}
forwarded_impl!((T), RwLock<T>, RwLock::new);
////////////////////////////////////////////////////////////////////////////////
@@ -1364,6 +1293,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:
//
// #[derive(Deserialize)]
@@ -1518,14 +1573,9 @@ where
D: Deserializer<'de>,
{
let value = try!(Deserialize::deserialize(deserializer));
unsafe {
let ptr = &value as *const T as *const u8;
if slice::from_raw_parts(ptr, mem::size_of::<T>()).iter().all(|&b| b == 0) {
return Err(Error::custom("expected a non-zero value"));
}
// Waiting for a safe way to construct NonZero<T>:
// https://github.com/rust-lang/rust/issues/27730#issuecomment-269726075
Ok(NonZero::new(value))
match NonZero::new(value) {
Some(nonzero) => Ok(nonzero),
None => Err(Error::custom("expected a non-zero value")),
}
}
}
+3 -2
View File
@@ -94,6 +94,7 @@
//! - OsString
//! - **Miscellaneous standard library types**:
//! - Duration
//! - SystemTime
//! - Path
//! - PathBuf
//! - Range\<T\>
@@ -1262,7 +1263,7 @@ pub trait Visitor<'de>: Sized {
/// The default implementation forwards to `visit_str` and then drops the
/// `String`.
#[inline]
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
@@ -1321,7 +1322,7 @@ pub trait Visitor<'de>: Sized {
///
/// The default implementation forwards to `visit_bytes` and then drops the
/// `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>
where
E: Error,
+126 -17
View File
@@ -51,13 +51,13 @@ pub struct Error {
err: ErrorImpl,
}
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
type ErrorImpl = Box<str>;
#[cfg(not(any(feature = "std", feature = "collections")))]
#[cfg(not(any(feature = "std", feature = "alloc")))]
type ErrorImpl = ();
impl de::Error for Error {
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
fn custom<T>(msg: T) -> Self
where
T: Display,
@@ -65,7 +65,7 @@ impl de::Error for Error {
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
where
T: Display,
@@ -85,12 +85,12 @@ impl ser::Error 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> {
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> {
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`.
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Clone, Debug)]
pub struct StringDeserializer<E> {
value: String,
marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, E> IntoDeserializer<'de, E> for String
where
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>
where
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>
where
E: de::Error,
@@ -432,14 +501,14 @@ where
////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `Cow<str>`.
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Clone, Debug)]
pub struct CowStrDeserializer<'a, E> {
value: Cow<'a, str>,
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>
where
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>
where
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>
where
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.
#[derive(Clone, Debug)]
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>
where
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>
where
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>
where
K: IntoDeserializer<'de, E> + Eq + Ord,
+2 -2
View File
@@ -19,7 +19,7 @@ pub use self::string::from_utf8_lossy;
mod string {
use lib::*;
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
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
// 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 {
// Three unicode replacement characters if it fails. They look like a
// 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.
#![doc(html_root_url = "https://docs.rs/serde/1.0.6")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.11")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
@@ -91,7 +91,6 @@
#![cfg_attr(feature = "unstable", feature(nonzero, specialization))]
#![cfg_attr(all(feature = "std", feature = "unstable"), feature(into_boxed_c_str))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "collections", feature(collections))]
// Whitelisted clippy lints.
#![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))]
@@ -104,18 +103,15 @@
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "collections")]
extern crate collections;
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(all(feature = "unstable", feature = "std"))]
extern crate core;
/// A facade around all the types we need from the `std`, `core`, `alloc`, and
/// `collections` crates. This avoids elaborate import wrangling having to
/// happen in every module.
/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
mod core {
#[cfg(feature = "std")]
@@ -140,18 +136,18 @@ mod lib {
#[cfg(feature = "std")]
pub use std::borrow::{Cow, ToOwned};
#[cfg(all(feature = "collections", not(feature = "std")))]
pub use collections::borrow::{Cow, ToOwned};
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::borrow::{Cow, ToOwned};
#[cfg(feature = "std")]
pub use std::string::String;
#[cfg(all(feature = "collections", not(feature = "std")))]
pub use collections::string::{String, ToString};
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::string::{String, ToString};
#[cfg(feature = "std")]
pub use std::vec::Vec;
#[cfg(all(feature = "collections", not(feature = "std")))]
pub use collections::vec::Vec;
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::vec::Vec;
#[cfg(feature = "std")]
pub use std::boxed::Box;
@@ -170,8 +166,8 @@ mod lib {
#[cfg(feature = "std")]
pub use std::collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
#[cfg(all(feature = "collections", not(feature = "std")))]
pub use collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
#[cfg(feature = "std")]
pub use std::{error, net};
@@ -187,7 +183,7 @@ mod lib {
#[cfg(feature = "std")]
pub use std::path::{Path, PathBuf};
#[cfg(feature = "std")]
pub use std::time::Duration;
pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
#[cfg(feature = "std")]
pub use std::sync::{Mutex, RwLock};
+5 -5
View File
@@ -10,10 +10,10 @@ use lib::*;
use de::{Deserialize, Deserializer, IntoDeserializer, Error, Visitor};
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
use de::Unexpected;
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::content::{Content, ContentRefDeserializer, ContentDeserializer,
TaggedContentVisitor, TagOrContentField, TagOrContentFieldVisitor,
TagContentOtherField, TagContentOtherFieldVisitor,
@@ -59,7 +59,7 @@ where
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>
where
D: Deserializer<'de>,
@@ -128,7 +128,7 @@ where
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>
where
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 {
// This module is private and nothing here should be used outside of
// generated code.
+13 -13
View File
@@ -10,7 +10,7 @@ use lib::*;
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};
/// Used to check that serde(getter) attributes return the expected type.
@@ -64,7 +64,7 @@ enum Unsupported {
Sequence,
Tuple,
TupleStruct,
#[cfg(not(any(feature = "std", feature = "collections")))]
#[cfg(not(any(feature = "std", feature = "alloc")))]
Enum,
}
@@ -83,7 +83,7 @@ impl Display for Unsupported {
Unsupported::Sequence => formatter.write_str("a sequence"),
Unsupported::Tuple => formatter.write_str("a tuple"),
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"),
}
}
@@ -117,14 +117,14 @@ where
type SerializeMap = S::SerializeMap;
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>;
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
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>;
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
type SerializeStructVariant = SerializeStructVariantAsMapValue<S::SerializeMap>;
fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
@@ -257,7 +257,7 @@ where
Err(self.bad_type(Unsupported::TupleStruct))
}
#[cfg(not(any(feature = "std", feature = "collections")))]
#[cfg(not(any(feature = "std", feature = "alloc")))]
fn serialize_tuple_variant(
self,
_: &'static str,
@@ -270,7 +270,7 @@ where
Err(self.bad_type(Unsupported::Enum))
}
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
fn serialize_tuple_variant(
self,
_: &'static str,
@@ -300,7 +300,7 @@ where
Ok(state)
}
#[cfg(not(any(feature = "std", feature = "collections")))]
#[cfg(not(any(feature = "std", feature = "alloc")))]
fn serialize_struct_variant(
self,
_: &'static str,
@@ -313,7 +313,7 @@ where
Err(self.bad_type(Unsupported::Enum))
}
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
fn serialize_struct_variant(
self,
_: &'static str,
@@ -327,7 +327,7 @@ where
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>
where
T: Display,
@@ -363,7 +363,7 @@ impl Display for Error {
}
}
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
mod content {
use lib::*;
+27 -8
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 {
#[inline]
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 {
($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => {
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>);
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(BTreeSet<T: Ord>);
#[cfg(feature = "std")]
seq_impl!(HashSet<T: Eq + Hash, H: BuildHasher>);
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(LinkedList<T>);
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(Vec<T>);
#[cfg(any(feature = "std", feature = "collections"))]
#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(VecDeque<T>);
////////////////////////////////////////////////////////////////////////////////
@@ -290,6 +291,7 @@ tuple_impls! {
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! map_impl {
($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => {
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>);
#[cfg(feature = "std")]
@@ -343,7 +345,7 @@ deref_impl!(<T> Serialize for Rc<T> where T: Serialize);
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
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);
////////////////////////////////////////////////////////////////////////////////
@@ -455,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
/// statically known to never have more than a constant `MAX_LEN` bytes.
///
+3 -2
View File
@@ -89,6 +89,7 @@
//! - OsString
//! - **Miscellaneous standard library types**:
//! - Duration
//! - SystemTime
//! - Path
//! - PathBuf
//! - Range\<T\>
@@ -1321,7 +1322,7 @@ pub trait Serializer: Sized {
///
/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
/// [`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>
where
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>
where
T: Display;
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.6" # remember to update html_root_url
version = "1.0.11" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -20,5 +20,5 @@ proc-macro = true
[dependencies]
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"] }
+4 -5
View File
@@ -23,15 +23,15 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
let ident = &cont.ident;
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 body = Stmts(deserialize_body(&cont, &params));
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();
let vis = &input.vis;
quote! {
impl #impl_generics #ident #ty_generics #where_clause {
fn deserialize<#de_lifetime, __D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
impl #de_impl_generics #ident #ty_generics #where_clause {
#vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
where __D: _serde::Deserializer<'de>
{
#body
@@ -39,7 +39,6 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
}
}
} else {
let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params);
quote! {
#[automatically_derived]
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
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.6")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.11")]
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
#![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))]
+2 -1
View File
@@ -29,9 +29,10 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
let body = Stmts(serialize_body(&cont, &params));
let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis;
quote! {
impl #impl_generics #ident #ty_generics #where_clause {
fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer
{
#body
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
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>"]
license = "MIT/Apache-2.0"
description = "AST representation used by Serde derive macros. Unstable."
+1 -1
View File
@@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed
// 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;
#[macro_use]
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_test"
version = "1.0.6" # remember to update html_root_url
version = "1.0.11" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
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.6")]
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.11")]
#[macro_use]
extern crate serde;
+3
View File
@@ -4,5 +4,8 @@ version = "0.0.0"
publish = false
[dependencies]
libc = { version = "0.2", default-features = false }
serde = { path = "../../serde", default-features = false }
serde_derive = { path = "../../serde_derive" }
[workspace]
+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]
extern crate libc;
@@ -18,7 +18,9 @@ mod remote {
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::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() {}
+18 -1
View File
@@ -14,7 +14,7 @@ extern crate serde_derive;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::net;
use std::path::{Path, PathBuf};
use std::time::Duration;
use std::time::{Duration, UNIX_EPOCH};
use std::default::Default;
use std::ffi::{CString, OsString};
@@ -682,6 +682,23 @@ declare_tests! {
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 {
1u32..2u32 => &[
Token::Struct { name: "Range", len: 2 },
+43
View File
@@ -330,6 +330,49 @@ fn test_gen() {
struct EmptyArray {
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>,
}
mod vis {
pub struct S;
#[derive(Serialize, Deserialize)]
#[serde(remote = "S")]
pub struct SDef;
}
// This would not work if SDef::serialize / deserialize are private.
#[derive(Serialize, Deserialize)]
struct RemoteVisibility {
#[serde(with = "vis::SDef")]
s: vis::S,
}
}
//////////////////////////////////////////////////////////////////////////
+24 -2
View File
@@ -9,10 +9,10 @@
#[macro_use]
extern crate serde_derive;
use std::collections::{BTreeMap, HashMap, HashSet};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::net;
use std::path::{Path, PathBuf};
use std::time::Duration;
use std::time::{Duration, UNIX_EPOCH};
use std::ffi::CString;
#[cfg(unix)]
@@ -170,6 +170,17 @@ declare_tests! {
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 {
HashSet::<isize>::new() => &[
Token::Seq { len: Some(0) },
@@ -319,6 +330,17 @@ declare_tests! {
Token::StructEnd,
],
}
test_system_time {
UNIX_EPOCH + Duration::new(1, 200) => &[
Token::Struct { name: "SystemTime", len: 2 },
Token::Str("secs_since_epoch"),
Token::U64(1),
Token::Str("nanos_since_epoch"),
Token::U32(200),
Token::StructEnd,
],
}
test_range {
1u32..2u32 => &[
Token::Struct { name: "Range", len: 2 },
+4 -1
View File
@@ -41,12 +41,12 @@ if [ -n "${CLIPPY}" ]; then
cargo clippy -- -Dclippy
else
CHANNEL=nightly
cd "$DIR"
cargo clean
cd "$DIR/serde"
channel build
channel build --no-default-features
channel build --no-default-features --features alloc
channel build --no-default-features --features collections
channel test --features 'rc unstable'
cd "$DIR/test_suite/deps"
channel build
@@ -56,6 +56,7 @@ else
channel build
CHANNEL=beta
cd "$DIR"
cargo clean
cd "$DIR/serde"
channel build --features rc
@@ -63,6 +64,7 @@ else
channel test
CHANNEL=stable
cd "$DIR"
cargo clean
cd "$DIR/serde"
channel build --features rc
@@ -72,6 +74,7 @@ else
channel test
CHANNEL=1.13.0
cd "$DIR"
cargo clean
cd "$DIR/serde"
channel build --features rc