Compare commits

...

46 Commits

Author SHA1 Message Date
David Tolnay 7b50388fef Release 1.0.78 2018-09-08 17:10:41 -07:00
David Tolnay e704990322 Merge pull request #1380 from dtolnay/f
Fix panic deserializing flattened any after flattened struct
2018-09-08 17:10:01 -07:00
David Tolnay 2a4b8ce42d Fix panic deserializing flattened any after flattened struct 2018-09-08 16:55:34 -07:00
David Tolnay 108cca687c Release 1.0.77 2018-09-06 21:36:27 -07:00
David Tolnay bca8c115c7 Merge pull request #1372 from dtolnay/syn
Update to syn 0.15
2018-09-06 21:34:14 -07:00
David Tolnay b49bd52a53 Use parse_macro_input to report parse errors 2018-09-06 21:16:12 -07:00
David Tolnay 27bd640812 Update to syn 0.15 2018-09-06 21:16:08 -07:00
David Tolnay 8d5cda8464 Merge pull request #1376 from dreid/fix-internally-tagged-enum-deserialization-with-unknown-fields
Fix internally tagged enum deserialization with unknown fields
2018-09-06 21:10:41 -07:00
David Reid 389b9b5fe7 Add a test for an internally tagged unit enum flattened with a second internally tagged unit enum. 2018-09-06 14:55:10 -07:00
David Reid 27478b6f71 Internally tagged unit enum variants should ignore unknown fields. 2018-09-06 14:29:49 -07:00
David Tolnay 480f858fc3 Update panic_handler attribute name changed in nightly 2018-09-03 08:24:27 -07:00
David Tolnay 7d752c5a60 Merge pull request #1373 from dtolnay/emscripten
Add Emscripten build in Travis
2018-09-02 13:56:41 -07:00
David Tolnay 33b7841300 Skip asmjs 2018-09-02 13:21:36 -07:00
David Tolnay 2244b92eb0 Nvm install in .travis.yml
The one in travis.sh was failing:

    ./travis.sh: line 56: nvm: command not found
    The command "./travis.sh" exited with 127.
2018-09-02 12:45:12 -07:00
David Tolnay d0464fbff7 Add Emscripten build in Travis 2018-09-02 12:34:13 -07:00
David Tolnay 98eddf9b29 Update to syn 0.15-rc1 2018-09-01 23:03:59 -07:00
David Tolnay d23a40c1bb Format with rustfmt 0.99.2 2018-09-01 23:03:41 -07:00
David Tolnay 55cecace29 Release 1.0.76 2018-09-01 15:25:53 -07:00
David Tolnay 3da0deaa50 Merge pull request #1371 from hcpl/nonzero_u128
Add support for `NonZeroU128`
2018-09-01 15:25:10 -07:00
hcpl 585550a5be Add support for NonZeroU128 2018-09-02 00:34:56 +03:00
David Tolnay 5b7b8abf9f Move some compile-fail errors based on proc-macro2 update 2018-08-28 20:35:49 -07:00
David Tolnay 2aab0ce2f6 Release 1.0.75 2018-08-24 23:03:04 -04:00
David Tolnay a157c56d7d Merge pull request #1367 from Eh2406/master
update a deb for minimal-versions
2018-08-24 23:02:02 -04:00
Eh2406 6c45593ee4 update a deb for minimal-versions 2018-08-24 22:50:17 -04:00
David Tolnay 1175d54fb7 Stabilize raw_identifiers 2018-08-24 19:49:13 -04:00
David Tolnay cfdbbee845 Release 1.0.74 2018-08-23 18:29:16 -04:00
David Tolnay c1583bf2b8 Merge pull request #1365 from koute/master
Disable i128 integers on Emscripten targets
2018-08-23 18:28:51 -04:00
Jan Bujak 7385b50249 Disable i128 integers on Emscripten targets 2018-08-24 00:02:40 +02:00
David Tolnay db6aaf5110 Release 1.0.73 2018-08-22 21:47:15 -04:00
David Tolnay c4a4501d71 Merge pull request #1363 from dtolnay/raw
Trim the r# from raw identifiers in user-facing strings
2018-08-22 21:46:31 -04:00
David Tolnay a3ae14d090 Test raw identifiers 2018-08-22 21:09:37 -04:00
David Tolnay dc4bb0bf08 Trim the r# from raw identifiers in user-facing strings 2018-08-22 20:50:29 -04:00
David Tolnay c69a3e083f Merge pull request #1360 from Pratyush/master
Update travis.sh to also test `--no-default-features --features "rc alloc"`
2018-08-20 21:38:55 -04:00
Pratyush Mishra c790bd2a69 Update travis.sh 2018-08-20 18:30:43 -07:00
David Tolnay 60cbbacdb3 Release 1.0.72 2018-08-20 21:02:03 -04:00
David Tolnay befc7edc17 Merge pull request #1359 from Pratyush/master
Fix compilation under `rc` feature
2018-08-20 21:00:47 -04:00
Pratyush Mishra 3897ccb3f9 Fix compilation under rc feature 2018-08-20 14:35:48 -07:00
David Tolnay 11c5fd78ad Abbreviate and touch up some attribute parsing comments 2018-08-14 22:37:59 -07:00
David Tolnay cbfdba3826 Use rustfmt to wrap and format comments 2018-08-14 22:32:27 -07:00
David Tolnay 5985b7edaf Format with rustfmt 0.99.2 2018-08-14 19:59:20 -07:00
David Tolnay d28a0e66c8 Fix old reference to serde_codegen 2018-08-12 10:54:59 -07:00
David Tolnay 0ca4db1616 Move untagged borrow test case into codegen tests 2018-08-12 10:54:29 -07:00
David Tolnay 72b3438dfc Merge pull request #1338 from toidiu/ak-untagged-enum
test borrowing untagged enum
2018-08-12 10:49:15 -07:00
David Tolnay c7051ac748 Update links to a renamed manual chapter 2018-08-12 10:48:20 -07:00
David Tolnay a065db9838 Add AppVeyor badge to rest of crates 2018-08-07 00:15:12 -07:00
toidiu 3ca0597a7e test borrowing untagged enum 2018-07-12 17:12:27 -04:00
34 changed files with 453 additions and 192 deletions
+3
View File
@@ -18,5 +18,8 @@ matrix:
include:
- rust: nightly
env: CLIPPY=true
- rust: nightly
env: EMSCRIPTEN=true
script: nvm install 9 && ./travis.sh
script: ./travis.sh
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.71" # remember to update html_root_url
version = "1.0.78" # 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"
+7 -1
View File
@@ -11,6 +11,9 @@ fn main() {
None => return,
};
let target = env::var("TARGET").unwrap();
let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten";
// CString::into_boxed_c_str stabilized in Rust 1.20:
// https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str
if minor >= 20 {
@@ -32,7 +35,10 @@ fn main() {
// 128-bit integers stabilized in Rust 1.26:
// https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
if minor >= 26 {
//
// Disabled on Emscripten targets as Emscripten doesn't
// currently support integers larger than 64 bits.
if minor >= 26 && !emscripten {
println!("cargo:rustc-cfg=integer128");
}
+8 -2
View File
@@ -20,7 +20,9 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
/// use std::fmt;
/// use std::marker::PhantomData;
///
/// use serde::de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess, IgnoredAny};
/// use serde::de::{
/// self, Deserialize, DeserializeSeed, Deserializer, IgnoredAny, SeqAccess, Visitor,
/// };
///
/// /// A seed that can be used to deserialize only the `n`th element of a sequence
/// /// while efficiently discarding elements of any type before or after index `n`.
@@ -51,7 +53,11 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
/// type Value = T;
///
/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// write!(formatter, "a sequence in which we care about element {}", self.n)
/// write!(
/// formatter,
/// "a sequence in which we care about element {}",
/// self.n
/// )
/// }
///
/// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+33 -36
View File
@@ -1602,13 +1602,11 @@ forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice);
#[cfg(any(feature = "std", feature = "alloc"))]
forwarded_impl!((), Box<str>, String::into_boxed_str);
#[cfg(
all(
not(de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
)
)]
#[cfg(all(
not(de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -1620,13 +1618,11 @@ forwarded_impl! {
(T), Arc<T>, Arc::new
}
#[cfg(
all(
not(de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
)
)]
#[cfg(all(
not(de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -1693,13 +1689,11 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(
all(
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
)
)]
#[cfg(all(
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
))]
macro_rules! box_forwarded_impl {
(
$(#[doc = $doc:tt])*
@@ -1720,13 +1714,11 @@ macro_rules! box_forwarded_impl {
};
}
#[cfg(
all(
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
)
)]
#[cfg(all(
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
))]
box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -1738,13 +1730,11 @@ box_forwarded_impl! {
Rc
}
#[cfg(
all(
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
)
)]
#[cfg(all(
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
))]
box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -2252,10 +2242,17 @@ nonzero_integers! {
NonZeroU16,
NonZeroU32,
NonZeroU64,
// FIXME: https://github.com/serde-rs/serde/issues/1136 NonZeroU128,
NonZeroUsize,
}
// Currently 128-bit integers do not work on Emscripten targets so we need an
// additional `#[cfg]`
serde_if_integer128! {
nonzero_integers! {
NonZeroU128,
}
}
////////////////////////////////////////////////////////////////////////////////
impl<'de, T, E> Deserialize<'de> for Result<T, E>
+29 -27
View File
@@ -24,8 +24,7 @@
//!
//! Additionally, Serde provides a procedural macro called [`serde_derive`] to
//! automatically generate [`Deserialize`] implementations for structs and enums
//! in your program. See the [codegen section of the manual] for how to use
//! this.
//! in your program. See the [derive section of the manual] for how to use this.
//!
//! In rare cases it may be necessary to implement [`Deserialize`] manually for
//! some type in your program. See the [Implementing `Deserialize`] section of
@@ -117,7 +116,7 @@
//! [`serde_derive`]: https://crates.io/crates/serde_derive
//! [`serde_json`]: https://github.com/serde-rs/json
//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml
//! [codegen section of the manual]: https://serde.rs/codegen.html
//! [derive section of the manual]: https://serde.rs/derive.html
//! [data formats]: https://serde.rs/#data-formats
use lib::*;
@@ -498,7 +497,7 @@ impl<'a> Display for Expected + 'a {
///
/// Additionally, Serde provides a procedural macro called `serde_derive` to
/// automatically generate `Deserialize` implementations for structs and enums
/// in your program. See the [codegen section of the manual][codegen] for how to
/// in your program. See the [derive section of the manual][derive] for how to
/// use this.
///
/// In rare cases it may be necessary to implement `Deserialize` manually for
@@ -511,7 +510,7 @@ impl<'a> Display for Expected + 'a {
/// provides an implementation of `Deserialize` for it.
///
/// [de]: https://docs.serde.rs/serde/de/index.html
/// [codegen]: https://serde.rs/codegen.html
/// [derive]: https://serde.rs/derive.html
/// [impl-deserialize]: https://serde.rs/impl-deserialize.html
///
/// # Lifetime
@@ -660,7 +659,7 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
/// use std::fmt;
/// use std::marker::PhantomData;
///
/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess};
/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor};
///
/// // A DeserializeSeed implementation that uses stateful deserialization to
/// // append array elements onto the end of an existing vector. The preexisting
@@ -807,16 +806,16 @@ where
/// - When serializing, all strings are handled equally. When deserializing,
/// there are three flavors of strings: transient, owned, and borrowed.
/// - **byte array** - \[u8\]
/// - Similar to strings, during deserialization byte arrays can be transient,
/// owned, or borrowed.
/// - Similar to strings, during deserialization byte arrays can be
/// transient, owned, or borrowed.
/// - **option**
/// - Either none or some value.
/// - **unit**
/// - The type of `()` in Rust. It represents an anonymous value containing no
/// data.
/// - The type of `()` in Rust. It represents an anonymous value containing
/// no data.
/// - **unit_struct**
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named value
/// containing no data.
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named
/// value containing no data.
/// - **unit_variant**
/// - For example the `E::A` and `E::B` in `enum E { A, B }`.
/// - **newtype_struct**
@@ -824,14 +823,15 @@ where
/// - **newtype_variant**
/// - For example the `E::N` in `enum E { N(u8) }`.
/// - **seq**
/// - A variably sized heterogeneous sequence of values, for example `Vec<T>` or
/// `HashSet<T>`. When serializing, the length may or may not be known before
/// iterating through all the data. When deserializing, the length is determined
/// by looking at the serialized data.
/// - A variably sized heterogeneous sequence of values, for example `Vec<T>`
/// or `HashSet<T>`. When serializing, the length may or may not be known
/// before iterating through all the data. When deserializing, the length
/// is determined by looking at the serialized data.
/// - **tuple**
/// - A statically sized heterogeneous sequence of values for which the length
/// will be known at deserialization time without looking at the serialized
/// data, for example `(u8,)` or `(String, u64, Vec<T>)` or `[u64; 10]`.
/// - A statically sized heterogeneous sequence of values for which the
/// length will be known at deserialization time without looking at the
/// serialized data, for example `(u8,)` or `(String, u64, Vec<T>)` or
/// `[u64; 10]`.
/// - **tuple_struct**
/// - A named tuple, for example `struct Rgb(u8, u8, u8)`.
/// - **tuple_variant**
@@ -839,9 +839,9 @@ where
/// - **map**
/// - A heterogeneous key-value pairing, for example `BTreeMap<K, V>`.
/// - **struct**
/// - A heterogeneous key-value pairing in which the keys are strings and will be
/// known at deserialization time without looking at the serialized data, for
/// example `struct S { r: u8, g: u8, b: u8 }`.
/// - A heterogeneous key-value pairing in which the keys are strings and
/// will be known at deserialization time without looking at the serialized
/// data, for example `struct S { r: u8, g: u8, b: u8 }`.
/// - **struct_variant**
/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
///
@@ -856,7 +856,8 @@ where
/// type it sees in the input. JSON uses this approach when deserializing
/// `serde_json::Value` which is an enum that can represent any JSON
/// document. Without knowing what is in a JSON document, we can deserialize
/// it to `serde_json::Value` by going through `Deserializer::deserialize_any`.
/// it to `serde_json::Value` by going through
/// `Deserializer::deserialize_any`.
///
/// 2. The various `deserialize_*` methods. Non-self-describing formats like
/// Bincode need to be told what is in the input in order to deserialize it.
@@ -866,10 +867,11 @@ where
/// `Deserializer::deserialize_any`.
///
/// When implementing `Deserialize`, you should avoid relying on
/// `Deserializer::deserialize_any` unless you need to be told by the Deserializer
/// what type is in the input. Know that relying on `Deserializer::deserialize_any`
/// means your data type will be able to deserialize from self-describing
/// formats only, ruling out Bincode and many others.
/// `Deserializer::deserialize_any` unless you need to be told by the
/// Deserializer what type is in the input. Know that relying on
/// `Deserializer::deserialize_any` means your data type will be able to
/// deserialize from self-describing formats only, ruling out Bincode and many
/// others.
///
/// [Serde data model]: https://serde.rs/data-model.html
///
+2 -2
View File
@@ -82,7 +82,7 @@
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.71")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.78")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
@@ -196,7 +196,7 @@ mod lib {
pub use std::rc::{Rc, Weak as RcWeak};
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
pub use alloc::arc::{Arc, Weak as ArcWeak};
pub use alloc::sync::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "rc", feature = "std"))]
pub use std::sync::{Arc, Weak as ArcWeak};
+14 -14
View File
@@ -231,8 +231,8 @@ mod content {
use super::size_hint;
use de::{
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess,
SeqAccess, Unexpected, Visitor,
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
MapAccess, SeqAccess, Unexpected, Visitor,
};
/// Used from generated code to buffer the contents of the Deserializer when
@@ -832,8 +832,8 @@ mod content {
}
impl<'de, T> TaggedContentVisitor<'de, T> {
/// Visitor for the content of an internally tagged enum with the given tag
/// name.
/// Visitor for the content of an internally tagged enum with the given
/// tag name.
pub fn new(name: &'static str) -> Self {
TaggedContentVisitor {
tag_name: name,
@@ -1075,8 +1075,8 @@ mod content {
Ok(value)
}
/// Used when deserializing an internally tagged enum because the content will
/// be used exactly once.
/// Used when deserializing an internally tagged enum because the content
/// will be used exactly once.
impl<'de, E> Deserializer<'de> for ContentDeserializer<'de, E>
where
E: de::Error,
@@ -1790,8 +1790,8 @@ mod content {
Ok(value)
}
/// Used when deserializing an untagged enum because the content may need to be
/// used more than once.
/// Used when deserializing an untagged enum because the content may need
/// to be used more than once.
impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2470,10 +2470,11 @@ mod content {
Ok(())
}
fn visit_map<M>(self, _: M) -> Result<(), M::Error>
fn visit_map<M>(self, mut access: M) -> Result<(), M::Error>
where
M: MapAccess<'de>,
{
while let Some(_) = try!(access.next_entry::<IgnoredAny, IgnoredAny>()) {}
Ok(())
}
}
@@ -2915,18 +2916,17 @@ where
where
T: DeserializeSeed<'de>,
{
match self.iter.next() {
Some(item) => {
while let Some(item) = self.iter.next() {
if let Some((ref key, ref content)) = *item {
// Do not take(), instead borrow this entry. The internally tagged
// enum does its own buffering so we can't tell whether this entry
// is going to be consumed. Borrowing here leaves the entry
// available for later flattened fields.
let (ref key, ref content) = *item.as_ref().unwrap();
self.pending = Some(content);
seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
}
None => Ok(None),
}
Ok(None)
}
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
+8 -1
View File
@@ -469,10 +469,17 @@ nonzero_integers! {
NonZeroU16,
NonZeroU32,
NonZeroU64,
// FIXME: https://github.com/serde-rs/serde/issues/1136 NonZeroU128,
NonZeroUsize,
}
// Currently 128-bit integers do not work on Emscripten targets so we need an
// additional `#[cfg]`
serde_if_integer128! {
nonzero_integers! {
NonZeroU128,
}
}
impl<T> Serialize for Cell<T>
where
T: Serialize + Copy,
+44 -36
View File
@@ -24,8 +24,7 @@
//!
//! Additionally, Serde provides a procedural macro called [`serde_derive`] to
//! automatically generate [`Serialize`] implementations for structs and enums
//! in your program. See the [codegen section of the manual] for how to use
//! this.
//! in your program. See the [derive section of the manual] for how to use this.
//!
//! In rare cases it may be necessary to implement [`Serialize`] manually for
//! some type in your program. See the [Implementing `Serialize`] section of the
@@ -112,7 +111,7 @@
//! [`serde_derive`]: https://crates.io/crates/serde_derive
//! [`serde_json`]: https://github.com/serde-rs/json
//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml
//! [codegen section of the manual]: https://serde.rs/codegen.html
//! [derive section of the manual]: https://serde.rs/derive.html
//! [data formats]: https://serde.rs/#data-formats
use lib::*;
@@ -196,7 +195,7 @@ declare_error_trait!(Error: Sized + Debug + Display);
///
/// Additionally, Serde provides a procedural macro called [`serde_derive`] to
/// automatically generate `Serialize` implementations for structs and enums in
/// your program. See the [codegen section of the manual] for how to use this.
/// your program. See the [derive section of the manual] for how to use this.
///
/// In rare cases it may be necessary to implement `Serialize` manually for some
/// type in your program. See the [Implementing `Serialize`] section of the
@@ -211,7 +210,7 @@ declare_error_trait!(Error: Sized + Debug + Display);
/// [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
/// [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
/// [`serde_derive`]: https://crates.io/crates/serde_derive
/// [codegen section of the manual]: https://serde.rs/codegen.html
/// [derive section of the manual]: https://serde.rs/derive.html
/// [ser]: https://docs.serde.rs/serde/ser/index.html
pub trait Serialize {
/// Serialize this value into the given Serde serializer.
@@ -220,7 +219,7 @@ pub trait Serialize {
/// information about how to implement this method.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStruct};
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Person {
/// name: String,
@@ -274,16 +273,16 @@ pub trait Serialize {
/// - When serializing, all strings are handled equally. When deserializing,
/// there are three flavors of strings: transient, owned, and borrowed.
/// - **byte array** - \[u8\]
/// - Similar to strings, during deserialization byte arrays can be transient,
/// owned, or borrowed.
/// - Similar to strings, during deserialization byte arrays can be
/// transient, owned, or borrowed.
/// - **option**
/// - Either none or some value.
/// - **unit**
/// - The type of `()` in Rust. It represents an anonymous value containing no
/// data.
/// - The type of `()` in Rust. It represents an anonymous value containing
/// no data.
/// - **unit_struct**
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named value
/// containing no data.
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named
/// value containing no data.
/// - **unit_variant**
/// - For example the `E::A` and `E::B` in `enum E { A, B }`.
/// - **newtype_struct**
@@ -291,14 +290,15 @@ pub trait Serialize {
/// - **newtype_variant**
/// - For example the `E::N` in `enum E { N(u8) }`.
/// - **seq**
/// - A variably sized heterogeneous sequence of values, for example `Vec<T>` or
/// `HashSet<T>`. When serializing, the length may or may not be known before
/// iterating through all the data. When deserializing, the length is determined
/// by looking at the serialized data.
/// - A variably sized heterogeneous sequence of values, for example
/// `Vec<T>` or `HashSet<T>`. When serializing, the length may or may not
/// be known before iterating through all the data. When deserializing,
/// the length is determined by looking at the serialized data.
/// - **tuple**
/// - A statically sized heterogeneous sequence of values for which the length
/// will be known at deserialization time without looking at the serialized
/// data, for example `(u8,)` or `(String, u64, Vec<T>)` or `[u64; 10]`.
/// - A statically sized heterogeneous sequence of values for which the
/// length will be known at deserialization time without looking at the
/// serialized data, for example `(u8,)` or `(String, u64, Vec<T>)` or
/// `[u64; 10]`.
/// - **tuple_struct**
/// - A named tuple, for example `struct Rgb(u8, u8, u8)`.
/// - **tuple_variant**
@@ -306,9 +306,9 @@ pub trait Serialize {
/// - **map**
/// - A heterogeneous key-value pairing, for example `BTreeMap<K, V>`.
/// - **struct**
/// - A heterogeneous key-value pairing in which the keys are strings and will be
/// known at deserialization time without looking at the serialized data, for
/// example `struct S { r: u8, g: u8, b: u8 }`.
/// - A heterogeneous key-value pairing in which the keys are strings and
/// will be known at deserialization time without looking at the
/// serialized data, for example `struct S { r: u8, g: u8, b: u8 }`.
/// - **struct_variant**
/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
///
@@ -1111,7 +1111,7 @@ pub trait Serializer: Sized {
/// ```
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTuple};
/// use serde::ser::{Serialize, SerializeTuple, Serializer};
///
/// const VRAM_SIZE: usize = 386;
/// struct Vram([u16; VRAM_SIZE]);
@@ -1139,7 +1139,7 @@ pub trait Serializer: Sized {
/// of data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleStruct};
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
///
/// struct Rgb(u8, u8, u8);
///
@@ -1171,7 +1171,7 @@ pub trait Serializer: Sized {
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleVariant};
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
///
/// enum E {
/// T(u8, u8),
@@ -1265,7 +1265,7 @@ pub trait Serializer: Sized {
/// data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStruct};
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Rgb {
/// r: u8,
@@ -1301,10 +1301,10 @@ pub trait Serializer: Sized {
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStructVariant};
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
///
/// enum E {
/// S { r: u8, g: u8, b: u8 }
/// S { r: u8, g: u8, b: u8 },
/// }
///
/// impl Serialize for E {
@@ -1313,7 +1313,11 @@ pub trait Serializer: Sized {
/// S: Serializer,
/// {
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// E::S {
/// ref r,
/// ref g,
/// ref b,
/// } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
@@ -1376,8 +1380,8 @@ pub trait Serializer: Sized {
/// method.
///
/// ```rust
/// use std::collections::BTreeSet;
/// use serde::{Serialize, Serializer};
/// use std::collections::BTreeSet;
///
/// struct MapToUnit {
/// keys: BTreeSet<i32>,
@@ -1705,7 +1709,7 @@ pub trait SerializeTuple {
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleStruct};
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
///
/// struct Rgb(u8, u8, u8);
///
@@ -1750,7 +1754,7 @@ pub trait SerializeTupleStruct {
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleVariant};
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
///
/// enum E {
/// T(u8, u8),
@@ -1919,7 +1923,7 @@ pub trait SerializeMap {
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStruct};
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Rgb {
/// r: u8,
@@ -1979,10 +1983,10 @@ pub trait SerializeStruct {
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStructVariant};
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
///
/// enum E {
/// S { r: u8, g: u8, b: u8 }
/// S { r: u8, g: u8, b: u8 },
/// }
///
/// impl Serialize for E {
@@ -1991,7 +1995,11 @@ pub trait SerializeStruct {
/// S: Serializer,
/// {
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// E::S {
/// ref r,
/// ref g,
/// ref b,
/// } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
+4 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.71" # remember to update html_root_url
version = "1.0.78" # 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)]"
@@ -13,6 +13,7 @@ include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-AP
[badges]
travis-ci = { repository = "serde-rs/serde" }
appveyor = { repository = "serde-rs/serde" }
[features]
default = []
@@ -24,8 +25,8 @@ proc-macro = true
[dependencies]
proc-macro2 = "0.4"
quote = "0.6"
syn = { version = "0.14", features = ["visit"] }
quote = "0.6.3"
syn = { version = "0.15", features = ["visit"] }
[dev-dependencies]
serde = { version = "1.0", path = "../serde" }
+2 -1
View File
@@ -90,7 +90,8 @@ pub fn with_where_predicates_from_variants(
// Puts the given bound on any generic type parameters that are used in fields
// for which filter returns true.
//
// For example, the following struct needs the bound `A: Serialize, B: Serialize`.
// For example, the following struct needs the bound `A: Serialize, B:
// Serialize`.
//
// struct S<'b, A, B: 'b, C> {
// a: A,
+8 -5
View File
@@ -30,8 +30,9 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream
let ident = &cont.ident;
let params = Parameters::new(&cont);
let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params);
let suffix = ident.to_string().trim_left_matches("r#").to_owned();
let dummy_const = Ident::new(
&format!("_IMPL_DESERIALIZE_FOR_{}", ident),
&format!("_IMPL_DESERIALIZE_FOR_{}", suffix),
Span::call_site(),
);
let body = Stmts(deserialize_body(&cont, &params));
@@ -837,7 +838,8 @@ fn deserialize_newtype_struct(
#[cfg(feature = "deserialize_in_place")]
fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> TokenStream {
// We do not generate deserialize_in_place if every field has a deserialize_with.
// We do not generate deserialize_in_place if every field has a
// deserialize_with.
assert!(field.attrs.deserialize_with().is_none());
let delife = params.borrowed.de_lifetime();
@@ -941,8 +943,8 @@ fn deserialize_struct(
quote!(mut __seq)
};
// untagged struct variants do not get a visit_seq method. The same applies to structs that
// only have a map representation.
// untagged struct variants do not get a visit_seq method. The same applies to
// structs that only have a map representation.
let visit_seq = match *untagged {
Untagged::No if !cattrs.has_flatten() => Some(quote! {
#[inline]
@@ -2547,7 +2549,8 @@ fn deserialize_map_in_place(
.map(|(i, field)| (field, field_i(i)))
.collect();
// For deserialize_in_place, declare booleans for each field that will be deserialized.
// For deserialize_in_place, declare booleans for each field that will be
// deserialized.
let let_flags = fields_names
.iter()
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
+28 -24
View File
@@ -11,8 +11,8 @@ use proc_macro2::{Group, Span, TokenStream, TokenTree};
use std::collections::BTreeSet;
use std::str::FromStr;
use syn;
use syn::parse::{self, Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::synom::{ParseError, Synom};
use syn::Ident;
use syn::Meta::{List, NameValue, Word};
use syn::NestedMeta::{Literal, Meta};
@@ -90,6 +90,10 @@ pub struct Name {
deserialize: String,
}
fn unraw(ident: &Ident) -> String {
ident.to_string().trim_left_matches("r#").to_owned()
}
impl Name {
/// Return the container name for the container when serializing.
pub fn serialize_name(&self) -> String {
@@ -272,7 +276,7 @@ impl Container {
}
}
// Parse `#[serde(bound = "D: Serialize")]`
// Parse `#[serde(bound = "T: SomeBound")]`
Meta(NameValue(ref m)) if m.ident == "bound" => {
if let Ok(where_predicates) =
parse_lit_into_where(cx, &m.ident, &m.ident, &m.lit)
@@ -282,7 +286,7 @@ impl Container {
}
}
// Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
// Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
Meta(List(ref m)) if m.ident == "bound" => {
if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
ser_bound.set_opt(ser);
@@ -380,8 +384,8 @@ impl Container {
Container {
name: Name {
serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()),
deserialize: de_name.get().unwrap_or_else(|| item.ident.to_string()),
serialize: ser_name.get().unwrap_or_else(|| unraw(&item.ident)),
deserialize: de_name.get().unwrap_or_else(|| unraw(&item.ident)),
},
transparent: transparent.get(),
deny_unknown_fields: deny_unknown_fields.get(),
@@ -617,7 +621,7 @@ impl Variant {
other.set_true();
}
// Parse `#[serde(bound = "D: Serialize")]`
// Parse `#[serde(bound = "T: SomeBound")]`
Meta(NameValue(ref m)) if m.ident == "bound" => {
if let Ok(where_predicates) =
parse_lit_into_where(cx, &m.ident, &m.ident, &m.lit)
@@ -627,7 +631,7 @@ impl Variant {
}
}
// Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
// Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
Meta(List(ref m)) if m.ident == "bound" => {
if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
ser_bound.set_opt(ser);
@@ -697,8 +701,8 @@ impl Variant {
let de_renamed = de_name.is_some();
Variant {
name: Name {
serialize: ser_name.unwrap_or_else(|| variant.ident.to_string()),
deserialize: de_name.unwrap_or_else(|| variant.ident.to_string()),
serialize: ser_name.unwrap_or_else(|| unraw(&variant.ident)),
deserialize: de_name.unwrap_or_else(|| unraw(&variant.ident)),
},
ser_renamed: ser_renamed,
de_renamed: de_renamed,
@@ -822,7 +826,7 @@ impl Field {
let mut flatten = BoolAttr::none(cx, "flatten");
let ident = match field.ident {
Some(ref ident) => ident.to_string(),
Some(ref ident) => unraw(ident),
None => index.to_string(),
};
@@ -921,7 +925,7 @@ impl Field {
}
}
// Parse `#[serde(bound = "D: Serialize")]`
// Parse `#[serde(bound = "T: SomeBound")]`
Meta(NameValue(ref m)) if m.ident == "bound" => {
if let Ok(where_predicates) =
parse_lit_into_where(cx, &m.ident, &m.ident, &m.lit)
@@ -931,7 +935,7 @@ impl Field {
}
}
// Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
// Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
Meta(List(ref m)) if m.ident == "bound" => {
if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
ser_bound.set_opt(ser);
@@ -989,9 +993,9 @@ impl Field {
}
}
// Is skip_deserializing, initialize the field to Default::default() unless a different
// default is specified by `#[serde(default = "...")]` on ourselves or our container (e.g.
// the struct we are in).
// Is skip_deserializing, initialize the field to Default::default() unless a
// different default is specified by `#[serde(default = "...")]` on
// ourselves or our container (e.g. the struct we are in).
if let Default::None = *container_default {
if skip_deserializing.0.value.is_some() {
default.set_if_none(Default::Default);
@@ -1296,11 +1300,10 @@ fn parse_lit_into_lifetimes(
struct BorrowedLifetimes(Punctuated<syn::Lifetime, Token![+]>);
impl Synom for BorrowedLifetimes {
named!(parse -> Self, map!(
call!(Punctuated::parse_separated_nonempty),
BorrowedLifetimes
));
impl Parse for BorrowedLifetimes {
fn parse(input: ParseStream) -> parse::Result<Self> {
Punctuated::parse_separated_nonempty(input).map(BorrowedLifetimes)
}
}
if let Ok(BorrowedLifetimes(lifetimes)) = parse_lit_str(string) {
@@ -1509,7 +1512,8 @@ fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) {
syn::GenericArgument::Binding(ref binding) => {
collect_lifetimes(&binding.ty, out);
}
syn::GenericArgument::Const(_) => {}
syn::GenericArgument::Constraint(_)
| syn::GenericArgument::Const(_) => {}
}
}
}
@@ -1531,15 +1535,15 @@ fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) {
}
}
fn parse_lit_str<T>(s: &syn::LitStr) -> Result<T, ParseError>
fn parse_lit_str<T>(s: &syn::LitStr) -> parse::Result<T>
where
T: Synom,
T: Parse,
{
let tokens = try!(spanned_tokens(s));
syn::parse2(tokens)
}
fn spanned_tokens(s: &syn::LitStr) -> Result<TokenStream, ParseError> {
fn spanned_tokens(s: &syn::LitStr) -> parse::Result<TokenStream> {
let stream = try!(syn::parse_str(&s.value()));
Ok(respan_token_stream(stream, s.span()))
}
+6 -3
View File
@@ -22,13 +22,16 @@ pub enum RenameRule {
LowerCase,
/// Rename direct children to "UPPERCASE" style.
UPPERCASE,
/// Rename direct children to "PascalCase" style, as typically used for enum variants.
/// Rename direct children to "PascalCase" style, as typically used for
/// enum variants.
PascalCase,
/// Rename direct children to "camelCase" style.
CamelCase,
/// Rename direct children to "snake_case" style, as commonly used for fields.
/// Rename direct children to "snake_case" style, as commonly used for
/// fields.
SnakeCase,
/// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly used for constants.
/// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly
/// used for constants.
ScreamingSnakeCase,
/// Rename direct children to "kebab-case" style.
KebabCase,
+3 -3
View File
@@ -22,7 +22,7 @@
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.71")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.78")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(
@@ -81,7 +81,7 @@ mod try;
#[proc_macro_derive(Serialize, attributes(serde))]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
let input: DeriveInput = syn::parse(input).unwrap();
let input = parse_macro_input!(input as DeriveInput);
ser::expand_derive_serialize(&input)
.unwrap_or_else(compile_error)
.into()
@@ -89,7 +89,7 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream {
#[proc_macro_derive(Deserialize, attributes(serde))]
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
let input: DeriveInput = syn::parse(input).unwrap();
let input = parse_macro_input!(input as DeriveInput);
de::expand_derive_deserialize(&input)
.unwrap_or_else(compile_error)
.into()
+5 -1
View File
@@ -26,7 +26,11 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
let ident = &cont.ident;
let params = Parameters::new(&cont);
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
let dummy_const = Ident::new(&format!("_IMPL_SERIALIZE_FOR_{}", ident), Span::call_site());
let suffix = ident.to_string().trim_left_matches("r#").to_owned();
let dummy_const = Ident::new(
&format!("_IMPL_SERIALIZE_FOR_{}", suffix),
Span::call_site(),
);
let body = Stmts(serialize_body(&cont, &params));
let impl_block = if let Some(remote) = cont.attrs.remote() {
+2 -1
View File
@@ -16,7 +16,8 @@ path = "lib.rs"
[dependencies]
proc-macro2 = "0.4"
syn = { version = "0.14", default-features = false, features = ["derive", "parsing", "clone-impls"] }
syn = { version = "0.15", default-features = false, features = ["derive", "parsing", "clone-impls"] }
[badges]
travis-ci = { repository = "serde-rs/serde" }
appveyor = { repository = "serde-rs/serde" }
+2 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_test"
version = "1.0.71" # remember to update html_root_url
version = "1.0.78" # 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"
@@ -20,3 +20,4 @@ serde_derive = { version = "1.0", path = "../serde_derive" }
[badges]
travis-ci = { repository = "serde-rs/serde" }
appveyor = { repository = "serde-rs/serde" }
+2 -1
View File
@@ -95,7 +95,8 @@ where
}
}
/// Asserts that `value` serializes to the given `tokens`, and then yields `error`.
/// Asserts that `value` serializes to the given `tokens`, and then yields
/// `error`.
///
/// ```rust
/// # #[macro_use]
+2 -7
View File
@@ -19,7 +19,7 @@ pub struct Compact<T: ?Sized>(T);
/// extern crate serde_test;
///
/// use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// use serde_test::{Configure, Token, assert_tokens};
/// use serde_test::{assert_tokens, Configure, Token};
///
/// #[derive(Debug, PartialEq)]
/// struct Example(u8, u8);
@@ -67,12 +67,7 @@ pub struct Compact<T: ?Sized>(T);
/// Token::TupleEnd,
/// ],
/// );
/// assert_tokens(
/// &Example(1, 0).readable(),
/// &[
/// Token::Str("1.0"),
/// ],
/// );
/// assert_tokens(&Example(1, 0).readable(), &[Token::Str("1.0")]);
/// }
/// ```
pub trait Configure {
+1 -1
View File
@@ -161,7 +161,7 @@
//! # }
//! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.71")]
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.78")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
+2 -1
View File
@@ -11,7 +11,8 @@ use serde::{ser, Serialize};
use error::Error;
use token::Token;
/// A `Serializer` that ensures that a value serializes to a given list of tokens.
/// A `Serializer` that ensures that a value serializes to a given list of
/// tokens.
#[derive(Debug)]
pub struct Serializer<'a> {
tokens: &'a [Token],
+2 -2
View File
@@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(lang_items, start, panic_implementation)]
#![feature(lang_items, start, panic_handler)]
#![no_std]
extern crate libc;
@@ -20,7 +20,7 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
pub extern "C" fn rust_eh_personality() {}
#[panic_implementation]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
@@ -20,7 +20,7 @@ mod remote {
#[serde(remote = "remote::S")]
struct S {
a: u8,
//~^^^^ ERROR: missing field `b` in initializer of `remote::S`
//~^^^ ERROR: missing field `b` in initializer of `remote::S`
}
fn main() {}
@@ -18,9 +18,9 @@ mod remote {
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::S")]
struct S {
//~^^^ ERROR: struct `remote::S` has no field named `b`
b: u8,
//~^^^^^ ERROR: no field `b` on type `&remote::S`
//~^ ERROR: struct `remote::S` has no field named `b`
//~^^ ERROR: no field `b` on type `&remote::S`
}
fn main() {}
+131 -1
View File
@@ -12,9 +12,11 @@
extern crate serde_derive;
extern crate serde;
use self::serde::de::{self, Unexpected};
use self::serde::de::{self, Visitor, MapAccess, Unexpected};
use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::collections::{BTreeMap, HashMap};
use std::fmt;
use std::marker::PhantomData;
extern crate serde_test;
@@ -2246,3 +2248,131 @@ fn test_transparent_tuple_struct() {
assert_tokens(&Transparent(false, 1, false, PhantomData), &[Token::U32(1)]);
}
#[test]
fn test_internally_tagged_unit_enum_with_unknown_fields() {
#[derive(Deserialize, PartialEq, Debug)]
#[serde(tag = "t")]
enum Data {
A,
}
let data = Data::A;
assert_de_tokens(
&data,
&[
Token::Map { len: None },
Token::Str("t"),
Token::Str("A"),
Token::Str("b"),
Token::I32(0),
Token::MapEnd,
],
);
}
#[test]
fn test_flattened_internally_tagged_unit_enum_with_unknown_fields() {
#[derive(Deserialize, PartialEq, Debug)]
struct S {
#[serde(flatten)]
x: X,
#[serde(flatten)]
y: Y,
}
#[derive(Deserialize, PartialEq, Debug)]
#[serde(tag = "typeX")]
enum X {
A,
}
#[derive(Deserialize, PartialEq, Debug)]
#[serde(tag = "typeY")]
enum Y {
B { c: u32 },
}
let s = S {
x: X::A,
y: Y::B { c: 0 },
};
assert_de_tokens(
&s,
&[
Token::Map { len: None },
Token::Str("typeX"),
Token::Str("A"),
Token::Str("typeY"),
Token::Str("B"),
Token::Str("c"),
Token::I32(0),
Token::MapEnd,
],
);
}
#[test]
fn test_flatten_any_after_flatten_struct() {
#[derive(PartialEq, Debug)]
struct Any;
impl<'de> Deserialize<'de> for Any {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct AnyVisitor;
impl<'de> Visitor<'de> for AnyVisitor {
type Value = Any;
fn expecting(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
unimplemented!()
}
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
while let Some((Any, Any)) = map.next_entry()? {}
Ok(Any)
}
}
deserializer.deserialize_any(AnyVisitor)
}
}
#[derive(Deserialize, PartialEq, Debug)]
struct Outer {
#[serde(flatten)]
inner: Inner,
#[serde(flatten)]
extra: Any,
}
#[derive(Deserialize, PartialEq, Debug)]
struct Inner {
inner: i32,
}
let s = Outer {
inner: Inner {
inner: 0,
},
extra: Any,
};
assert_de_tokens(
&s,
&[
Token::Map { len: None },
Token::Str("inner"),
Token::I32(0),
Token::MapEnd,
],
);
}
+6 -1
View File
@@ -156,8 +156,12 @@ macro_rules! declare_tests {
)+
};
($($name:ident { $($value:expr => $tokens:expr,)+ })+) => {
($(
$(#[$cfg:meta])*
$name:ident { $($value:expr => $tokens:expr,)+ }
)+) => {
$(
$(#[$cfg])*
#[test]
fn $name() {
$(
@@ -260,6 +264,7 @@ declare_tests! {
0f32 => &[Token::F32(0.)],
0f64 => &[Token::F64(0.)],
}
#[cfg(not(target_arch = "wasm32"))]
test_small_int_to_128 {
1i128 => &[Token::I8(1)],
1i128 => &[Token::I16(1)],
+22 -13
View File
@@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// These just test that serde_codegen is able to produce code that compiles
// These just test that serde_derive is able to produce code that compiles
// successfully when there are a variety of generics and non-(de)serializable
// types involved.
@@ -198,12 +198,10 @@ fn test_gen() {
assert::<WithTraits1<X, X>>();
#[derive(Serialize, Deserialize)]
#[serde(
bound(
serialize = "D: SerializeWith",
deserialize = "D: DeserializeWith"
)
)]
#[serde(bound(
serialize = "D: SerializeWith",
deserialize = "D: DeserializeWith"
))]
struct WithTraits2<D, E> {
#[serde(
serialize_with = "SerializeWith::serialize_with",
@@ -240,12 +238,10 @@ fn test_gen() {
assert::<VariantWithTraits1<X, X>>();
#[derive(Serialize, Deserialize)]
#[serde(
bound(
serialize = "D: SerializeWith",
deserialize = "D: DeserializeWith"
)
)]
#[serde(bound(
serialize = "D: SerializeWith",
deserialize = "D: DeserializeWith"
))]
enum VariantWithTraits2<D, E> {
#[serde(
serialize_with = "SerializeWith::serialize_with",
@@ -669,6 +665,19 @@ fn test_gen() {
#[serde(deserialize_with = "de_x")]
x: X,
}
#[derive(Deserialize)]
#[serde(untagged)]
enum UntaggedWithBorrow<'a> {
Single(#[serde(borrow)] RelObject<'a>),
Many(#[serde(borrow)] Vec<RelObject<'a>>),
}
#[derive(Deserialize)]
struct RelObject<'a> {
ty: &'a str,
id: String,
}
}
//////////////////////////////////////////////////////////////////////////
+1
View File
@@ -618,6 +618,7 @@ fn test_enum_skipped() {
);
}
#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_integer128() {
assert_ser_tokens_error(&1i128, &[], "i128 is not supported");
+26
View File
@@ -0,0 +1,26 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![deny(warnings)]
#[cfg(feature = "unstable")]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "unstable")]
extern crate serde;
#[cfg(feature = "unstable")]
extern crate serde_test;
// This test target is convoluted with the actual #[test] in a separate file to
// get it so that the stable compiler does not need to parse the code of the
// test. If the test were written with #[cfg(feature = "unstable")] #[test]
// right here, the stable compiler would fail to parse those raw identifiers
// even if the cfg were not enabled.
#[cfg(feature = "unstable")]
mod unstable;
+1
View File
@@ -26,6 +26,7 @@ fn test_u32_to_enum() {
assert_eq!(E::B, e);
}
#[cfg(not(target_arch = "wasm32"))]
#[test]
fn test_integer128() {
let de_u128 = IntoDeserializer::<value::Error>::into_deserializer(1u128);
+32
View File
@@ -0,0 +1,32 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde_test::{assert_tokens, Token};
#[test]
fn test_raw_identifiers() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[allow(non_camel_case_types)]
enum r#type {
r#type { r#type: () },
}
assert_tokens(
&r#type::r#type { r#type: () },
&[
Token::StructVariant {
name: "type",
variant: "type",
len: 1,
},
Token::Str("type"),
Token::Unit,
Token::StructVariantEnd,
],
);
}
+13
View File
@@ -42,6 +42,18 @@ if [ -n "${CLIPPY}" ]; then
cd "$DIR/test_suite/no_std"
cargo clippy -- -Dclippy
elif [ -n "${EMSCRIPTEN}" ]; then
CARGO_WEB_RELEASE=$(curl -L -s -H 'Accept: application/json' https://github.com/koute/cargo-web/releases/latest)
CARGO_WEB_VERSION=$(echo "${CARGO_WEB_RELEASE}" | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')
CARGO_WEB_URL="https://github.com/koute/cargo-web/releases/download/${CARGO_WEB_VERSION}/cargo-web-x86_64-unknown-linux-gnu.gz"
mkdir -p ~/.cargo/bin
echo "Downloading cargo-web from: ${CARGO_WEB_URL}"
curl -L "${CARGO_WEB_URL}" | gzip -d > ~/.cargo/bin/cargo-web
chmod +x ~/.cargo/bin/cargo-web
cd "$DIR/test_suite"
cargo web test --target=wasm32-unknown-emscripten --nodejs
else
CHANNEL=nightly
cd "$DIR"
@@ -50,6 +62,7 @@ else
channel build
channel build --no-default-features
channel build --no-default-features --features alloc
channel build --no-default-features --features 'rc alloc'
channel test --features 'rc unstable'
cd "$DIR/test_suite/deps"
channel build