mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-27 19:17:57 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1b45e5766a | |||
| 59c8951341 | |||
| aca61b5dda | |||
| 908affd24f | |||
| f878d2ebd5 | |||
| 778e516270 | |||
| 6d58492ad0 | |||
| fecfabb168 | |||
| 80765eb453 | |||
| f1073dca04 | |||
| da65fe5a52 | |||
| 3f0f739e17 | |||
| 5023e2ad52 | |||
| 810cde1c84 | |||
| 9436efb80e | |||
| 48230890c5 | |||
| f1e8dcf38e | |||
| 2cf10a6003 | |||
| 23a53d8008 | |||
| 9956589ed5 | |||
| 81a3f66d78 | |||
| a8247bc619 | |||
| 66a9ccb10e | |||
| 53fe1b328e | |||
| 2753ec757b | |||
| dcd2232f69 | |||
| 0156f1355a | |||
| 61bf901048 | |||
| 7870b58356 | |||
| 8cc7e6aa90 |
+88
-20
@@ -1,25 +1,93 @@
|
|||||||
sudo: false
|
|
||||||
language: rust
|
language: rust
|
||||||
cache: cargo
|
|
||||||
|
|
||||||
# run builds for all the trains (and more)
|
|
||||||
rust:
|
|
||||||
- stable
|
|
||||||
- beta
|
|
||||||
- nightly
|
|
||||||
- 1.13.0
|
|
||||||
- 1.15.0
|
|
||||||
- 1.20.0
|
|
||||||
- 1.21.0
|
|
||||||
- 1.25.0
|
|
||||||
- 1.26.0
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- rust: nightly
|
- rust: stable
|
||||||
env: CLIPPY=true
|
script:
|
||||||
- rust: nightly
|
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||||
env: EMSCRIPTEN=true
|
- cargo build --features rc
|
||||||
script: nvm install 9 && ./travis.sh
|
- cargo build --no-default-features
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/serde_test"
|
||||||
|
- cargo build
|
||||||
|
- cargo test
|
||||||
|
|
||||||
script: ./travis.sh
|
- rust: beta
|
||||||
|
script:
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||||
|
- cargo build --features rc
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/test_suite"
|
||||||
|
- cargo test
|
||||||
|
|
||||||
|
- rust: nightly
|
||||||
|
script:
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||||
|
- cargo build
|
||||||
|
- cargo build --no-default-features
|
||||||
|
- cargo build --no-default-features --features alloc
|
||||||
|
- cargo build --no-default-features --features rc,alloc
|
||||||
|
- cargo test --features rc,unstable
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/test_suite/deps"
|
||||||
|
- cargo build
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/test_suite"
|
||||||
|
- cargo test --features unstable
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/test_suite/no_std"
|
||||||
|
- cargo build
|
||||||
|
|
||||||
|
- rust: 1.13.0
|
||||||
|
script:
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||||
|
- cargo build --features rc
|
||||||
|
- cargo build --no-default-features
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/serde_test"
|
||||||
|
- cargo build
|
||||||
|
|
||||||
|
- rust: 1.15.0
|
||||||
|
script:
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/serde_derive"
|
||||||
|
- cargo build
|
||||||
|
|
||||||
|
- rust: 1.20.0
|
||||||
|
- rust: 1.21.0
|
||||||
|
- rust: 1.25.0
|
||||||
|
- rust: 1.26.0
|
||||||
|
|
||||||
|
- rust: nightly
|
||||||
|
env: CLIPPY
|
||||||
|
script:
|
||||||
|
- rustup component add clippy-preview || travis_terminate 0
|
||||||
|
- cargo clippy -- -Dclippy
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||||
|
- cargo clippy --features rc,unstable -- -Dclippy
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/serde_derive"
|
||||||
|
- cargo clippy -- -Dclippy
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/serde_test"
|
||||||
|
- cargo clippy -- -Dclippy
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/test_suite"
|
||||||
|
- cargo clippy --features unstable -- -Dclippy
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/test_suite/no_std"
|
||||||
|
- cargo clippy -- -Dclippy
|
||||||
|
|
||||||
|
- rust: nightly
|
||||||
|
env: EMSCRIPTEN
|
||||||
|
script:
|
||||||
|
- 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}" | jq -r .tag_name)
|
||||||
|
- CARGO_WEB_URL="https://github.com/koute/cargo-web/releases/download/${CARGO_WEB_VERSION}/cargo-web-x86_64-unknown-linux-gnu.gz"
|
||||||
|
|
||||||
|
- nvm install 9
|
||||||
|
- mkdir -p ~/.cargo/bin
|
||||||
|
- curl -L "${CARGO_WEB_URL}" | gzip -d > ~/.cargo/bin/cargo-web
|
||||||
|
- chmod +x ~/.cargo/bin/cargo-web
|
||||||
|
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/test_suite"
|
||||||
|
- cargo web test --target=asmjs-unknown-emscripten --nodejs
|
||||||
|
- cargo web test --target=wasm32-unknown-emscripten --nodejs
|
||||||
|
|
||||||
|
allow_failures:
|
||||||
|
- rust: nightly
|
||||||
|
env: CLIPPY
|
||||||
|
|
||||||
|
script:
|
||||||
|
- cd "${TRAVIS_BUILD_DIR}/serde"
|
||||||
|
- cargo build --no-default-features
|
||||||
|
- cargo build
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ You may be looking for:
|
|||||||
|
|
||||||
- [An overview of Serde](https://serde.rs/)
|
- [An overview of Serde](https://serde.rs/)
|
||||||
- [Data formats supported by Serde](https://serde.rs/#data-formats)
|
- [Data formats supported by Serde](https://serde.rs/#data-formats)
|
||||||
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
|
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
|
||||||
- [Examples](https://serde.rs/examples.html)
|
- [Examples](https://serde.rs/examples.html)
|
||||||
- [API documentation](https://docs.serde.rs/serde/)
|
- [API documentation](https://docs.serde.rs/serde/)
|
||||||
- [Release notes](https://github.com/serde-rs/serde/releases)
|
- [Release notes](https://github.com/serde-rs/serde/releases)
|
||||||
|
|||||||
+26
-2
@@ -13,5 +13,29 @@ install:
|
|||||||
|
|
||||||
build: false
|
build: false
|
||||||
|
|
||||||
test_script:
|
for:
|
||||||
- sh -c 'PATH=`rustc --print sysroot`/bin:$PATH ./travis.sh'
|
- matrix:
|
||||||
|
only:
|
||||||
|
- APPVEYOR_RUST_CHANNEL: stable
|
||||||
|
test_script:
|
||||||
|
- cd %APPVEYOR_BUILD_FOLDER%\serde
|
||||||
|
- cargo build --features rc
|
||||||
|
- cargo build --no-default-features
|
||||||
|
- cd %APPVEYOR_BUILD_FOLDER%\serde_test
|
||||||
|
- cargo build
|
||||||
|
- cargo test
|
||||||
|
|
||||||
|
- matrix:
|
||||||
|
only:
|
||||||
|
- APPVEYOR_RUST_CHANNEL: nightly
|
||||||
|
test_script:
|
||||||
|
- cd %APPVEYOR_BUILD_FOLDER%\serde
|
||||||
|
- cargo build
|
||||||
|
- cargo build --no-default-features
|
||||||
|
- cargo build --no-default-features --features alloc
|
||||||
|
- cargo build --no-default-features --features rc,alloc
|
||||||
|
- cargo test --features rc,unstable
|
||||||
|
- cd %APPVEYOR_BUILD_FOLDER%\test_suite\deps
|
||||||
|
- cargo build
|
||||||
|
- cd %APPVEYOR_BUILD_FOLDER%\test_suite
|
||||||
|
- cargo test --features unstable
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ You may be looking for:
|
|||||||
|
|
||||||
- [An overview of Serde](https://serde.rs/)
|
- [An overview of Serde](https://serde.rs/)
|
||||||
- [Data formats supported by Serde](https://serde.rs/#data-formats)
|
- [Data formats supported by Serde](https://serde.rs/#data-formats)
|
||||||
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
|
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
|
||||||
- [Examples](https://serde.rs/examples.html)
|
- [Examples](https://serde.rs/examples.html)
|
||||||
- [API documentation](https://docs.serde.rs/serde/)
|
- [API documentation](https://docs.serde.rs/serde/)
|
||||||
- [Release notes](https://github.com/serde-rs/serde/releases)
|
- [Release notes](https://github.com/serde-rs/serde/releases)
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.78" # remember to update html_root_url
|
version = "1.0.80" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "A generic serialization/deserialization framework"
|
description = "A generic serialization/deserialization framework"
|
||||||
|
|||||||
+91
-20
@@ -696,7 +696,6 @@ macro_rules! seq_impl {
|
|||||||
(
|
(
|
||||||
$ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
|
$ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
|
||||||
$access:ident,
|
$access:ident,
|
||||||
$ctor:expr,
|
|
||||||
$clear:expr,
|
$clear:expr,
|
||||||
$with_capacity:expr,
|
$with_capacity:expr,
|
||||||
$reserve:expr,
|
$reserve:expr,
|
||||||
@@ -793,7 +792,6 @@ fn nop_reserve<T>(_seq: T, _n: usize) {}
|
|||||||
seq_impl!(
|
seq_impl!(
|
||||||
BinaryHeap<T: Ord>,
|
BinaryHeap<T: Ord>,
|
||||||
seq,
|
seq,
|
||||||
BinaryHeap::new(),
|
|
||||||
BinaryHeap::clear,
|
BinaryHeap::clear,
|
||||||
BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
|
BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
|
||||||
BinaryHeap::reserve,
|
BinaryHeap::reserve,
|
||||||
@@ -803,7 +801,6 @@ seq_impl!(
|
|||||||
seq_impl!(
|
seq_impl!(
|
||||||
BTreeSet<T: Eq + Ord>,
|
BTreeSet<T: Eq + Ord>,
|
||||||
seq,
|
seq,
|
||||||
BTreeSet::new(),
|
|
||||||
BTreeSet::clear,
|
BTreeSet::clear,
|
||||||
BTreeSet::new(),
|
BTreeSet::new(),
|
||||||
nop_reserve,
|
nop_reserve,
|
||||||
@@ -813,7 +810,6 @@ seq_impl!(
|
|||||||
seq_impl!(
|
seq_impl!(
|
||||||
LinkedList<T>,
|
LinkedList<T>,
|
||||||
seq,
|
seq,
|
||||||
LinkedList::new(),
|
|
||||||
LinkedList::clear,
|
LinkedList::clear,
|
||||||
LinkedList::new(),
|
LinkedList::new(),
|
||||||
nop_reserve,
|
nop_reserve,
|
||||||
@@ -824,28 +820,15 @@ seq_impl!(
|
|||||||
seq_impl!(
|
seq_impl!(
|
||||||
HashSet<T: Eq + Hash, S: BuildHasher + Default>,
|
HashSet<T: Eq + Hash, S: BuildHasher + Default>,
|
||||||
seq,
|
seq,
|
||||||
HashSet::with_hasher(S::default()),
|
|
||||||
HashSet::clear,
|
HashSet::clear,
|
||||||
HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
|
HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
|
||||||
HashSet::reserve,
|
HashSet::reserve,
|
||||||
HashSet::insert);
|
HashSet::insert);
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
|
||||||
seq_impl!(
|
|
||||||
Vec<T>,
|
|
||||||
seq,
|
|
||||||
Vec::new(),
|
|
||||||
Vec::clear,
|
|
||||||
Vec::with_capacity(size_hint::cautious(seq.size_hint())),
|
|
||||||
Vec::reserve,
|
|
||||||
Vec::push
|
|
||||||
);
|
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
seq_impl!(
|
seq_impl!(
|
||||||
VecDeque<T>,
|
VecDeque<T>,
|
||||||
seq,
|
seq,
|
||||||
VecDeque::new(),
|
|
||||||
VecDeque::clear,
|
VecDeque::clear,
|
||||||
VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
|
VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
|
||||||
VecDeque::reserve,
|
VecDeque::reserve,
|
||||||
@@ -854,6 +837,97 @@ seq_impl!(
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
impl<'de, T> Deserialize<'de> for Vec<T>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
struct VecVisitor<T> {
|
||||||
|
marker: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, T> Visitor<'de> for VecVisitor<T>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
type Value = Vec<T>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("a sequence")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
|
where
|
||||||
|
A: SeqAccess<'de>,
|
||||||
|
{
|
||||||
|
let mut values = Vec::with_capacity(size_hint::cautious(seq.size_hint()));
|
||||||
|
|
||||||
|
while let Some(value) = try!(seq.next_element()) {
|
||||||
|
values.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let visitor = VecVisitor { marker: PhantomData };
|
||||||
|
deserializer.deserialize_seq(visitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
struct VecInPlaceVisitor<'a, T: 'a>(&'a mut Vec<T>);
|
||||||
|
|
||||||
|
impl<'a, 'de, T> Visitor<'de> for VecInPlaceVisitor<'a, T>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
type Value = ();
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("a sequence")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
|
where
|
||||||
|
A: SeqAccess<'de>,
|
||||||
|
{
|
||||||
|
let hint = size_hint::cautious(seq.size_hint());
|
||||||
|
if let Some(additional) = hint.checked_sub(self.0.len()) {
|
||||||
|
self.0.reserve(additional);
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..self.0.len() {
|
||||||
|
let next = {
|
||||||
|
let next_place = InPlaceSeed(&mut self.0[i]);
|
||||||
|
try!(seq.next_element_seed(next_place))
|
||||||
|
};
|
||||||
|
if next.is_none() {
|
||||||
|
self.0.truncate(i);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(value) = try!(seq.next_element()) {
|
||||||
|
self.0.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_seq(VecInPlaceVisitor(place))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct ArrayVisitor<A> {
|
struct ArrayVisitor<A> {
|
||||||
marker: PhantomData<A>,
|
marker: PhantomData<A>,
|
||||||
}
|
}
|
||||||
@@ -1113,7 +1187,6 @@ macro_rules! map_impl {
|
|||||||
(
|
(
|
||||||
$ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
|
$ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
|
||||||
$access:ident,
|
$access:ident,
|
||||||
$ctor:expr,
|
|
||||||
$with_capacity:expr
|
$with_capacity:expr
|
||||||
) => {
|
) => {
|
||||||
impl<'de, K, V $(, $typaram)*> Deserialize<'de> for $ty<K, V $(, $typaram)*>
|
impl<'de, K, V $(, $typaram)*> Deserialize<'de> for $ty<K, V $(, $typaram)*>
|
||||||
@@ -1168,14 +1241,12 @@ macro_rules! map_impl {
|
|||||||
map_impl!(
|
map_impl!(
|
||||||
BTreeMap<K: Ord, V>,
|
BTreeMap<K: Ord, V>,
|
||||||
map,
|
map,
|
||||||
BTreeMap::new(),
|
|
||||||
BTreeMap::new());
|
BTreeMap::new());
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
map_impl!(
|
map_impl!(
|
||||||
HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
|
HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
|
||||||
map,
|
map,
|
||||||
HashMap::with_hasher(S::default()),
|
|
||||||
HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default()));
|
HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default()));
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
+2
-1
@@ -82,7 +82,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Serde types in rustdoc of other crates get linked to here.
|
// Serde types in rustdoc of other crates get linked to here.
|
||||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.78")]
|
#![doc(html_root_url = "https://docs.rs/serde/1.0.80")]
|
||||||
// Support using Serde without the standard library!
|
// Support using Serde without the standard library!
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
// Unstable functionality only if the user asks for it. For tracking and
|
// Unstable functionality only if the user asks for it. For tracking and
|
||||||
@@ -91,6 +91,7 @@
|
|||||||
// https://github.com/serde-rs/serde/issues/812
|
// https://github.com/serde-rs/serde/issues/812
|
||||||
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
|
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
|
||||||
#![cfg_attr(feature = "alloc", feature(alloc))]
|
#![cfg_attr(feature = "alloc", feature(alloc))]
|
||||||
|
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||||
// Whitelisted clippy lints
|
// Whitelisted clippy lints
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.78" # remember to update html_root_url
|
version = "1.0.80" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||||
homepage = "https://serde.rs"
|
homepage = "https://serde.rs"
|
||||||
repository = "https://github.com/serde-rs/serde"
|
repository = "https://github.com/serde-rs/serde"
|
||||||
documentation = "https://serde.rs/codegen.html"
|
documentation = "https://serde.rs/derive.html"
|
||||||
keywords = ["serde", "serialization", "no_std"]
|
keywords = ["serde", "serialization", "no_std"]
|
||||||
readme = "crates-io.md"
|
readme = "crates-io.md"
|
||||||
include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
|
|||||||
+23
-3
@@ -1157,6 +1157,10 @@ fn deserialize_externally_tagged_enum(
|
|||||||
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
|
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let other_idx = variants
|
||||||
|
.iter()
|
||||||
|
.position(|ref variant| variant.attrs.other());
|
||||||
|
|
||||||
let variants_stmt = {
|
let variants_stmt = {
|
||||||
let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
|
let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
|
||||||
quote! {
|
quote! {
|
||||||
@@ -1168,6 +1172,7 @@ fn deserialize_externally_tagged_enum(
|
|||||||
&variant_names_idents,
|
&variant_names_idents,
|
||||||
cattrs,
|
cattrs,
|
||||||
true,
|
true,
|
||||||
|
other_idx,
|
||||||
));
|
));
|
||||||
|
|
||||||
// Match arms to extract a variant from a string
|
// Match arms to extract a variant from a string
|
||||||
@@ -1255,6 +1260,10 @@ fn deserialize_internally_tagged_enum(
|
|||||||
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
|
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let other_idx = variants
|
||||||
|
.iter()
|
||||||
|
.position(|ref variant| variant.attrs.other());
|
||||||
|
|
||||||
let variants_stmt = {
|
let variants_stmt = {
|
||||||
let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
|
let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
|
||||||
quote! {
|
quote! {
|
||||||
@@ -1266,6 +1275,7 @@ fn deserialize_internally_tagged_enum(
|
|||||||
&variant_names_idents,
|
&variant_names_idents,
|
||||||
cattrs,
|
cattrs,
|
||||||
true,
|
true,
|
||||||
|
other_idx,
|
||||||
));
|
));
|
||||||
|
|
||||||
// Match arms to extract a variant from a string
|
// Match arms to extract a variant from a string
|
||||||
@@ -1324,6 +1334,10 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
|
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let other_idx = variants
|
||||||
|
.iter()
|
||||||
|
.position(|ref variant| variant.attrs.other());
|
||||||
|
|
||||||
let variants_stmt = {
|
let variants_stmt = {
|
||||||
let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
|
let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
|
||||||
quote! {
|
quote! {
|
||||||
@@ -1335,6 +1349,7 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
&variant_names_idents,
|
&variant_names_idents,
|
||||||
cattrs,
|
cattrs,
|
||||||
true,
|
true,
|
||||||
|
other_idx,
|
||||||
));
|
));
|
||||||
|
|
||||||
let variant_arms: &Vec<_> = &variants
|
let variant_arms: &Vec<_> = &variants
|
||||||
@@ -1842,6 +1857,7 @@ fn deserialize_generated_identifier(
|
|||||||
fields: &[(String, Ident)],
|
fields: &[(String, Ident)],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
is_variant: bool,
|
is_variant: bool,
|
||||||
|
other_idx: Option<usize>,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = quote!(__Field);
|
let this = quote!(__Field);
|
||||||
let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect();
|
let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect();
|
||||||
@@ -1850,6 +1866,10 @@ fn deserialize_generated_identifier(
|
|||||||
let ignore_variant = quote!(__other(_serde::private::de::Content<'de>),);
|
let ignore_variant = quote!(__other(_serde::private::de::Content<'de>),);
|
||||||
let fallthrough = quote!(_serde::export::Ok(__Field::__other(__value)));
|
let fallthrough = quote!(_serde::export::Ok(__Field::__other(__value)));
|
||||||
(Some(ignore_variant), Some(fallthrough))
|
(Some(ignore_variant), Some(fallthrough))
|
||||||
|
} else if let Some(other_idx) = other_idx {
|
||||||
|
let ignore_variant = fields[other_idx].1.clone();
|
||||||
|
let fallthrough = quote!(_serde::export::Ok(__Field::#ignore_variant));
|
||||||
|
(None, Some(fallthrough))
|
||||||
} else if is_variant || cattrs.deny_unknown_fields() {
|
} else if is_variant || cattrs.deny_unknown_fields() {
|
||||||
(None, None)
|
(None, None)
|
||||||
} else {
|
} else {
|
||||||
@@ -2272,7 +2292,7 @@ fn deserialize_struct_as_struct_visitor(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false);
|
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
|
||||||
|
|
||||||
let visit_map = deserialize_map(struct_path, params, fields, cattrs);
|
let visit_map = deserialize_map(struct_path, params, fields, cattrs);
|
||||||
|
|
||||||
@@ -2292,7 +2312,7 @@ fn deserialize_struct_as_map_visitor(
|
|||||||
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
|
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false);
|
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
|
||||||
|
|
||||||
let visit_map = deserialize_map(struct_path, params, fields, cattrs);
|
let visit_map = deserialize_map(struct_path, params, fields, cattrs);
|
||||||
|
|
||||||
@@ -2527,7 +2547,7 @@ fn deserialize_struct_as_struct_in_place_visitor(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false);
|
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
|
||||||
|
|
||||||
let visit_map = deserialize_map_in_place(params, fields, cattrs);
|
let visit_map = deserialize_map_in_place(params, fields, cattrs);
|
||||||
|
|
||||||
|
|||||||
@@ -6,24 +6,36 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
//! A Serde ast, parsed from the Syn ast and ready to generate Rust code.
|
||||||
|
|
||||||
use internals::attr;
|
use internals::attr;
|
||||||
use internals::check;
|
use internals::check;
|
||||||
use internals::{Ctxt, Derive};
|
use internals::{Ctxt, Derive};
|
||||||
use syn;
|
use syn;
|
||||||
use syn::punctuated::Punctuated;
|
use syn::punctuated::Punctuated;
|
||||||
|
|
||||||
|
/// A source data structure annotated with `#[derive(Serialize)]` and/or `#[derive(Deserialize)]`,
|
||||||
|
/// parsed into an internal representation.
|
||||||
pub struct Container<'a> {
|
pub struct Container<'a> {
|
||||||
|
/// The struct or enum name (without generics).
|
||||||
pub ident: syn::Ident,
|
pub ident: syn::Ident,
|
||||||
|
/// Attributes on the structure, parsed for Serde.
|
||||||
pub attrs: attr::Container,
|
pub attrs: attr::Container,
|
||||||
|
/// The contents of the struct or enum.
|
||||||
pub data: Data<'a>,
|
pub data: Data<'a>,
|
||||||
|
/// Any generics on the struct or enum.
|
||||||
pub generics: &'a syn::Generics,
|
pub generics: &'a syn::Generics,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The fields of a struct or enum.
|
||||||
|
///
|
||||||
|
/// Analagous to `syn::Data`.
|
||||||
pub enum Data<'a> {
|
pub enum Data<'a> {
|
||||||
Enum(Vec<Variant<'a>>),
|
Enum(Vec<Variant<'a>>),
|
||||||
Struct(Style, Vec<Field<'a>>),
|
Struct(Style, Vec<Field<'a>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A variant of an enum.
|
||||||
pub struct Variant<'a> {
|
pub struct Variant<'a> {
|
||||||
pub ident: syn::Ident,
|
pub ident: syn::Ident,
|
||||||
pub attrs: attr::Variant,
|
pub attrs: attr::Variant,
|
||||||
@@ -31,6 +43,7 @@ pub struct Variant<'a> {
|
|||||||
pub fields: Vec<Field<'a>>,
|
pub fields: Vec<Field<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A field of a struct.
|
||||||
pub struct Field<'a> {
|
pub struct Field<'a> {
|
||||||
pub member: syn::Member,
|
pub member: syn::Member,
|
||||||
pub attrs: attr::Field,
|
pub attrs: attr::Field,
|
||||||
@@ -40,13 +53,18 @@ pub struct Field<'a> {
|
|||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum Style {
|
pub enum Style {
|
||||||
|
/// Named fields.
|
||||||
Struct,
|
Struct,
|
||||||
|
/// Many unnamed fields.
|
||||||
Tuple,
|
Tuple,
|
||||||
|
/// One unnamed field.
|
||||||
Newtype,
|
Newtype,
|
||||||
|
/// No fields.
|
||||||
Unit,
|
Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Container<'a> {
|
impl<'a> Container<'a> {
|
||||||
|
/// Convert the raw Syn ast into a parsed container object, collecting errors in `cx`.
|
||||||
pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput, derive: Derive) -> Container<'a> {
|
pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput, derive: Derive) -> Container<'a> {
|
||||||
let mut attrs = attr::Container::from_ast(cx, item);
|
let mut attrs = attr::Container::from_ast(cx, item);
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ impl Name {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents container (e.g. struct) attribute information
|
/// Represents struct or enum attribute information.
|
||||||
pub struct Container {
|
pub struct Container {
|
||||||
name: Name,
|
name: Name,
|
||||||
transparent: bool,
|
transparent: bool,
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
//! Code to convert the Rust-styled field/variant (e.g. `my_field`, `MyType`) to the
|
||||||
|
//! case of the source (e.g. `my-field`, `MY_FIELD`).
|
||||||
|
|
||||||
// See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726
|
// See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726
|
||||||
#[allow(deprecated, unused_imports)]
|
#[allow(deprecated, unused_imports)]
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
@@ -14,6 +17,7 @@ use std::str::FromStr;
|
|||||||
|
|
||||||
use self::RenameRule::*;
|
use self::RenameRule::*;
|
||||||
|
|
||||||
|
/// The different possible ways to change case of fields in a struct, or variants in an enum.
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub enum RenameRule {
|
pub enum RenameRule {
|
||||||
/// Don't apply a default rename rule.
|
/// Don't apply a default rename rule.
|
||||||
@@ -40,6 +44,7 @@ pub enum RenameRule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RenameRule {
|
impl RenameRule {
|
||||||
|
/// Apply a renaming rule to an enum variant, returning the version expected in the source.
|
||||||
pub fn apply_to_variant(&self, variant: &str) -> String {
|
pub fn apply_to_variant(&self, variant: &str) -> String {
|
||||||
match *self {
|
match *self {
|
||||||
None | PascalCase => variant.to_owned(),
|
None | PascalCase => variant.to_owned(),
|
||||||
@@ -64,6 +69,7 @@ impl RenameRule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Apply a renaming rule to a struct field, returning the version expected in the source.
|
||||||
pub fn apply_to_field(&self, field: &str) -> String {
|
pub fn apply_to_field(&self, field: &str) -> String {
|
||||||
match *self {
|
match *self {
|
||||||
None | LowerCase | SnakeCase => field.to_owned(),
|
None | LowerCase | SnakeCase => field.to_owned(),
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The `other` attribute must be used at most once and it must be the last
|
/// The `other` attribute must be used at most once and it must be the last
|
||||||
/// variant of an enum that has the `field_identifier` attribute.
|
/// variant of an enum.
|
||||||
///
|
///
|
||||||
/// Inside a `variant_identifier` all variants must be unit variants. Inside a
|
/// Inside a `variant_identifier` all variants must be unit variants. Inside a
|
||||||
/// `field_identifier` all but possibly one variant must be unit variants. The
|
/// `field_identifier` all but possibly one variant must be unit variants. The
|
||||||
@@ -111,42 +111,48 @@ fn check_identifier(cx: &Ctxt, cont: &Container) {
|
|||||||
variant.style,
|
variant.style,
|
||||||
cont.attrs.identifier(),
|
cont.attrs.identifier(),
|
||||||
variant.attrs.other(),
|
variant.attrs.other(),
|
||||||
|
cont.attrs.tag(),
|
||||||
) {
|
) {
|
||||||
// The `other` attribute may only be used in a field_identifier.
|
// The `other` attribute may not be used in a variant_identifier.
|
||||||
(_, Identifier::Variant, true) | (_, Identifier::No, true) => {
|
(_, Identifier::Variant, true, _) => {
|
||||||
cx.error("#[serde(other)] may only be used inside a field_identifier");
|
cx.error("#[serde(other)] may not be used on a variant_identifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variant with `other` attribute cannot appear in untagged enum
|
||||||
|
(_, Identifier::No, true, &EnumTag::None) => {
|
||||||
|
cx.error("#[serde(other)] cannot appear on untagged enum");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variant with `other` attribute must be the last one.
|
// Variant with `other` attribute must be the last one.
|
||||||
(Style::Unit, Identifier::Field, true) => {
|
(Style::Unit, Identifier::Field, true, _) | (Style::Unit, Identifier::No, true, _) => {
|
||||||
if i < variants.len() - 1 {
|
if i < variants.len() - 1 {
|
||||||
cx.error("#[serde(other)] must be the last variant");
|
cx.error("#[serde(other)] must be the last variant");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Variant with `other` attribute must be a unit variant.
|
// Variant with `other` attribute must be a unit variant.
|
||||||
(_, Identifier::Field, true) => {
|
(_, Identifier::Field, true, _) | (_, Identifier::No, true, _) => {
|
||||||
cx.error("#[serde(other)] must be on a unit variant");
|
cx.error("#[serde(other)] must be on a unit variant");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Any sort of variant is allowed if this is not an identifier.
|
// Any sort of variant is allowed if this is not an identifier.
|
||||||
(_, Identifier::No, false) => {}
|
(_, Identifier::No, false, _) => {}
|
||||||
|
|
||||||
// Unit variant without `other` attribute is always fine.
|
// Unit variant without `other` attribute is always fine.
|
||||||
(Style::Unit, _, false) => {}
|
(Style::Unit, _, false, _) => {}
|
||||||
|
|
||||||
// The last field is allowed to be a newtype catch-all.
|
// The last field is allowed to be a newtype catch-all.
|
||||||
(Style::Newtype, Identifier::Field, false) => {
|
(Style::Newtype, Identifier::Field, false, _) => {
|
||||||
if i < variants.len() - 1 {
|
if i < variants.len() - 1 {
|
||||||
cx.error(format!("`{}` must be the last variant", variant.ident));
|
cx.error(format!("`{}` must be the last variant", variant.ident));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(_, Identifier::Field, false) => {
|
(_, Identifier::Field, false, _) => {
|
||||||
cx.error("field_identifier may only contain unit variants");
|
cx.error("field_identifier may only contain unit variants");
|
||||||
}
|
}
|
||||||
|
|
||||||
(_, Identifier::Variant, false) => {
|
(_, Identifier::Variant, false, _) => {
|
||||||
cx.error("variant_identifier may only contain unit variants");
|
cx.error("variant_identifier may only contain unit variants");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,18 +10,29 @@ use std::cell::RefCell;
|
|||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
/// A type to collect errors together and format them.
|
||||||
|
///
|
||||||
|
/// Dropping this object will cause a panic. It must be consumed using `check`.
|
||||||
|
///
|
||||||
|
/// References can be shared since this type uses run-time exclusive mut checking.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Ctxt {
|
pub struct Ctxt {
|
||||||
|
// The contents will be set to `None` during checking. This is so that checking can be
|
||||||
|
// enforced.
|
||||||
errors: RefCell<Option<Vec<String>>>,
|
errors: RefCell<Option<Vec<String>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ctxt {
|
impl Ctxt {
|
||||||
|
/// Create a new context object.
|
||||||
|
///
|
||||||
|
/// This object contains no errors, but will still trigger a panic if it is not `check`ed.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Ctxt {
|
Ctxt {
|
||||||
errors: RefCell::new(Some(Vec::new())),
|
errors: RefCell::new(Some(Vec::new())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add an error to the context object.
|
||||||
pub fn error<T: Display>(&self, msg: T) {
|
pub fn error<T: Display>(&self, msg: T) {
|
||||||
self.errors
|
self.errors
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
@@ -30,6 +41,7 @@ impl Ctxt {
|
|||||||
.push(msg.to_string());
|
.push(msg.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Consume this object, producing a formatted error string if there are errors.
|
||||||
pub fn check(self) -> Result<(), String> {
|
pub fn check(self) -> Result<(), String> {
|
||||||
let mut errors = self.errors.borrow_mut().take().unwrap();
|
let mut errors = self.errors.borrow_mut().take().unwrap();
|
||||||
match errors.len() {
|
match errors.len() {
|
||||||
|
|||||||
+14
-12
@@ -22,35 +22,37 @@
|
|||||||
//!
|
//!
|
||||||
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.78")]
|
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.80")]
|
||||||
|
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||||
// Whitelisted clippy lints
|
// Whitelisted clippy lints
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(
|
allow(
|
||||||
|
cyclomatic_complexity,
|
||||||
enum_variant_names,
|
enum_variant_names,
|
||||||
|
needless_pass_by_value,
|
||||||
redundant_field_names,
|
redundant_field_names,
|
||||||
too_many_arguments,
|
too_many_arguments,
|
||||||
used_underscore_binding,
|
used_underscore_binding,
|
||||||
cyclomatic_complexity,
|
|
||||||
needless_pass_by_value
|
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
// Whitelisted clippy_pedantic lints
|
// Whitelisted clippy_pedantic lints
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(
|
allow(
|
||||||
items_after_statements,
|
|
||||||
doc_markdown,
|
|
||||||
stutter,
|
|
||||||
similar_names,
|
|
||||||
use_self,
|
|
||||||
single_match_else,
|
|
||||||
enum_glob_use,
|
|
||||||
match_same_arms,
|
|
||||||
filter_map,
|
|
||||||
cast_possible_truncation,
|
cast_possible_truncation,
|
||||||
|
doc_markdown,
|
||||||
|
enum_glob_use,
|
||||||
|
filter_map,
|
||||||
indexing_slicing,
|
indexing_slicing,
|
||||||
|
items_after_statements,
|
||||||
|
match_same_arms,
|
||||||
|
similar_names,
|
||||||
|
single_match_else,
|
||||||
|
stutter,
|
||||||
|
unseparated_literal_suffix,
|
||||||
|
use_self,
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
// The `quote!` macro requires deep recursion.
|
// The `quote!` macro requires deep recursion.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.23.1")]
|
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.23.1")]
|
||||||
|
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(
|
allow(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_test"
|
name = "serde_test"
|
||||||
version = "1.0.78" # remember to update html_root_url
|
version = "1.0.80" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Token De/Serializer for testing De/Serialize implementations"
|
description = "Token De/Serializer for testing De/Serialize implementations"
|
||||||
|
|||||||
@@ -161,7 +161,8 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.78")]
|
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.80")]
|
||||||
|
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||||
// Whitelisted clippy lints
|
// Whitelisted clippy lints
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
|
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ unstable = ["serde/unstable", "compiletest_rs"]
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
proc-macro2 = "0.4"
|
|
||||||
rustc-serialize = "0.3.16"
|
rustc-serialize = "0.3.16"
|
||||||
serde = { path = "../serde", features = ["rc"] }
|
serde = { path = "../serde", features = ["rc"] }
|
||||||
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
|
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![feature(lang_items, start, panic_handler)]
|
#![feature(lang_items, start)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
// Copyright 2017 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.
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
enum F {
|
|
||||||
A,
|
|
||||||
#[serde(other)]
|
|
||||||
//~^^^^ ERROR: #[serde(other)] may only be used inside a field_identifier
|
|
||||||
B,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
|
||||||
@@ -6,13 +6,14 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
|
#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
use self::serde::de::{self, Visitor, MapAccess, Unexpected};
|
use self::serde::de::{self, MapAccess, Unexpected, Visitor};
|
||||||
use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
@@ -2360,9 +2361,7 @@ fn test_flatten_any_after_flatten_struct() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let s = Outer {
|
let s = Outer {
|
||||||
inner: Inner {
|
inner: Inner { inner: 0 },
|
||||||
inner: 0,
|
|
||||||
},
|
|
||||||
extra: Any,
|
extra: Any,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(decimal_literal_representation)
|
allow(decimal_literal_representation)
|
||||||
@@ -135,6 +136,13 @@ enum EnumSkipAll {
|
|||||||
Skipped,
|
Skipped,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, Deserialize)]
|
||||||
|
enum EnumOther {
|
||||||
|
Unit,
|
||||||
|
#[serde(other)]
|
||||||
|
Other,
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
macro_rules! declare_tests {
|
macro_rules! declare_tests {
|
||||||
@@ -264,7 +272,7 @@ declare_tests! {
|
|||||||
0f32 => &[Token::F32(0.)],
|
0f32 => &[Token::F32(0.)],
|
||||||
0f64 => &[Token::F64(0.)],
|
0f64 => &[Token::F64(0.)],
|
||||||
}
|
}
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))]
|
||||||
test_small_int_to_128 {
|
test_small_int_to_128 {
|
||||||
1i128 => &[Token::I8(1)],
|
1i128 => &[Token::I8(1)],
|
||||||
1i128 => &[Token::I16(1)],
|
1i128 => &[Token::I16(1)],
|
||||||
@@ -753,6 +761,20 @@ declare_tests! {
|
|||||||
Token::Unit,
|
Token::Unit,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_enum_other_unit {
|
||||||
|
EnumOther::Unit => &[
|
||||||
|
Token::Enum { name: "EnumOther" },
|
||||||
|
Token::Str("Unit"),
|
||||||
|
Token::Unit,
|
||||||
|
],
|
||||||
|
}
|
||||||
|
test_enum_other {
|
||||||
|
EnumOther::Other => &[
|
||||||
|
Token::Enum { name: "EnumOther" },
|
||||||
|
Token::Str("Foo"),
|
||||||
|
Token::Unit,
|
||||||
|
],
|
||||||
|
}
|
||||||
test_box {
|
test_box {
|
||||||
Box::new(0i32) => &[Token::I32(0)],
|
Box::new(0i32) => &[Token::I32(0)],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![deny(trivial_numeric_casts)]
|
#![deny(trivial_numeric_casts)]
|
||||||
|
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(redundant_field_names))]
|
#![cfg_attr(feature = "cargo-clippy", allow(redundant_field_names))]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(redundant_field_names))]
|
#![cfg_attr(feature = "cargo-clippy", allow(redundant_field_names))]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|||||||
@@ -618,7 +618,7 @@ fn test_enum_skipped() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_integer128() {
|
fn test_integer128() {
|
||||||
assert_ser_tokens_error(&1i128, &[], "i128 is not supported");
|
assert_ser_tokens_error(&1i128, &[], "i128 is not supported");
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ fn test_u32_to_enum() {
|
|||||||
assert_eq!(E::B, e);
|
assert_eq!(E::B, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_integer128() {
|
fn test_integer128() {
|
||||||
let de_u128 = IntoDeserializer::<value::Error>::into_deserializer(1u128);
|
let de_u128 = IntoDeserializer::<value::Error>::into_deserializer(1u128);
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
|
|
||||||
channel() {
|
|
||||||
if [ -n "${TRAVIS}" ]; then
|
|
||||||
if [ "${TRAVIS_RUST_VERSION}" = "${CHANNEL}" ]; then
|
|
||||||
pwd
|
|
||||||
(set -x; cargo "$@")
|
|
||||||
fi
|
|
||||||
elif [ -n "${APPVEYOR}" ]; then
|
|
||||||
if [ "${APPVEYOR_RUST_CHANNEL}" = "${CHANNEL}" ]; then
|
|
||||||
pwd
|
|
||||||
(set -x; cargo "$@")
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
pwd
|
|
||||||
(set -x; cargo "+${CHANNEL}" "$@")
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -n "${CLIPPY}" ]; then
|
|
||||||
# cached installation will not work on a later nightly
|
|
||||||
if [ -n "${TRAVIS}" ] && ! cargo install clippy --debug --force; then
|
|
||||||
echo "COULD NOT COMPILE CLIPPY, IGNORING CLIPPY TESTS"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd "$DIR/serde"
|
|
||||||
cargo clippy --features 'rc unstable' -- -Dclippy
|
|
||||||
|
|
||||||
cd "$DIR/serde_derive"
|
|
||||||
cargo clippy -- -Dclippy
|
|
||||||
|
|
||||||
cd "$DIR/serde_test"
|
|
||||||
cargo clippy -- -Dclippy
|
|
||||||
|
|
||||||
cd "$DIR/test_suite"
|
|
||||||
cargo clippy --features unstable -- -Dclippy
|
|
||||||
|
|
||||||
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"
|
|
||||||
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 'rc alloc'
|
|
||||||
channel test --features 'rc unstable'
|
|
||||||
cd "$DIR/test_suite/deps"
|
|
||||||
channel build
|
|
||||||
cd "$DIR/test_suite"
|
|
||||||
channel test --features unstable
|
|
||||||
channel build --tests --features proc-macro2/nightly
|
|
||||||
if [ -z "${APPVEYOR}" ]; then
|
|
||||||
cd "$DIR/test_suite/no_std"
|
|
||||||
channel build
|
|
||||||
fi
|
|
||||||
|
|
||||||
CHANNEL=beta
|
|
||||||
cd "$DIR"
|
|
||||||
cargo clean
|
|
||||||
cd "$DIR/serde"
|
|
||||||
channel build --features rc
|
|
||||||
cd "$DIR/test_suite"
|
|
||||||
channel test
|
|
||||||
|
|
||||||
CHANNEL=stable
|
|
||||||
cd "$DIR"
|
|
||||||
cargo clean
|
|
||||||
cd "$DIR/serde"
|
|
||||||
channel build --features rc
|
|
||||||
channel build --no-default-features
|
|
||||||
cd "$DIR/serde_test"
|
|
||||||
channel build
|
|
||||||
channel test
|
|
||||||
|
|
||||||
CHANNEL=1.13.0
|
|
||||||
cd "$DIR"
|
|
||||||
cargo clean
|
|
||||||
cd "$DIR/serde"
|
|
||||||
channel build --features rc
|
|
||||||
channel build --no-default-features
|
|
||||||
cd "$DIR/serde_test"
|
|
||||||
channel build
|
|
||||||
|
|
||||||
CHANNEL=1.15.0
|
|
||||||
cd "$DIR"
|
|
||||||
cargo clean
|
|
||||||
cd "$DIR/serde_derive"
|
|
||||||
channel build
|
|
||||||
|
|
||||||
for CHANNEL in 1.20.0 1.21.0 1.25.0 1.26.0; do
|
|
||||||
cd "$DIR"
|
|
||||||
cargo clean
|
|
||||||
cd "$DIR/serde"
|
|
||||||
channel build --no-default-features
|
|
||||||
channel build
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
Reference in New Issue
Block a user