Compare commits

...

53 Commits

Author SHA1 Message Date
David Tolnay fa51083a12 Merge pull request #446 from serde-rs/unstable
Rename feature nightly-testing to unstable-testing
2016-07-17 18:26:20 -07:00
David Tolnay aaca4f06c6 Release 0.8.0-rc2 2016-07-17 18:07:40 -07:00
David Tolnay cc8a5a79ab See whether relative paths help cargo find the unstable-testing feature 2016-07-17 13:40:39 -07:00
David Tolnay 4f79829849 Rename feature nightly-testing to unstable-testing 2016-07-17 13:34:23 -07:00
David Tolnay 6c18896cf5 Unpin the clippy dependency 2016-07-17 13:32:40 -07:00
David Tolnay ac738632ef Merge pull request #445 from serde-rs/pubdep
Remove public dependency on Syntex
2016-07-17 13:15:42 -07:00
David Tolnay 8d06f36d71 Remove public dependency on Syntex 2016-07-17 13:00:39 -07:00
David Tolnay e404de85b2 Remove serde-syntex-example from travis until serde_json 0.8.0 2016-07-17 12:59:04 -07:00
David Tolnay 6fe01bc8e3 Release 0.8.0-rc1
This prerelease contains the Serializer API changes intended for 0.8.0. It
allows us to start merging PRs that use the new API.
2016-07-17 11:46:03 -07:00
David Tolnay 855f3d99bb Do not release any more 0.7 releases from master 2016-07-15 17:00:09 -07:00
David Tolnay 9d015a2942 Merge pull request #437 from oli-obk/map_seq_ser
Revamp Map/Seq serialization
2016-07-15 16:59:45 -07:00
Oliver Schneider 42c41922ce adjust tests for new interface 2016-07-15 12:59:30 +02:00
Oliver Schneider 984181c558 Merge remote-tracking branch 'serde/master' into map_seq_ser 2016-07-15 10:59:46 +02:00
David Tolnay ed603d4580 Merge pull request #442 from serde-rs/override
Use cargo override instead of relative paths
2016-07-15 01:56:14 -07:00
Oliver Schneider 70c83768b7 Merge pull request #1 from serde-rs/dtolnay/serializer
David's take on Serializer
2016-07-15 10:38:22 +02:00
David Tolnay 7220029055 Use cargo override instead of relative paths
This makes it possible to use `cargo clone` + `cargo build`.
2016-07-15 01:17:23 -07:00
David Tolnay 35676305da Merge pull request #401 from erickt/contributing
Add a contribution guide
2016-07-15 01:06:54 -07:00
David Tolnay fbad194042 Restore 'static requirement for names 2016-07-15 00:59:56 -07:00
David Tolnay 2e4cc0b443 Restore serialize_seq_fixed_size 2016-07-15 00:58:48 -07:00
David Tolnay 9217517532 Update impls 2016-07-15 00:55:38 -07:00
David Tolnay 0feeb7a341 David's take on Serializer 2016-07-15 00:01:31 -07:00
Oliver Schneider 2901344722 this time really fix ranges 2016-07-14 16:16:20 +02:00
Oliver Schneider 54c80ad677 fix range serialization 2016-07-14 15:37:05 +02:00
Oliver Schneider 16ba32dbe1 stateful map/seq serialization 2016-07-14 15:36:47 +02:00
Oliver Schneider 60938913b2 face -> palm 2016-07-13 19:18:01 +02:00
Oliver Schneider 26528fbbb4 silence lint about a: ref a patterns 2016-07-12 16:53:38 +02:00
Oliver Schneider 6adcaa55e5 json needs more info 2016-07-12 16:53:20 +02:00
Oliver Schneider fb575225bc simplify! 2016-07-12 16:16:48 +02:00
Oliver Schneider ee4e7413b0 whoops 2016-07-12 15:50:41 +02:00
Oliver Schneider a6f8bd5aac nightly 2016-07-12 15:49:41 +02:00
Oliver Schneider 3766633f4a adjust codegen to work with the revamped map/seq serializer 2016-07-12 15:44:19 +02:00
Dawid Ciężarkiewicz 99038b044e Eliminate Visitor pattern
Visitor is "pull", while `MapSerializer` and `SeqSerializer`
are "push" like the rest of the API.
2016-07-12 11:46:44 +02:00
David Tolnay 4ec0a7e672 Merge pull request #433 from softprops/add_envy
add envy
2016-07-10 20:59:50 -07:00
softprops a41dae45a5 add envy 2016-07-10 23:55:32 -04:00
David Tolnay cb9e1cfb54 Merge pull request #431 from serde-rs/version
Drop support for 1.7.0
2016-07-10 14:40:15 -07:00
David Tolnay 54ce7f2e90 Drop support for 1.7.0 2016-07-10 14:25:17 -07:00
David Tolnay ddbd139793 Merge pull request #430 from serde-rs/bump
Update syntex to 0.38
2016-07-09 11:51:38 -07:00
David Tolnay a070de28e2 Update syntex to 0.38 2016-07-09 11:37:01 -07:00
David Tolnay 57aeb26728 Merge pull request #428 from erickt/readme
Rewrite readme to front-load stable rust usage
2016-07-07 20:26:00 -07:00
Erick Tryzelaar a592828808 Rewrite readme to front-load stable rust usage 2016-07-07 14:31:24 -07:00
David Tolnay 67d86dcc4f Merge pull request #426 from serde-rs/display
impl Display for de::Type
2016-07-07 00:59:17 -07:00
David Tolnay 15764cb955 impl Display for de::Type 2016-07-06 23:33:59 -07:00
David Tolnay 97bc1e08e7 Release 0.7.13 2016-07-05 20:06:10 -07:00
Oliver Schneider 7ffb74f5bb Merge pull request #423 from dtolnay/seq
Close the seq before failing on invalid length
2016-07-05 22:44:52 +02:00
David Tolnay f25e6d3ea9 Close the seq before failing on invalid length
Equivalent to what 0f9a930 does for maps.
2016-07-05 10:08:36 -07:00
David Tolnay 431cbe48b7 Merge pull request #422 from serde-rs/missing
Close the map before checking for missing fields
2016-07-05 07:11:03 -07:00
Homu 5405ab319d Auto merge of #421 - serde-rs:length, r=oli-obk
Invalid-length when enum seq is too short

Fixes https://github.com/serde-rs/json/issues/96.
2016-07-05 18:27:33 +09:00
David Tolnay 0f9a930c4f Close the map before checking for missing fields 2016-07-05 01:42:38 -07:00
David Tolnay 1a449bb3d0 Invalid-length when enum seq is too short 2016-07-05 01:35:20 -07:00
David Tolnay c0e8164792 Merge pull request #418 from serde-rs/expninfo
Record expansion info
2016-07-04 15:22:09 -07:00
David Tolnay a3a7e4085f Add run-pass test for expansion info 2016-07-04 15:02:15 -07:00
David Tolnay 149c87d7c2 Record expansion info 2016-07-03 10:53:33 -07:00
Erick Tryzelaar 18e077eda9 Add a contributing guide 2016-06-22 07:04:13 -07:00
38 changed files with 1209 additions and 1201 deletions
+7
View File
@@ -0,0 +1,7 @@
paths = [
"serde",
"serde_codegen",
"serde_codegen_internals",
"serde_macros",
"serde_test",
]
+7 -7
View File
@@ -2,10 +2,10 @@ sudo: false
language: rust
rust:
- stable
- beta
- nightly
- 1.7.0
- 1.8.0
- 1.9.0
- beta
addons:
apt:
packages:
@@ -18,15 +18,15 @@ before_script:
script:
- (cd serde && travis-cargo build)
- (cd serde && travis-cargo --skip nightly test)
- (cd serde && travis-cargo --only nightly test -- --features nightly-testing)
- (cd serde && travis-cargo --only nightly test -- --features unstable-testing)
- (cd serde && travis-cargo build -- --no-default-features)
- (cd serde && travis-cargo --only nightly build -- --no-default-features --features alloc)
- (cd serde && travis-cargo --only nightly build -- --no-default-features --features collections)
- (cd testing && travis-cargo --skip nightly test)
- (cd testing && travis-cargo --only nightly test -- --features nightly-testing)
- (cd serde_macros && travis-cargo --only nightly test -- --features nightly-testing)
- (cd examples/serde-syntex-example && travis-cargo --skip nightly run)
- (cd examples/serde-syntex-example && travis-cargo --only nightly run -- --no-default-features --features nightly)
- (cd testing && travis-cargo --only nightly test -- --features unstable-testing)
- (cd serde_macros && travis-cargo --only nightly test -- --features unstable-testing)
#- (cd examples/serde-syntex-example && travis-cargo --skip nightly run)
#- (cd examples/serde-syntex-example && travis-cargo --only nightly run -- --no-default-features --features unstable)
- (cd serde && travis-cargo --only stable doc)
after_success:
- (cd serde && travis-cargo --only stable doc-upload)
+45
View File
@@ -0,0 +1,45 @@
# Contributing to Serde
Serde welcomes contribution from everyone. Here are the guidelines if you are
thinking of helping us:
## Contributions
Contributions to Serde or its dependencies should be made in the form of GitHub
pull requests. Each pull request will be reviewed by a core contributor
(someone with permission to land patches) and either landed in the main tree or
given feedback for changes that would be required. All contributions should
follow this format, even those from core contributors.
Should you wish to work on an issue, please claim it first by commenting on
the GitHub issue that you want to work on it. This is to prevent duplicated
efforts from contributors on the same issue.
## Pull Request Checklist
- Branch from the master branch and, if needed, rebase to the current master
branch before submitting your pull request. If it doesn't merge cleanly with
master you may be asked to rebase your changes.
- Commits should be as small as possible, while ensuring that each commit is
correct independently (i.e., each commit should compile and pass tests).
- If your patch is not getting reviewed or you need a specific person to review
it, you can @-reply a reviewer asking for a review in the pull request or a
comment, or you can ask for a review in `#serde` on `irc.mozilla.org`.
- Add tests relevant to the fixed bug or new feature.
## Conduct
In all Serde-related forums, we follow the [Rust Code of
Conduct](https://www.rust-lang.org/conduct.html). For escalation or moderation
issues, please contact Erick (erick.tryzelaar@gmail.com) instead of the Rust
moderation team.
## Communication
Beyond opening tickets on the
[serde-rs/serde](https://github.com/serde-rs/serde) project, Serde contributors
frequent the `#serde` channel on
[`irc.mozilla.org`](https://wiki.mozilla.org/IRC).
+138 -53
View File
@@ -12,74 +12,100 @@ information. In many situations, the handshake protocol between serializers and
serializees can be completely optimized away, leaving Serde to perform roughly
the same speed as a hand written serializer for a specific type.
Documentation is available at:
[Documentation](https://serde-rs.github.io/serde/serde/index.html)
* [serde](https://serde-rs.github.io/serde/serde/index.html)
Simple Serde Example
====================
Using Serde with Nightly Rust and serde\_macros
===============================================
Here is a simple example that demonstrates how to use Serde by serializing and
deserializing to JSON. Serde comes with some powerful code generation libraries
that work with Stable and Nightly Rust that eliminate much of the complexity of
hand rolling serialization and deserialization for a given type. First lets see
how we would use Nightly Rust, which is currently a bit simpler than Stable
Rust:
`Cargo.toml`:
Here is a simple example that uses
[serde_json](https://github.com/serde-rs/json), which uses Serde under the
covers, to generate and parse JSON. First, lets start off with the `Cargo.toml`
file:
```toml
[package]
name = "serde_example_nightly"
name = "serde_example"
version = "0.1.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
[dependencies]
serde = "*"
serde_json = "*"
serde_macros = "*"
```
`src/main.rs`
```rust
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
Next, the `src/main.rs` file itself:
```rust,ignore
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
use std::collections::HashMap;
use serde_json::Value;
use serde_json::builder::{ArrayBuilder, ObjectBuilder};
fn main() {
let point = Point { x: 1, y: 2 };
let serialized = serde_json::to_string(&point).unwrap();
// Serde has support for many of the builtin Rust types, like arrays..:
let v = vec![1, 2];
let serialized = serde_json::to_string(&v).unwrap();
println!("serialized vec: {:?}", serialized);
println!("{}", serialized);
let deserialized: Vec<u32> = serde_json::from_str(&serialized).unwrap();
println!("deserialized vec: {:?}", deserialized);
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
// ... and maps:
let mut map = HashMap::new();
map.insert("x".to_string(), 1);
map.insert("y".to_string(), 2);
println!("{:?}", deserialized);
let serialized = serde_json::to_string(&map).unwrap();
println!("serialized map: {:?}", serialized);
let deserialized: HashMap<String, u32> = serde_json::from_str(&serialized).unwrap();
println!("deserialized map: {:?}", deserialized);
// It also can handle complex objects:
let value = ObjectBuilder::new()
.insert("int", 1)
.insert("string", "a string")
.insert("array", ArrayBuilder::new()
.push(1)
.push(2)
.unwrap())
.unwrap();
let serialized = serde_json::to_string(&value).unwrap();
println!("serialized value: {:?}", serialized);
let deserialized: serde_json::Value = serde_json::from_str(&serialized).unwrap();
println!("deserialized value: {:?}", deserialized);
}
```
When run, it produces:
This produces the following output when run:
```
% cargo run
{"x":1,"y":2}
Point { x: 1, y: 2 }
serialized vec: "[1,2]"
deserialized vec: [1, 2]
serialized map: "{\"y\":2,\"x\":1}"
deserialized map: {"y": 2, "x": 1}
serialized value: "{\"array\":[1,2],\"int\":1,\"string\":\"a string\"}"
deserialized value: {"array":[1,2],"int":1,"string":"a string"}
```
Using Serde with Stable Rust and serde\_codegen
===============================================
Stable Rust is a little more complicated because it does not yet support
compiler plugins. Instead we need to use `serde_codegen` which is based on the
code generation library [syntex](https://github.com/serde-rs/syntex):
The example before used `serde_json::Value` as the in-memory representation of
the JSON value, but it's also possible for Serde to serialize to and from
regular Rust types. However, the code to do this can be a bit complicated to
write. So instead, Serde also has some powerful code generation libraries that
work with Stable and Nightly Rust that eliminate much of the complexity of hand
rolling serialization and deserialization for a given type.
First lets see how we would use Stable Rust, which is currently a tad more
complicated than Nightly Rust due to having to work around compiler plugins
being unstable. We will use `serde_codegen` which is based on the code
generation library [syntex](https://github.com/serde-rs/syntex). First we need
to setup the `Cargo.toml` that builds the project:
```toml
[package]
@@ -96,16 +122,8 @@ serde = "*"
serde_json = "*"
```
`src/main.rs`:
```rust,ignore
extern crate serde;
extern crate serde_json;
include!(concat!(env!("OUT_DIR"), "/main.rs"));
```
`src/main.rs.in`:
Next, we define our source file, `src/main.rs.in`. Note this is a different
extension than usual becaues we need to do code generation:
```rust,ignore
#[derive(Serialize, Deserialize, Debug)]
@@ -116,17 +134,28 @@ struct Point {
fn main() {
let point = Point { x: 1, y: 2 };
let serialized = serde_json::to_string(&point).unwrap();
let serialized = serde_json::to_string(&point).unwrap();
println!("{}", serialized);
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
println!("{:?}", deserialized);
}
```
`build.rs`
To finish up the main source code, we define a very simple `src/main.rs` that
uses the generated code.
`src/main.rs`:
```rust,ignore
extern crate serde;
extern crate serde_json;
include!(concat!(env!("OUT_DIR"), "/main.rs"));
```
The last step is to actually drive the code generation, with the `build.rs` script:
```rust,ignore
extern crate serde_codegen;
@@ -144,7 +173,7 @@ pub fn main() {
}
```
This also produces:
All this produces this when run:
```
% cargo run
@@ -153,8 +182,63 @@ Point { x: 1, y: 2 }
```
While this works well with Stable Rust, be aware that the error locations
currently are reported in the generated file instead of in the source file. You
may find it easier to develop with Nightly Rust and `serde\_macros`, then
currently are reported in the generated file instead of in the source file.
Using Serde with Nightly Rust and serde\_macros
===============================================
The prior example is a bit more complicated than it needs to be due to compiler
plugins being unstable. However, if you are already using Nightly Rust, you can
use `serde_macros`, which has a much simpler interface. First, here is the new
`Cargo.toml`:
```toml
[package]
name = "serde_example_nightly"
version = "0.1.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
[dependencies]
serde = "*"
serde_json = "*"
serde_macros = "*"
```
Note that it doesn't need a build script. Now the `src/main.rs`, which enables
the plugin feature, and registers the `serde_macros` plugin:
```rust
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
let serialized = serde_json::to_string(&point).unwrap();
println!("{}", serialized);
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
println!("{:?}", deserialized);
}
```
This also produces the same output:
```
% cargo run
{"x":1,"y":2}
Point { x: 1, y: 2 }
```
You may find it easier to develop with Nightly Rust and `serde\_macros`, then
deploy with Stable Rust and `serde_codegen`. It's possible to combine both
approaches in one setup:
@@ -740,6 +824,7 @@ Serialization Formats Using Serde
| Format | Name |
| ------ | ---- |
| Bincode | [bincode](https://crates.io/crates/bincode) |
| env vars | [envy](https://crates.io/crates/envy) |
| JSON | [serde\_json](https://crates.io/crates/serde_json) |
| MessagePack | [rmp](https://crates.io/crates/rmp) |
| XML | [serde\_xml](https://github.com/serde-rs/xml) |
-5
View File
@@ -1,5 +0,0 @@
paths = [
"../serde",
"../serde_codegen",
"../serde_macros",
]
+5 -5
View File
@@ -6,12 +6,12 @@ build = "build.rs"
[features]
default = ["serde_codegen"]
nightly = ["serde_macros"]
unstable = ["serde_macros"]
[build-dependencies]
serde_codegen = { version = "^0.7.12", optional = true }
serde_codegen = { version = "^0.7", optional = true }
[dependencies]
serde = "^0.7.12"
serde_json = "^0.7.0"
serde_macros = { version = "^0.7.12", optional = true }
serde = "^0.7"
serde_json = "^0.7"
serde_macros = { version = "^0.7", optional = true }
+6 -4
View File
@@ -1,6 +1,8 @@
[package]
name = "serde"
version = "0.7.12"
# DO NOT RELEASE ANY MORE 0.7 RELEASES FROM THIS BRANCH
# USE THE 0.7.x BRANCH
version = "0.8.0-rc2"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
@@ -14,10 +16,10 @@ include = ["Cargo.toml", "src/**/*.rs"]
default = ["std"]
std = []
nightly = []
alloc = ["nightly"]
unstable = []
alloc = ["unstable"]
collections = ["alloc"]
nightly-testing = ["clippy", "nightly", "std"]
unstable-testing = ["clippy", "unstable", "std"]
[dependencies]
clippy = { version = "^0.*", optional = true }
+11 -11
View File
@@ -2,7 +2,7 @@
#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(all(feature = "nightly", feature = "collections", not(feature = "std")))]
#[cfg(all(feature = "unstable", feature = "collections", not(feature = "std")))]
use collections::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))]
@@ -27,9 +27,9 @@ use std::collections::{
VecDeque,
};
#[cfg(all(feature = "nightly", feature = "collections"))]
#[cfg(all(feature = "unstable", feature = "collections"))]
use collections::enum_set::{CLike, EnumSet};
#[cfg(all(feature = "nightly", feature = "collections"))]
#[cfg(all(feature = "unstable", feature = "collections"))]
use collections::borrow::ToOwned;
use core::hash::{Hash, BuildHasher};
@@ -42,21 +42,21 @@ use core::str;
#[cfg(feature = "std")]
use std::rc::Rc;
#[cfg(all(feature = "nightly", feature = "alloc", not(feature = "std")))]
#[cfg(all(feature = "unstable", feature = "alloc", not(feature = "std")))]
use alloc::rc::Rc;
#[cfg(feature = "std")]
use std::sync::Arc;
#[cfg(all(feature = "nightly", feature = "alloc", not(feature = "std")))]
#[cfg(all(feature = "unstable", feature = "alloc", not(feature = "std")))]
use alloc::arc::Arc;
#[cfg(all(feature = "nightly", feature = "alloc", not(feature = "std")))]
#[cfg(all(feature = "unstable", feature = "alloc", not(feature = "std")))]
use alloc::boxed::Box;
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
use core::nonzero::{NonZero, Zeroable};
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
use core::num::Zero;
use de::{
@@ -461,7 +461,7 @@ seq_impl!(
BTreeSet::new(),
BTreeSet::insert);
#[cfg(all(feature = "nightly", feature = "collections"))]
#[cfg(all(feature = "unstable", feature = "collections"))]
seq_impl!(
EnumSet<T>,
EnumSetVisitor<T: Deserialize + CLike>,
@@ -806,7 +806,7 @@ map_impl!(
///////////////////////////////////////////////////////////////////////////////
#[cfg(all(feature = "nightly", feature = "std"))]
#[cfg(all(feature = "unstable", feature = "std"))]
impl Deserialize for net::IpAddr {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer,
@@ -972,7 +972,7 @@ impl<'a, T: ?Sized> Deserialize for Cow<'a, T> where T: ToOwned, T::Owned: Deser
///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
impl<T> Deserialize for NonZero<T> where T: Deserialize + PartialEq + Zeroable + Zero {
fn deserialize<D>(deserializer: &mut D) -> Result<NonZero<T>, D::Error> where D: Deserializer {
let value = try!(Deserialize::deserialize(deserializer));
+42
View File
@@ -8,6 +8,8 @@ use error;
#[cfg(all(not(feature = "std"), feature = "collections"))]
use collections::{String, Vec};
use core::fmt;
pub mod impls;
pub mod value;
mod from_primitive;
@@ -169,6 +171,46 @@ pub enum Type {
Bytes,
}
impl fmt::Display for Type {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let display = match *self {
Type::Bool => "bool",
Type::Usize => "usize",
Type::U8 => "u8",
Type::U16 => "u16",
Type::U32 => "u32",
Type::U64 => "u64",
Type::Isize => "isize",
Type::I8 => "i8",
Type::I16 => "i16",
Type::I32 => "i32",
Type::I64 => "i64",
Type::F32 => "f32",
Type::F64 => "f64",
Type::Char => "char",
Type::Str => "str",
Type::String => "string",
Type::Unit => "unit",
Type::Option => "option",
Type::Seq => "seq",
Type::Map => "map",
Type::UnitStruct => "unit struct",
Type::NewtypeStruct => "newtype struct",
Type::TupleStruct => "tuple struct",
Type::Struct => "struct",
Type::FieldName => "field name",
Type::Tuple => "tuple",
Type::Enum => "enum",
Type::VariantName => "variant name",
Type::StructVariant => "struct variant",
Type::TupleVariant => "tuple variant",
Type::UnitVariant => "unit variant",
Type::Bytes => "bytes",
};
display.fmt(formatter)
}
}
///////////////////////////////////////////////////////////////////////////////
/// `Deserialize` represents a type that can be deserialized.
+1 -1
View File
@@ -25,7 +25,7 @@ use collections::{
vec,
};
#[cfg(all(feature = "nightly", feature = "collections"))]
#[cfg(all(feature = "unstable", feature = "collections"))]
use collections::borrow::ToOwned;
use core::hash::Hash;
+2 -2
View File
@@ -4,7 +4,7 @@ use core::fmt::{Debug, Display};
/// A stand-in for `std::error::Error`, which requires no allocation.
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
pub trait Error: Debug + Display + ::core::marker::Reflect {
/// A short description of the error.
///
@@ -24,7 +24,7 @@ pub trait Error: Debug + Display + ::core::marker::Reflect {
}
/// A stand-in for `std::error::Error`, which requires no allocation.
#[cfg(not(feature = "nightly"))]
#[cfg(not(feature = "unstable"))]
pub trait Error: Debug + Display {
/// A short description of the error.
///
+8 -8
View File
@@ -11,29 +11,29 @@
#![doc(html_root_url="https://serde-rs.github.io/serde/serde")]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "nightly", feature(reflect_marker, unicode, nonzero, plugin, step_trait, zero_one))]
#![cfg_attr(feature = "unstable", feature(reflect_marker, unicode, nonzero, plugin, step_trait, zero_one))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "collections", feature(collections, enumset))]
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
#![cfg_attr(feature = "nightly-testing", allow(linkedlist))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", allow(linkedlist))]
#![cfg_attr(any(not(feature = "std"), feature = "nightly"), allow(unused_variables, unused_imports, unused_features, dead_code))]
#![cfg_attr(any(not(feature = "std"), feature = "unstable"), allow(unused_variables, unused_imports, unused_features, dead_code))]
#![deny(missing_docs)]
#[cfg(all(feature = "nightly", feature = "collections"))]
#[cfg(all(feature = "unstable", feature = "collections"))]
extern crate collections;
#[cfg(all(feature = "nightly", feature = "alloc"))]
#[cfg(all(feature = "unstable", feature = "alloc"))]
extern crate alloc;
#[cfg(feature = "std")]
mod core {
pub use std::{ops, hash, fmt, cmp, marker, mem, i8, i16, i32, i64, u8, u16, u32, u64, isize,
usize, f32, f64, char, str, num, slice, iter};
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
extern crate core;
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
pub use self::core::nonzero;
}
+75 -264
View File
@@ -26,19 +26,19 @@ use collections::{
Vec,
};
#[cfg(all(feature = "nightly", feature = "collections"))]
#[cfg(all(feature = "unstable", feature = "collections"))]
use collections::enum_set::{CLike, EnumSet};
#[cfg(all(feature = "nightly", feature = "collections"))]
#[cfg(all(feature = "unstable", feature = "collections"))]
use collections::borrow::ToOwned;
use core::hash::{Hash, BuildHasher};
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
use core::iter;
#[cfg(feature = "std")]
use std::net;
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
use core::num;
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
use core::ops;
#[cfg(feature = "std")]
use std::path;
@@ -57,15 +57,13 @@ use alloc::boxed::Box;
use core::marker::PhantomData;
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
use core::nonzero::{NonZero, Zeroable};
use super::{
Error,
Serialize,
Serializer,
SeqVisitor,
MapVisitor,
};
///////////////////////////////////////////////////////////////////////////////
@@ -133,26 +131,6 @@ impl<T> Serialize for Option<T> where T: Serialize {
}
}
impl<T> SeqVisitor for Option<T> where T: Serialize {
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.take() {
Some(value) => {
try!(serializer.serialize_seq_elt(value));
Ok(Some(()))
}
None => Ok(None),
}
}
#[inline]
fn len(&self) -> Option<usize> {
Some(if self.is_some() { 1 } else { 0 })
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for PhantomData<T> {
@@ -164,69 +142,6 @@ impl<T> Serialize for PhantomData<T> {
}
}
///////////////////////////////////////////////////////////////////////////////
/// A `serde::Visitor` for sequence iterators.
///
/// # Examples
///
/// ```
/// use serde::{Serialize, Serializer};
/// use serde::ser::impls::SeqIteratorVisitor;
///
/// struct Seq(Vec<u32>);
///
/// impl Serialize for Seq {
/// fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
/// where S: Serializer,
/// {
/// ser.serialize_seq(SeqIteratorVisitor::new(
/// self.0.iter(),
/// Some(self.0.len()),
/// ))
/// }
/// }
/// ```
pub struct SeqIteratorVisitor<Iter> {
iter: Iter,
len: Option<usize>,
}
impl<T, Iter> SeqIteratorVisitor<Iter>
where Iter: Iterator<Item=T>
{
/// Construct a new `SeqIteratorVisitor<Iter>`.
#[inline]
pub fn new(iter: Iter, len: Option<usize>) -> SeqIteratorVisitor<Iter> {
SeqIteratorVisitor {
iter: iter,
len: len,
}
}
}
impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
where T: Serialize,
Iter: Iterator<Item=T>,
{
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.iter.next() {
Some(value) => {
try!(serializer.serialize_seq_elt(value));
Ok(Some(()))
}
None => Ok(None),
}
}
#[inline]
fn len(&self) -> Option<usize> {
self.len
}
}
///////////////////////////////////////////////////////////////////////////////
@@ -237,7 +152,11 @@ impl<T> Serialize for [T]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
let mut state = try!(serializer.serialize_seq(Some(self.len())));
for e in self.iter() {
try!(serializer.serialize_seq_elt(&mut state, e));
}
serializer.serialize_seq_end(state)
}
}
@@ -250,8 +169,11 @@ macro_rules! array_impls {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
let visitor = SeqIteratorVisitor::new(self.iter(), Some($len));
serializer.serialize_fixed_size_array(visitor)
let mut state = try!(serializer.serialize_seq_fixed_size($len));
for e in self.iter() {
try!(serializer.serialize_seq_elt(&mut state, e));
}
serializer.serialize_seq_end(state)
}
}
}
@@ -293,40 +215,40 @@ array_impls!(32);
///////////////////////////////////////////////////////////////////////////////
macro_rules! serialize_seq {
() => {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
let mut state = try!(serializer.serialize_seq(Some(self.len())));
for e in self {
try!(serializer.serialize_seq_elt(&mut state, e));
}
serializer.serialize_seq_end(state)
}
}
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for BinaryHeap<T>
where T: Serialize + Ord
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
serialize_seq!();
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for BTreeSet<T>
where T: Serialize + Ord,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
serialize_seq!();
}
#[cfg(all(feature = "nightly", feature = "collections"))]
#[cfg(all(feature = "unstable", feature = "collections"))]
impl<T> Serialize for EnumSet<T>
where T: Serialize + CLike
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
serialize_seq!();
}
#[cfg(feature = "std")]
@@ -334,27 +256,27 @@ impl<T, H> Serialize for HashSet<T, H>
where T: Serialize + Eq + Hash,
H: BuildHasher,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
serialize_seq!();
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for LinkedList<T>
where T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
serialize_seq!();
}
#[cfg(feature = "nightly")]
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for Vec<T> where T: Serialize {
serialize_seq!();
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for VecDeque<T> where T: Serialize {
serialize_seq!();
}
#[cfg(feature = "unstable")]
impl<A> Serialize for ops::Range<A>
where A: Serialize + Clone + iter::Step + num::One,
for<'a> &'a A: ops::Add<&'a A, Output = A>,
@@ -364,27 +286,11 @@ impl<A> Serialize for ops::Range<A>
where S: Serializer,
{
let len = iter::Step::steps_between(&self.start, &self.end, &A::one());
serializer.serialize_seq(SeqIteratorVisitor::new(self.clone(), len))
}
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for Vec<T> where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(&self[..]).serialize(serializer)
}
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for VecDeque<T> where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
let mut state = try!(serializer.serialize_seq(len));
for e in self.clone() {
try!(serializer.serialize_seq_elt(&mut state, e));
}
serializer.serialize_seq_end(state)
}
}
@@ -413,52 +319,18 @@ macro_rules! tuple_impls {
}
)+) => {
$(
/// A tuple visitor.
pub struct $TupleVisitor<'a, $($T: 'a),+> {
tuple: &'a ($($T,)+),
state: u8,
}
impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> {
/// Construct a new, empty `TupleVisitor`.
pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> {
$TupleVisitor {
tuple: tuple,
state: 0,
}
}
}
impl<'a, $($T),+> SeqVisitor for $TupleVisitor<'a, $($T),+>
where $($T: Serialize),+
{
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.state {
$(
$state => {
self.state += 1;
Ok(Some(try!(serializer.serialize_tuple_elt(&e!(self.tuple.$idx)))))
}
)+
_ => {
Ok(None)
}
}
}
fn len(&self) -> Option<usize> {
Some($len)
}
}
impl<$($T),+> Serialize for ($($T,)+)
where $($T: Serialize),+
{
#[inline]
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
serializer.serialize_tuple($TupleVisitor::new(self))
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
let mut state = try!(serializer.serialize_tuple($len));
$(
try!(serializer.serialize_tuple_elt(&mut state, &e!(self.$idx)));
)+
serializer.serialize_tuple_end(state)
}
}
)+
@@ -638,83 +510,27 @@ tuple_impls! {
///////////////////////////////////////////////////////////////////////////////
/// A `serde::Visitor` for (key, value) map iterators.
///
/// # Examples
///
/// ```
/// use std::collections::HashMap;
/// use serde::{Serialize, Serializer};
/// use serde::ser::impls::MapIteratorVisitor;
///
/// struct Map(HashMap<u32, u32>);
///
/// impl Serialize for Map {
/// fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
/// where S: Serializer,
/// {
/// ser.serialize_map(MapIteratorVisitor::new(
/// self.0.iter(),
/// Some(self.0.len()),
/// ))
/// }
/// }
/// ```
pub struct MapIteratorVisitor<Iter> {
iter: Iter,
len: Option<usize>,
}
impl<K, V, Iter> MapIteratorVisitor<Iter>
where Iter: Iterator<Item=(K, V)>
{
/// Construct a new `MapIteratorVisitor<Iter>`.
#[inline]
pub fn new(iter: Iter, len: Option<usize>) -> MapIteratorVisitor<Iter> {
MapIteratorVisitor {
iter: iter,
len: len,
}
}
}
impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
where K: Serialize,
V: Serialize,
I: Iterator<Item=(K, V)>,
{
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.iter.next() {
Some((key, value)) => {
try!(serializer.serialize_map_elt(key, value));
Ok(Some(()))
macro_rules! serialize_map {
() => {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
let mut state = try!(serializer.serialize_map(Some(self.len())));
for (k, v) in self {
try!(serializer.serialize_map_elt(&mut state, k, v));
}
None => Ok(None)
serializer.serialize_map_end(state)
}
}
#[inline]
fn len(&self) -> Option<usize> {
self.len
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))]
impl<K, V> Serialize for BTreeMap<K, V>
where K: Serialize + Ord,
V: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.serialize_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
}
serialize_map!();
}
#[cfg(feature = "std")]
@@ -723,12 +539,7 @@ impl<K, V, H> Serialize for HashMap<K, V, H>
V: Serialize,
H: BuildHasher,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.serialize_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
}
serialize_map!();
}
///////////////////////////////////////////////////////////////////////////////
@@ -808,7 +619,7 @@ impl<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
///////////////////////////////////////////////////////////////////////////////
#[cfg(all(feature = "std", feature = "nightly"))]
#[cfg(all(feature = "std", feature = "unstable"))]
impl Serialize for net::IpAddr {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
@@ -893,7 +704,7 @@ impl Serialize for path::PathBuf {
}
}
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
impl<T> Serialize for NonZero<T> where T: Serialize + Zeroable {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
(**self).serialize(serializer)
+270 -286
View File
@@ -45,339 +45,323 @@ pub trait Serializer {
/// The error type that can be returned if some error occurs during serialization.
type Error: Error;
/// A state object that is initialized by `serialize_seq`, passed to
/// `serialize_seq_elt`, and consumed by `serialize_seq_end`. Use `()` if no
/// state is required.
type SeqState;
/// A state object that is initialized by `serialize_tuple`, passed to
/// `serialize_tuple_elt`, and consumed by `serialize_tuple_end`. Use `()`
/// if no state is required.
type TupleState;
/// A state object that is initialized by `serialize_tuple_struct`, passed
/// to `serialize_tuple_struct_elt`, and consumed by
/// `serialize_tuple_struct_end`. Use `()` if no state is required.
type TupleStructState;
/// A state object that is initialized by `serialize_tuple_variant`, passed
/// to `serialize_tuple_variant_elt`, and consumed by
/// `serialize_tuple_variant_end`. Use `()` if no state is required.
type TupleVariantState;
/// A state object that is initialized by `serialize_map`, passed to
/// `serialize_map_elt`, and consumed by `serialize_map_end`. Use `()` if no
/// state is required.
type MapState;
/// A state object that is initialized by `serialize_struct`, passed to
/// `serialize_struct_elt`, and consumed by `serialize_struct_end`. Use `()`
/// if no state is required.
type StructState;
/// A state object that is initialized by `serialize_struct_variant`, passed
/// to `serialize_struct_variant_elt`, and consumed by
/// `serialize_struct_variant_end`. Use `()` if no state is required.
type StructVariantState;
/// Serializes a `bool` value.
fn serialize_bool(&mut self, v: bool) -> Result<(), Self::Error>;
/// Serializes a `isize` value. By default it casts the value to a `i64` and
/// passes it to the `serialize_i64` method.
#[inline]
fn serialize_isize(&mut self, v: isize) -> Result<(), Self::Error> {
self.serialize_i64(v as i64)
}
/// Serializes an `isize` value. If the format does not differentiate
/// between `isize` and `i64`, a reasonable implementation would be to cast
/// the value to `i64` and forward to `serialize_i64`.
fn serialize_isize(&mut self, v: isize) -> Result<(), Self::Error>;
/// Serializes a `i8` value. By default it casts the value to a `i64` and
/// passes it to the `serialize_i64` method.
#[inline]
fn serialize_i8(&mut self, v: i8) -> Result<(), Self::Error> {
self.serialize_i64(v as i64)
}
/// Serializes an `i8` value. If the format does not differentiate between
/// `i8` and `i64`, a reasonable implementation would be to cast the value
/// to `i64` and forward to `serialize_i64`.
fn serialize_i8(&mut self, v: i8) -> Result<(), Self::Error>;
/// Serializes a `i16` value. By default it casts the value to a `i64` and
/// passes it to the `serialize_i64` method.
#[inline]
fn serialize_i16(&mut self, v: i16) -> Result<(), Self::Error> {
self.serialize_i64(v as i64)
}
/// Serializes an `i16` value. If the format does not differentiate between
/// `i16` and `i64`, a reasonable implementation would be to cast the value
/// to `i64` and forward to `serialize_i64`.
fn serialize_i16(&mut self, v: i16) -> Result<(), Self::Error>;
/// Serializes a `i32` value. By default it casts the value to a `i64` and
/// passes it to the `serialize_i64` method.
#[inline]
fn serialize_i32(&mut self, v: i32) -> Result<(), Self::Error> {
self.serialize_i64(v as i64)
}
/// Serializes an `i32` value. If the format does not differentiate between
/// `i32` and `i64`, a reasonable implementation would be to cast the value
/// to `i64` and forward to `serialize_i64`.
fn serialize_i32(&mut self, v: i32) -> Result<(), Self::Error>;
/// Serializes a `i64` value.
#[inline]
/// Serializes an `i64` value.
fn serialize_i64(&mut self, v: i64) -> Result<(), Self::Error>;
/// Serializes a `usize` value. By default it casts the value to a `u64` and
/// passes it to the `serialize_u64` method.
#[inline]
fn serialize_usize(&mut self, v: usize) -> Result<(), Self::Error> {
self.serialize_u64(v as u64)
}
/// Serializes a `usize` value. If the format does not differentiate between
/// `usize` and `u64`, a reasonable implementation would be to cast the
/// value to `u64` and forward to `serialize_u64`.
fn serialize_usize(&mut self, v: usize) -> Result<(), Self::Error>;
/// Serializes a `u8` value. By default it casts the value to a `u64` and passes
/// it to the `serialize_u64` method.
#[inline]
fn serialize_u8(&mut self, v: u8) -> Result<(), Self::Error> {
self.serialize_u64(v as u64)
}
/// Serializes a `u8` value. If the format does not differentiate between
/// `u8` and `u64`, a reasonable implementation would be to cast the value
/// to `u64` and forward to `serialize_u64`.
fn serialize_u8(&mut self, v: u8) -> Result<(), Self::Error>;
/// Serializes a `u32` value. By default it casts the value to a `u64` and passes
/// it to the `serialize_u64` method.
#[inline]
fn serialize_u16(&mut self, v: u16) -> Result<(), Self::Error> {
self.serialize_u64(v as u64)
}
/// Serializes a `u16` value. If the format does not differentiate between
/// `u16` and `u64`, a reasonable implementation would be to cast the value
/// to `u64` and forward to `serialize_u64`.
fn serialize_u16(&mut self, v: u16) -> Result<(), Self::Error>;
/// Serializes a `u32` value. By default it casts the value to a `u64` and passes
/// it to the `serialize_u64` method.
#[inline]
fn serialize_u32(&mut self, v: u32) -> Result<(), Self::Error> {
self.serialize_u64(v as u64)
}
/// Serializes a `u32` value. If the format does not differentiate between
/// `u32` and `u64`, a reasonable implementation would be to cast the value
/// to `u64` and forward to `serialize_u64`.
fn serialize_u32(&mut self, v: u32) -> Result<(), Self::Error>;
/// `Serializes a `u64` value.
#[inline]
fn serialize_u64(&mut self, v: u64) -> Result<(), Self::Error>;
/// Serializes a `f32` value. By default it casts the value to a `f64` and passes
/// it to the `serialize_f64` method.
#[inline]
fn serialize_f32(&mut self, v: f32) -> Result<(), Self::Error> {
self.serialize_f64(v as f64)
}
/// Serializes an `f32` value. If the format does not differentiate between
/// `f32` and `f64`, a reasonable implementation would be to cast the value
/// to `f64` and forward to `serialize_f64`.
fn serialize_f32(&mut self, v: f32) -> Result<(), Self::Error>;
/// Serializes a `f64` value.
/// Serializes an `f64` value.
fn serialize_f64(&mut self, v: f64) -> Result<(), Self::Error>;
/// Serializes a character. By default it serializes it as a `&str` containing a
/// single character.
#[inline]
fn serialize_char(&mut self, v: char) -> Result<(), Self::Error> {
self.serialize_str(::utils::encode_utf8(v).as_str())
}
/// Serializes a character.
fn serialize_char(&mut self, v: char) -> Result<(), Self::Error>;
/// Serializes a `&str`.
fn serialize_str(&mut self, value: &str) -> Result<(), Self::Error>;
/// Enables those serialization formats that support serializing
/// byte slices separately from generic arrays. By default it serializes as a regular array.
#[inline]
fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> {
self.serialize_seq(impls::SeqIteratorVisitor::new(value.iter(), Some(value.len())))
}
/// Enables serializers to serialize byte slices more compactly or more
/// efficiently than other types of slices. If no efficient implementation
/// is available, a reasonable implementation would be to forward to
/// `serialize_seq`.
fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error>;
/// Serializes a `()` value.
fn serialize_unit(&mut self) -> Result<(), Self::Error>;
/// Serializes a unit struct value.
///
/// By default, unit structs are serialized as a `()`.
#[inline]
fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<(), Self::Error> {
self.serialize_unit()
}
/// Serializes a unit struct value. A reasonable implementation would be to
/// forward to `serialize_unit`.
fn serialize_unit_struct(
&mut self,
name: &'static str,
) -> Result<(), Self::Error>;
/// Serializes a unit variant, otherwise known as a variant with no arguments.
///
/// By default, unit variants are serialized as a `()`.
#[inline]
fn serialize_unit_variant(&mut self,
_name: &'static str,
_variant_index: usize,
_variant: &'static str) -> Result<(), Self::Error> {
self.serialize_unit()
}
/// Serializes a unit variant, otherwise known as a variant with no
/// arguments. A reasonable implementation would be to forward to
/// `serialize_unit`.
fn serialize_unit_variant(
&mut self,
name: &'static str,
variant_index: usize,
variant: &'static str,
) -> Result<(), Self::Error>;
/// Allows a tuple struct with a single element, also known as a
/// newtyped value, to be more efficiently serialized than a tuple struct with multiple items.
/// By default it just serializes the value as a tuple struct sequence.
#[inline]
fn serialize_newtype_struct<T>(&mut self,
name: &'static str,
value: T) -> Result<(), Self::Error>
where T: Serialize,
{
self.serialize_tuple_struct(name, Some(value))
}
/// Allows a tuple struct with a single element, also known as a newtype
/// struct, to be more efficiently serialized than a tuple struct with
/// multiple items. A reasonable implementation would be to forward to
/// `serialize_tuple_struct`.
fn serialize_newtype_struct<T: Serialize>(
&mut self,
name: &'static str,
value: T,
) -> Result<(), Self::Error>;
/// Allows a variant with a single item to be more efficiently
/// serialized than a variant with multiple items. By default it just serializes the value as a
/// tuple variant sequence.
#[inline]
fn serialize_newtype_variant<T>(&mut self,
name: &'static str,
variant_index: usize,
variant: &'static str,
value: T) -> Result<(), Self::Error>
where T: Serialize,
{
self.serialize_tuple_variant(
name,
variant_index,
variant,
Some(value))
}
/// Allows a variant with a single item to be more efficiently serialized
/// than a variant with multiple items. A reasonable implementation would be
/// to forward to `serialize_tuple_variant`.
fn serialize_newtype_variant<T: Serialize>(
&mut self,
name: &'static str,
variant_index: usize,
variant: &'static str,
value: T,
) -> Result<(), Self::Error>;
/// Serializes a `None` value..serialize
/// Serializes a `None` value.
fn serialize_none(&mut self) -> Result<(), Self::Error>;
/// Serializes a `Some(...)` value.
fn serialize_some<V>(&mut self, value: V) -> Result<(), Self::Error>
where V: Serialize;
fn serialize_some<T: Serialize>(
&mut self,
value: T,
) -> Result<(), Self::Error>;
/// Serializes a sequence.
///
/// Callees of this method need to construct a `SeqVisitor`, which iterates through each item
/// in the sequence.
fn serialize_seq<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor;
/// Begins to serialize a sequence. This call must be followed by zero or
/// more calls to `serialize_seq_elt`, then a call to `serialize_seq_end`.
fn serialize_seq(
&mut self,
len: Option<usize>,
) -> Result<Self::SeqState, Self::Error>;
/// Serializes a sequence element.
fn serialize_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize;
/// Serializes a sequence element. Must have previously called
/// `serialize_seq`.
fn serialize_seq_elt<T: Serialize>(
&mut self,
state: &mut Self::SeqState,
value: T,
) -> Result<(), Self::Error>;
/// Serializes a tuple.
///
/// By default this serializes a tuple as a sequence.
#[inline]
fn serialize_tuple<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.serialize_seq(visitor)
}
/// Finishes serializing a sequence.
fn serialize_seq_end(
&mut self,
state: Self::SeqState,
) -> Result<(), Self::Error>;
/// Serializes a tuple element.
///
/// By default, tuples are serialized as a sequence.
#[inline]
fn serialize_tuple_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.serialize_seq_elt(value)
}
/// Begins to serialize a sequence whose length will be known at
/// deserialization time. This call must be followed by zero or more calls
/// to `serialize_seq_elt`, then a call to `serialize_seq_end`. A reasonable
/// implementation would be to forward to `serialize_seq`.
fn serialize_seq_fixed_size(
&mut self,
size: usize,
) -> Result<Self::SeqState, Self::Error>;
/// Serializes a fixed-size array.
///
/// By default this serializes an array as a sequence.
#[inline]
fn serialize_fixed_size_array<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.serialize_seq(visitor)
}
/// Begins to serialize a tuple. This call must be followed by zero or more
/// calls to `serialize_tuple_elt`, then a call to `serialize_tuple_end`. A
/// reasonable implementation would be to forward to `serialize_seq`.
fn serialize_tuple(
&mut self,
len: usize,
) -> Result<Self::TupleState, Self::Error>;
/// Serializes a tuple struct.
///
/// By default, tuple structs are serialized as a tuple.
#[inline]
fn serialize_tuple_struct<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.serialize_tuple(visitor)
}
/// Serializes a tuple element. Must have previously called
/// `serialize_tuple`.
fn serialize_tuple_elt<T: Serialize>(
&mut self,
state: &mut Self::TupleState,
value: T,
) -> Result<(), Self::Error>;
/// Serializes a tuple struct element.
///
/// By default, tuple struct elements are serialized as a tuple element.
#[inline]
fn serialize_tuple_struct_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.serialize_tuple_elt(value)
}
/// Finishes serializing a tuple.
fn serialize_tuple_end(
&mut self,
state: Self::TupleState,
) -> Result<(), Self::Error>;
/// Serializes a tuple variant.
///
/// By default, tuple variants are serialized as a tuple struct.
#[inline]
fn serialize_tuple_variant<V>(&mut self,
_name: &'static str,
_variant_index: usize,
variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.serialize_tuple_struct(variant, visitor)
}
/// Begins to serialize a tuple struct. This call must be followed by zero
/// or more calls to `serialize_tuple_struct_elt`, then a call to
/// `serialize_tuple_struct_end`. A reasonable implementation would be to
/// forward to `serialize_tuple`.
fn serialize_tuple_struct(
&mut self,
name: &'static str,
len: usize,
) -> Result<Self::TupleStructState, Self::Error>;
/// Serializes a tuple element.
///
/// By default, tuples are serialized as a sequence.
#[inline]
fn serialize_tuple_variant_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.serialize_tuple_struct_elt(value)
}
/// Serializes a tuple struct element. Must have previously called
/// `serialize_tuple_struct`.
fn serialize_tuple_struct_elt<T: Serialize>(
&mut self,
state: &mut Self::TupleStructState,
value: T,
) -> Result<(), Self::Error>;
/// Serializes a map.
///
/// Callees of this method need to construct a `MapVisitor`, which iterates through each item
/// in the map.
fn serialize_map<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: MapVisitor;
/// Finishes serializing a tuple struct.
fn serialize_tuple_struct_end(
&mut self,
state: Self::TupleStructState,
) -> Result<(), Self::Error>;
/// Serializes a map element (key-value pair).
fn serialize_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
where K: Serialize,
V: Serialize;
/// Begins to serialize a tuple variant. This call must be followed by zero
/// or more calls to `serialize_tuple_variant_elt`, then a call to
/// `serialize_tuple_variant_end`. A reasonable implementation would be to
/// forward to `serialize_tuple_struct`.
fn serialize_tuple_variant(
&mut self,
name: &'static str,
variant_index: usize,
variant: &'static str,
len: usize,
) -> Result<Self::TupleVariantState, Self::Error>;
/// Serializes a struct.
///
/// By default, structs are serialized as a map with the field name as the key.
#[inline]
fn serialize_struct<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.serialize_map(visitor)
}
/// Serializes a tuple variant element. Must have previously called
/// `serialize_tuple_variant`.
fn serialize_tuple_variant_elt<T: Serialize>(
&mut self,
state: &mut Self::TupleVariantState,
value: T,
) -> Result<(), Self::Error>;
/// Serializes an element of a struct.
///
/// By default, struct elements are serialized as a map element with the field name as the key.
#[inline]
fn serialize_struct_elt<V>(&mut self,
key: &'static str,
value: V) -> Result<(), Self::Error>
where V: Serialize,
{
self.serialize_map_elt(key, value)
}
/// Finishes serializing a tuple variant.
fn serialize_tuple_variant_end(
&mut self,
state: Self::TupleVariantState,
) -> Result<(), Self::Error>;
/// Serializes a struct variant.
///
/// By default, struct variants are serialized as a struct.
#[inline]
fn serialize_struct_variant<V>(&mut self,
_name: &'static str,
_variant_index: usize,
variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.serialize_struct(variant, visitor)
}
/// Begins to serialize a map. This call must be followed by zero or more
/// calls to `serialize_map_elt`, then a call to `serialize_map_end`.
fn serialize_map(
&mut self,
len: Option<usize>,
) -> Result<Self::MapState, Self::Error>;
/// Serializes an element of a struct variant.
///
/// By default, struct variant elements are serialized as a struct element.
#[inline]
fn serialize_struct_variant_elt<V>(&mut self,
key: &'static str,
value: V) -> Result<(), Self::Error>
where V: Serialize,
{
self.serialize_struct_elt(key, value)
}
}
/// A trait that is used by a `Serialize` to iterate through a sequence.
#[cfg_attr(feature = "nightly-testing", allow(len_without_is_empty))]
pub trait SeqVisitor {
/// Serializes a sequence item in the serializer.
///
/// This returns `Ok(Some(()))` when there are more items to serialize, or `Ok(None)` when
/// complete.
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer;
/// Return the length of the sequence if known.
#[inline]
fn len(&self) -> Option<usize> {
None
}
}
/// A trait that is used by a `Serialize` to iterate through a map.
#[cfg_attr(feature = "nightly-testing", allow(len_without_is_empty))]
pub trait MapVisitor {
/// Serializes a map item in the serializer.
///
/// This returns `Ok(Some(()))` when there are more items to serialize, or `Ok(None)` when
/// complete.
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer;
/// Return the length of the map if known.
#[inline]
fn len(&self) -> Option<usize> {
None
}
/// Serialize a map element. Must have previously called `serialize_map`.
fn serialize_map_elt<K: Serialize, V: Serialize>(
&mut self,
state: &mut Self::MapState,
key: K,
value: V,
) -> Result<(), Self::Error>;
/// Finishes serializing a map.
fn serialize_map_end(
&mut self,
state: Self::MapState,
) -> Result<(), Self::Error>;
/// Begins to serialize a struct. This call must be followed by zero or more
/// calls to `serialize_struct_elt`, then a call to `serialize_struct_end`.
fn serialize_struct(
&mut self,
name: &'static str,
len: usize,
) -> Result<Self::StructState, Self::Error>;
/// Serializes a struct field. Must have previously called
/// `serialize_struct`.
fn serialize_struct_elt<V: Serialize>(
&mut self,
state: &mut Self::StructState,
key: &'static str,
value: V,
) -> Result<(), Self::Error>;
/// Finishes serializing a struct.
fn serialize_struct_end(
&mut self,
state: Self::StructState,
) -> Result<(), Self::Error>;
/// Begins to serialize a struct variant. This call must be followed by zero
/// or more calls to `serialize_struct_variant_elt`, then a call to
/// `serialize_struct_variant_end`.
fn serialize_struct_variant(
&mut self,
name: &'static str,
variant_index: usize,
variant: &'static str,
len: usize,
) -> Result<Self::StructVariantState, Self::Error>;
/// Serialize a struct variant element. Must have previously called
/// `serialize_struct_variant`.
fn serialize_struct_variant_elt<V: Serialize>(
&mut self,
state: &mut Self::StructVariantState,
key: &'static str,
value: V,
) -> Result<(), Self::Error>;
/// Finishes serializing a struct variant.
fn serialize_struct_variant_end(
&mut self,
state: Self::StructVariantState,
) -> Result<(), Self::Error>;
}
+13 -11
View File
@@ -1,6 +1,8 @@
[package]
name = "serde_codegen"
version = "0.7.12"
# DO NOT RELEASE ANY MORE 0.7 RELEASES FROM THIS BRANCH
# USE THE 0.7.x BRANCH
version = "0.8.0-rc2"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
@@ -12,8 +14,8 @@ include = ["Cargo.toml", "build.rs", "src/**/*.rs", "src/lib.rs.in"]
[features]
default = ["with-syntex"]
nightly = ["quasi_macros"]
nightly-testing = ["clippy"]
unstable = ["quasi_macros"]
unstable-testing = ["clippy"]
with-syntex = [
"quasi/with-syntex",
"quasi_codegen",
@@ -24,14 +26,14 @@ with-syntex = [
]
[build-dependencies]
quasi_codegen = { version = "^0.14.0", optional = true }
syntex = { version = "^0.37.0", optional = true }
quasi_codegen = { version = "^0.15.0", optional = true }
syntex = { version = "^0.38.0", optional = true }
[dependencies]
aster = { version = "^0.20.0", default-features = false }
aster = { version = "^0.21.1", default-features = false }
clippy = { version = "^0.*", optional = true }
quasi = { version = "^0.14.0", default-features = false }
quasi_macros = { version = "^0.14.0", optional = true }
serde_codegen_internals = { version = "^0.2.0", path = "../serde_codegen_internals", default-features = false }
syntex = { version = "^0.37.0", optional = true }
syntex_syntax = { version = "^0.37.0", optional = true }
quasi = { version = "^0.15.0", default-features = false }
quasi_macros = { version = "^0.15.0", optional = true }
serde_codegen_internals = { version = "0.4.0-rc1", default-features = false }
syntex = { version = "^0.38.0", optional = true }
syntex_syntax = { version = "^0.38.0", optional = true }
+11 -6
View File
@@ -8,6 +8,7 @@ use syntax::ptr::P;
use syntax::tokenstream::TokenTree;
use bound;
use span;
use internals::ast::{Body, Field, Item, Style, Variant};
use internals::{attr, Error};
@@ -44,7 +45,7 @@ pub fn expand_derive_deserialize(
let builder = aster::AstBuilder::new().span(span);
let impl_item = deserialize_item(cx, &builder, &item);
push(Annotatable::Item(impl_item))
push(span::record_expansion(cx, impl_item, "Deserialize"))
}
fn deserialize_item(
@@ -394,6 +395,7 @@ fn deserialize_seq(
fields: &[Field],
is_struct: bool,
) -> P<ast::Expr> {
let mut index_in_seq = 0usize;
let let_values: Vec<_> = fields.iter()
.enumerate()
.map(|(i, field)| {
@@ -419,14 +421,17 @@ fn deserialize_seq(
})
}
};
quote_stmt!(cx,
let assign = quote_stmt!(cx,
let $name = match $visit {
Some(value) => { value },
None => {
return Err(_serde::de::Error::end_of_stream());
try!(visitor.end());
return Err(_serde::de::Error::invalid_length($index_in_seq));
}
};
).unwrap()
).unwrap();
index_in_seq += 1;
assign
}
})
.collect();
@@ -1092,10 +1097,10 @@ fn deserialize_map(
}
}
$extract_values
try!(visitor.end());
$extract_values
Ok($result)
})
}
+8 -11
View File
@@ -1,7 +1,7 @@
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
#![cfg_attr(feature = "nightly-testing", feature(plugin))]
#![cfg_attr(feature = "nightly-testing", allow(too_many_arguments))]
#![cfg_attr(feature = "nightly-testing", allow(used_underscore_binding))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", allow(too_many_arguments))]
#![cfg_attr(feature = "clippy", allow(used_underscore_binding))]
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))]
@@ -40,13 +40,6 @@ pub fn expand<S, D>(src: S, dst: D) -> Result<(), syntex::Error>
where S: AsRef<Path>,
D: AsRef<Path>,
{
let mut registry = syntex::Registry::new();
register(&mut registry);
registry.expand("", src.as_ref(), dst.as_ref())
}
#[cfg(feature = "with-syntex")]
pub fn register(reg: &mut syntex::Registry) {
use syntax::{ast, fold};
/// Strip the serde attributes from the crate.
@@ -73,6 +66,8 @@ pub fn register(reg: &mut syntex::Registry) {
fold::Folder::fold_crate(&mut StripAttributeFolder, krate)
}
let mut reg = syntex::Registry::new();
reg.add_attr("feature(custom_derive)");
reg.add_attr("feature(custom_attribute)");
@@ -80,6 +75,8 @@ pub fn register(reg: &mut syntex::Registry) {
reg.add_decorator("derive_Deserialize", de::expand_derive_deserialize);
reg.add_post_expansion_pass(strip_attributes);
reg.expand("", src.as_ref(), dst.as_ref())
}
#[cfg(not(feature = "with-syntex"))]
+1
View File
@@ -1,3 +1,4 @@
mod bound;
mod de;
mod ser;
mod span;
+99 -287
View File
@@ -6,6 +6,7 @@ use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ptr::P;
use bound;
use span;
use internals::ast::{Body, Field, Item, Style, Variant};
use internals::{attr, Error};
@@ -38,7 +39,7 @@ pub fn expand_derive_serialize(
let builder = aster::AstBuilder::new().span(span);
let impl_item = serialize_item(cx, &builder, &item);
push(Annotatable::Item(impl_item))
push(span::record_expansion(cx, impl_item, "Serialize"))
}
fn serialize_item(
@@ -215,30 +216,23 @@ fn serialize_tuple_struct(
fields: &[Field],
item_attrs: &attr::Item,
) -> P<ast::Expr> {
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
let serialize_stmts = serialize_tuple_struct_visitor(
cx,
builder,
ty.clone(),
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(ty.clone()),
builder.id("serialize_tuple_struct_elt"),
fields,
impl_generics,
false,
cx.ident_of("serialize_tuple_struct_elt"),
);
let type_name = name_expr(builder, item_attrs.name());
let len = serialize_stmts.len();
quote_expr!(cx, {
$visitor_struct
$visitor_impl
_serializer.serialize_tuple_struct($type_name, Visitor {
value: self,
state: 0,
_structure_ty: ::std::marker::PhantomData::<&$ty>,
})
let mut state = try!(_serializer.serialize_tuple_struct($type_name, $len));
$serialize_stmts
_serializer.serialize_tuple_struct_end(state)
})
}
@@ -250,30 +244,34 @@ fn serialize_struct(
fields: &[Field],
item_attrs: &attr::Item,
) -> P<ast::Expr> {
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
let serialize_fields = serialize_struct_visitor(
cx,
builder,
ty.clone(),
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(ty.clone()),
builder.id("serialize_struct_elt"),
fields,
impl_generics,
false,
cx.ident_of("serialize_struct_elt"),
);
let type_name = name_expr(builder, item_attrs.name());
let len = fields.iter()
.filter(|&field| !field.attrs.skip_serializing())
.map(|field| {
let ident = field.ident.expect("struct has unnamed fields");
let field_expr = quote_expr!(cx, &self.$ident);
match field.attrs.skip_serializing_if() {
Some(path) => quote_expr!(cx, if $path($field_expr) { 0 } else { 1 }),
None => quote_expr!(cx, 1),
}
})
.fold(quote_expr!(cx, 0), |sum, expr| quote_expr!(cx, $sum + $expr));
quote_expr!(cx, {
$visitor_struct
$visitor_impl
_serializer.serialize_struct($type_name, Visitor {
value: self,
state: 0,
_structure_ty: ::std::marker::PhantomData::<&$ty>,
})
let mut state = try!(_serializer.serialize_struct($type_name, $len));
$serialize_fields
_serializer.serialize_struct_end(state)
})
}
@@ -376,7 +374,6 @@ fn serialize_variant(
generics,
ty,
&variant.fields,
field_names,
);
quote_arm!(cx,
@@ -384,27 +381,19 @@ fn serialize_variant(
)
}
Style::Struct => {
let field_names: Vec<_> = (0 .. variant.fields.len())
.map(|i| builder.id(format!("__field{}", i)))
.collect();
let pat = builder.pat().struct_()
.id(type_ident).id(variant_ident).build()
.with_pats(
field_names.iter()
.zip(variant.fields.iter())
.map(|(id, field)| {
let name = match field.ident {
Some(name) => name,
None => {
cx.span_bug(field.span, "struct variant has unnamed fields")
}
};
(name, builder.pat().ref_id(id))
})
)
.build();
let mut pat = builder.pat().struct_().id(type_ident).id(variant_ident).build();
for field in variant.fields.iter() {
let name = match field.ident {
Some(name) => name,
None => cx.span_bug(field.span, "struct variant has unnamed fields"),
};
pat = pat.with_field_pat(ast::FieldPat {
ident: name,
pat: builder.pat().ref_id(name),
is_shorthand: true,
});
}
let pat = pat.build();
let expr = serialize_struct_variant(
cx,
@@ -414,7 +403,6 @@ fn serialize_variant(
generics,
ty,
&variant.fields,
field_names,
item_attrs,
);
@@ -461,46 +449,23 @@ fn serialize_tuple_variant(
generics: &ast::Generics,
structure_ty: P<ast::Ty>,
fields: &[Field],
field_names: Vec<Ident>,
) -> P<ast::Expr> {
let variant_ty = builder.ty().tuple()
.with_tys(
fields.iter().map(|field| {
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(field.ty.clone())
})
)
.build();
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
let serialize_stmts = serialize_tuple_struct_visitor(
cx,
builder,
structure_ty.clone(),
variant_ty,
builder.id("serialize_tuple_variant_elt"),
structure_ty,
fields,
generics,
true,
cx.ident_of("serialize_tuple_variant_elt"),
);
let value_expr = builder.expr().tuple()
.with_exprs(
field_names.iter().map(|field| {
builder.expr().id(field)
})
)
.build();
let len = serialize_stmts.len();
quote_expr!(cx, {
$visitor_struct
$visitor_impl
_serializer.serialize_tuple_variant($type_name, $variant_index, $variant_name, Visitor {
value: $value_expr,
state: 0,
_structure_ty: ::std::marker::PhantomData::<&$structure_ty>,
})
let mut state = try!(_serializer.serialize_tuple_variant($type_name, $variant_index, $variant_name, $len));
$serialize_stmts
_serializer.serialize_tuple_variant_end(state)
})
}
@@ -512,83 +477,42 @@ fn serialize_struct_variant(
generics: &ast::Generics,
ty: P<ast::Ty>,
fields: &[Field],
field_names: Vec<Ident>,
item_attrs: &attr::Item,
) -> P<ast::Expr> {
let variant_generics = builder.generics()
.with(generics.clone())
.add_lifetime_bound("'__serde_variant")
.lifetime_name("'__serde_variant")
.build();
let variant_struct = builder.item().struct_("__VariantStruct")
.with_generics(variant_generics.clone())
.with_fields(
fields.iter().map(|field| {
builder.struct_field(field.ident.expect("struct has unnamed fields"))
.ty()
.ref_()
.lifetime("'__serde_variant")
.build_ty(field.ty.clone())
})
)
.field("__serde_container_ty")
.ty().phantom_data().build(ty.clone())
.build();
let variant_expr = builder.expr().struct_id("__VariantStruct")
.with_id_exprs(
fields.iter()
.zip(field_names.iter())
.map(|(field, field_name)| {
(
field.ident.expect("struct has unnamed fields"),
builder.expr().id(field_name),
)
})
)
.field("__serde_container_ty").path()
.global()
.id("std").id("marker")
.segment("PhantomData")
.with_ty(ty.clone())
.build()
.build()
.build();
let variant_ty = builder.ty().path()
.segment("__VariantStruct")
.with_generics(variant_generics.clone())
.build()
.build();
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
let serialize_fields = serialize_struct_visitor(
cx,
builder,
variant_ty.clone(),
variant_ty.clone(),
builder.id("serialize_struct_variant_elt"),
ty.clone(),
fields,
&variant_generics,
&generics,
true,
cx.ident_of("serialize_struct_variant_elt"),
);
let item_name = name_expr(builder, item_attrs.name());
let len = fields.iter()
.filter(|&field| !field.attrs.skip_serializing())
.map(|field| {
let ident = field.ident.expect("struct has unnamed fields");
let field_expr = quote_expr!(cx, $ident);
match field.attrs.skip_serializing_if() {
Some(path) => quote_expr!(cx, if $path($field_expr) { 0 } else { 1 }),
None => quote_expr!(cx, 1),
}
})
.fold(quote_expr!(cx, 0), |sum, expr| quote_expr!(cx, $sum + $expr));
quote_expr!(cx, {
$variant_struct
$visitor_struct
$visitor_impl
_serializer.serialize_struct_variant(
let mut state = try!(_serializer.serialize_struct_variant(
$item_name,
$variant_index,
$variant_name,
Visitor {
value: $variant_expr,
state: 0,
_structure_ty: ::std::marker::PhantomData,
},
)
$len,
));
$serialize_fields
_serializer.serialize_struct_variant_end(state)
})
}
@@ -596,187 +520,75 @@ fn serialize_tuple_struct_visitor(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
structure_ty: P<ast::Ty>,
variant_ty: P<ast::Ty>,
serializer_method: ast::Ident,
fields: &[Field],
generics: &ast::Generics,
is_enum: bool,
) -> (P<ast::Item>, P<ast::Item>) {
let arms: Vec<_> = fields.iter()
func: ast::Ident,
) -> Vec<ast::Stmt> {
fields.iter()
.enumerate()
.map(|(i, field)| {
let mut field_expr = builder.expr().tup_field(i).field("value").self_();
if !is_enum {
field_expr = quote_expr!(cx, &$field_expr);
}
let mut field_expr = if is_enum {
builder.expr().path().id(format!("__field{}", i)).build()
} else {
builder.expr().ref_().tup_field(i).self_()
};
let continue_if_skip = field.attrs.skip_serializing_if()
.map(|path| quote_stmt!(cx, if $path($field_expr) { continue }));
let skip = field.attrs.skip_serializing_if()
.map(|path| quote_expr!(cx, $path($field_expr)))
.unwrap_or(quote_expr!(cx, false));
if let Some(path) = field.attrs.serialize_with() {
field_expr = wrap_serialize_with(cx, builder,
&structure_ty, generics, &field.ty, path, field_expr);
}
quote_arm!(cx,
$i => {
self.state += 1;
$continue_if_skip
Ok(Some(try!(_serializer.$serializer_method($field_expr))))
quote_stmt!(cx,
if !$skip {
try!(_serializer.$func(&mut state, $field_expr));
}
)
).unwrap()
})
.collect();
let visitor_impl_generics = builder.from_generics(generics.clone())
.add_lifetime_bound("'__a")
.lifetime_name("'__a")
.build();
let where_clause = &visitor_impl_generics.where_clause;
let visitor_generics = builder.from_generics(visitor_impl_generics.clone())
.strip_bounds()
.build();
let nfields = fields.len();
(
quote_item!(cx,
struct Visitor $visitor_impl_generics $where_clause {
state: usize,
value: $variant_ty,
_structure_ty: ::std::marker::PhantomData<&'__a $structure_ty>,
}
).unwrap(),
quote_item!(cx,
impl $visitor_impl_generics _serde::ser::SeqVisitor
for Visitor $visitor_generics
$where_clause {
#[inline]
fn visit<__S>(&mut self, _serializer: &mut __S) -> ::std::result::Result<Option<()>, __S::Error>
where __S: _serde::ser::Serializer
{
match self.state {
$arms
_ => Ok(None)
}
}
#[inline]
fn len(&self) -> Option<usize> {
Some($nfields)
}
}
).unwrap(),
)
.collect()
}
fn serialize_struct_visitor(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
structure_ty: P<ast::Ty>,
variant_ty: P<ast::Ty>,
serializer_method: ast::Ident,
fields: &[Field],
generics: &ast::Generics,
is_enum: bool,
) -> (P<ast::Item>, P<ast::Item>) {
let arms: Vec<ast::Arm> = fields.iter()
func: ast::Ident,
) -> Vec<ast::Stmt> {
fields.iter()
.filter(|&field| !field.attrs.skip_serializing())
.enumerate()
.map(|(i, field)| {
.map(|field| {
let ident = field.ident.expect("struct has unnamed field");
let mut field_expr = quote_expr!(cx, self.value.$ident);
if !is_enum {
field_expr = quote_expr!(cx, &$field_expr);
}
let mut field_expr = if is_enum {
quote_expr!(cx, $ident)
} else {
quote_expr!(cx, &self.$ident)
};
let key_expr = name_expr(builder, field.attrs.name());
let continue_if_skip = field.attrs.skip_serializing_if()
.map(|path| quote_stmt!(cx, if $path($field_expr) { continue }));
let skip = field.attrs.skip_serializing_if()
.map(|path| quote_expr!(cx, $path($field_expr)))
.unwrap_or(quote_expr!(cx, false));
if let Some(path) = field.attrs.serialize_with() {
field_expr = wrap_serialize_with(cx, builder,
&structure_ty, generics, &field.ty, path, field_expr)
}
let expr = quote_expr!(cx,
_serializer.$serializer_method($key_expr, $field_expr)
);
quote_arm!(cx,
$i => {
self.state += 1;
$continue_if_skip
return Ok(Some(try!($expr)));
quote_stmt!(cx,
if !$skip {
try!(_serializer.$func(&mut state, $key_expr, $field_expr));
}
)
).unwrap()
})
.collect();
let visitor_impl_generics = builder.from_generics(generics.clone())
.add_lifetime_bound("'__a")
.lifetime_name("'__a")
.build();
let where_clause = &visitor_impl_generics.where_clause;
let visitor_generics = builder.from_generics(visitor_impl_generics.clone())
.strip_bounds()
.build();
let len = fields.iter()
.filter(|&field| !field.attrs.skip_serializing())
.map(|field| {
let ident = field.ident.expect("struct has unnamed fields");
let mut field_expr = quote_expr!(cx, self.value.$ident);
if !is_enum {
field_expr = quote_expr!(cx, &$field_expr);
}
match field.attrs.skip_serializing_if() {
Some(path) => quote_expr!(cx, if $path($field_expr) { 0 } else { 1 }),
None => quote_expr!(cx, 1),
}
})
.fold(quote_expr!(cx, 0), |sum, expr| quote_expr!(cx, $sum + $expr));
(
quote_item!(cx,
struct Visitor $visitor_impl_generics $where_clause {
state: usize,
value: $variant_ty,
_structure_ty: ::std::marker::PhantomData<&'__a $structure_ty>,
}
).unwrap(),
quote_item!(cx,
impl $visitor_impl_generics
_serde::ser::MapVisitor
for Visitor $visitor_generics
$where_clause {
#[inline]
fn visit<__S>(&mut self, _serializer: &mut __S) -> ::std::result::Result<Option<()>, __S::Error>
where __S: _serde::ser::Serializer,
{
loop {
match self.state {
$arms
_ => { return Ok(None); }
}
}
}
#[inline]
fn len(&self) -> Option<usize> {
Some($len)
}
}
).unwrap(),
)
.collect()
}
fn wrap_serialize_with(
+43
View File
@@ -0,0 +1,43 @@
use syntax::ast;
use syntax::codemap::{self, ExpnId, Span};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::fold::{self, Folder};
use syntax::parse::token::intern;
use syntax::ptr::P;
pub fn record_expansion(
cx: &ExtCtxt,
item: P<ast::Item>,
derive: &str,
) -> Annotatable {
let info = codemap::ExpnInfo {
call_site: codemap::DUMMY_SP,
callee: codemap::NameAndSpan {
format: codemap::MacroAttribute(intern(&format!("derive({})", derive))),
span: None,
allow_internal_unstable: false,
},
};
let expn_id = cx.codemap().record_expansion(info);
let mut respanner = Respanner { expn_id: expn_id };
let item = item.map(|item| respanner.fold_item_simple(item));
Annotatable::Item(item)
}
struct Respanner {
expn_id: ExpnId,
}
impl Folder for Respanner {
fn new_span(&mut self, span: Span) -> Span {
Span {
expn_id: self.expn_id,
.. span
}
}
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
fold::noop_fold_mac(mac, self)
}
}
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_codegen_internals"
version = "0.2.0"
version = "0.4.0-rc1"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "AST representation used by Serde codegen. Unstable."
@@ -11,10 +11,10 @@ include = ["Cargo.toml", "src/**/*.rs"]
[features]
default = ["with-syntex"]
nightly-testing = ["clippy"]
unstable-testing = ["clippy"]
with-syntex = ["syntex_syntax", "syntex_errors"]
[dependencies]
clippy = { version = "^0.*", optional = true }
syntex_syntax = { version = "^0.37.0", optional = true }
syntex_errors = { version = "^0.37.0", optional = true }
syntex_syntax = { version = "^0.38.0", optional = true }
syntex_errors = { version = "^0.38.0", optional = true }
+14 -12
View File
@@ -1,3 +1,5 @@
use std::rc::Rc;
use syntax::ast;
use syntax::attr::{self, HasAttrs};
use syntax::codemap::{Span, Spanned, respan};
@@ -517,33 +519,33 @@ struct Respanner<'a, 'b: 'a> {
}
impl<'a, 'b> Folder for Respanner<'a, 'b> {
fn fold_tt(&mut self, tt: TokenTree) -> TokenTree {
match tt {
fn fold_tt(&mut self, tt: &TokenTree) -> TokenTree {
match *tt {
TokenTree::Token(span, ref tok) => {
TokenTree::Token(
self.new_span(span),
self.fold_token(tok.clone())
)
}
TokenTree::Delimited(span, delimed) => {
TokenTree::Delimited(span, ref delimed) => {
TokenTree::Delimited(
self.new_span(span),
tokenstream::Delimited {
Rc::new(tokenstream::Delimited {
delim: delimed.delim,
open_span: delimed.open_span,
tts: self.fold_tts(delimed.tts),
tts: self.fold_tts(&delimed.tts),
close_span: delimed.close_span,
}
})
)
}
TokenTree::Sequence(span, seq) => {
TokenTree::Sequence(span, ref seq) => {
TokenTree::Sequence(
self.new_span(span),
tokenstream::SequenceRepetition {
tts: self.fold_tts(seq.tts),
Rc::new(tokenstream::SequenceRepetition {
tts: self.fold_tts(&seq.tts),
separator: seq.separator.clone().map(|tok| self.fold_token(tok)),
..seq
}
..**seq
})
)
}
}
@@ -589,7 +591,7 @@ fn parse_string_via_tts<T, F>(cx: &ExtCtxt, name: &str, string: String, action:
cx.parse_sess()));
// Respan the spans to say they are all coming from this macro.
let tts = Respanner { cx: cx }.fold_tts(tts);
let tts = Respanner { cx: cx }.fold_tts(&tts);
let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts);
+2 -2
View File
@@ -1,5 +1,5 @@
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
#![cfg_attr(feature = "nightly-testing", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
#[cfg(feature = "with-syntex")]
+8 -5
View File
@@ -1,6 +1,8 @@
[package]
name = "serde_macros"
version = "0.7.12"
# DO NOT RELEASE ANY MORE 0.7 RELEASES FROM THIS BRANCH
# USE THE 0.7.x BRANCH
version = "0.8.0-rc2"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
@@ -14,18 +16,19 @@ name = "serde_macros"
plugin = true
[features]
nightly-testing = ["clippy", "serde/nightly-testing", "serde_codegen/nightly-testing"]
unstable-testing = ["clippy", "serde/unstable-testing", "serde_codegen/unstable-testing"]
[dependencies]
clippy = { version = "^0.*", optional = true }
serde_codegen = { version = "^0.7.12", path = "../serde_codegen", default-features = false, features = ["nightly"] }
serde_codegen = { version = "^0.8.0-rc2", default-features = false, features = ["unstable"] }
[dev-dependencies]
clippy = "^0.*"
compiletest_rs = "^0.2.0"
fnv = "1.0"
rustc-serialize = "^0.3.16"
serde = { version = "^0.7.12", path = "../serde" }
serde_test = { version = "^0.7.12", path = "../serde_test" }
serde = "0.8.0-rc2"
serde_test = "0.8.0-rc2"
[[test]]
name = "test"
+6 -1
View File
@@ -20,6 +20,11 @@ fn run_mode(mode: &'static str) {
}
#[test]
fn compile_test() {
fn compile_fail() {
run_mode("compile-fail");
}
#[test]
fn run_pass() {
run_mode("run-pass");
}
@@ -0,0 +1,12 @@
#![feature(custom_derive, plugin)]
#![plugin(serde_macros, clippy)]
#![deny(identity_op)]
// The derived implementation uses 0+1 to add up the number of fields
// serialized, which Clippy warns about. If the expansion info is registered
// correctly, the Clippy lint is not triggered.
#[derive(Serialize)]
struct A { b: u8 }
fn main() {}
+4 -2
View File
@@ -1,6 +1,8 @@
[package]
name = "serde_test"
version = "0.7.12"
# DO NOT RELEASE ANY MORE 0.7 RELEASES FROM THIS BRANCH
# USE THE 0.7.x BRANCH
version = "0.8.0-rc2"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations"
@@ -11,4 +13,4 @@ keywords = ["serde", "serialization"]
include = ["Cargo.toml", "src/**/*.rs"]
[dependencies]
serde = { version = "0.7.12", path = "../serde" }
serde = "0.8.0-rc2"
+8 -5
View File
@@ -135,15 +135,18 @@ impl<I> de::Deserializer for Deserializer<I>
Some(Token::Option(true)) => visitor.visit_some(self),
Some(Token::Unit) => visitor.visit_unit(),
Some(Token::UnitStruct(name)) => visitor.visit_unit_struct(name),
Some(Token::SeqStart(len)) | Some(Token::TupleStructStart(_, len)) => {
Some(Token::SeqStart(len)) => {
self.visit_seq(len, visitor)
}
Some(Token::SeqArrayStart(len)) => {
Some(Token::SeqArrayStart(len))| Some(Token::TupleStructStart(_, len)) => {
self.visit_seq(Some(len), visitor)
}
Some(Token::MapStart(len)) | Some(Token::StructStart(_, len)) => {
Some(Token::MapStart(len)) => {
self.visit_map(len, visitor)
}
Some(Token::StructStart(_, len)) => {
self.visit_map(Some(len), visitor)
}
Some(token) => Err(Error::UnexpectedToken(token)),
None => Err(Error::EndOfStream),
}
@@ -745,7 +748,7 @@ impl<'a, I> VariantVisitor for DeserializerVariantVisitor<'a, I>
where V: Visitor,
{
match self.de.tokens.peek() {
Some(&Token::EnumSeqStart(_, _, Some(enum_len))) => {
Some(&Token::EnumSeqStart(_, _, enum_len)) => {
let token = self.de.tokens.next().unwrap();
if len == enum_len {
@@ -776,7 +779,7 @@ impl<'a, I> VariantVisitor for DeserializerVariantVisitor<'a, I>
where V: Visitor,
{
match self.de.tokens.peek() {
Some(&Token::EnumMapStart(_, _, Some(enum_len))) => {
Some(&Token::EnumMapStart(_, _, enum_len)) => {
let token = self.de.tokens.next().unwrap();
if fields.len() == enum_len {
+86 -116
View File
@@ -2,8 +2,6 @@ use std::marker::PhantomData;
use serde::ser::{
self,
MapVisitor,
SeqVisitor,
Serialize,
};
@@ -30,32 +28,19 @@ impl<'a, I> Serializer<'a, I>
pub fn next_token(&mut self) -> Option<&'a Token<'a>> {
self.tokens.next()
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<(), Error>
where V: SeqVisitor
{
while let Some(()) = try!(visitor.visit(self)) { }
assert_eq!(self.tokens.next(), Some(&Token::SeqEnd));
Ok(())
}
fn visit_map<V>(&mut self, mut visitor: V) -> Result<(), Error>
where V: MapVisitor
{
while let Some(()) = try!(visitor.visit(self)) { }
assert_eq!(self.tokens.next(), Some(&Token::MapEnd));
Ok(())
}
}
impl<'a, I> ser::Serializer for Serializer<'a, I>
where I: Iterator<Item=&'a Token<'a>>,
{
type Error = Error;
type MapState = ();
type SeqState = ();
type TupleState = ();
type TupleStructState = ();
type TupleVariantState = ();
type StructState = ();
type StructVariantState = ();
fn serialize_unit(&mut self) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Unit));
@@ -174,177 +159,162 @@ impl<'a, I> ser::Serializer for Serializer<'a, I>
value.serialize(self)
}
fn serialize_seq<V>(&mut self, visitor: V) -> Result<(), Error>
where V: SeqVisitor
fn serialize_seq<'b>(&'b mut self, len: Option<usize>) -> Result<(), Error>
{
let len = visitor.len();
assert_eq!(self.tokens.next(), Some(&Token::SeqStart(len)));
self.visit_seq(visitor)
Ok(())
}
fn serialize_fixed_size_array<V>(&mut self, visitor: V) -> Result<(), Error>
where V: SeqVisitor
{
let len = visitor.len().expect("arrays must have a length");
assert_eq!(self.tokens.next(), Some(&Token::SeqArrayStart(len)));
self.visit_seq(visitor)
}
fn serialize_seq_elt<T>(&mut self, value: T) -> Result<(), Error>
fn serialize_seq_elt<T>(&mut self, _: &mut (), value: T) -> Result<(), Error>
where T: Serialize
{
assert_eq!(self.tokens.next(), Some(&Token::SeqSep));
value.serialize(self)
}
fn serialize_tuple<V>(&mut self, mut visitor: V) -> Result<(), Error>
where V: SeqVisitor
{
let len = visitor.len().expect("arrays must have a length");
assert_eq!(self.tokens.next(), Some(&Token::TupleStart(len)));
while let Some(()) = try!(visitor.visit(self)) { }
assert_eq!(self.tokens.next(), Some(&Token::TupleEnd));
fn serialize_seq_end(&mut self, _: ()) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::SeqEnd));
Ok(())
}
fn serialize_tuple_elt<T>(&mut self, value: T) -> Result<(), Error>
fn serialize_seq_fixed_size(&mut self, len: usize) -> Result<(), Error>
{
assert_eq!(self.tokens.next(), Some(&Token::SeqArrayStart(len)));
Ok(())
}
fn serialize_tuple(&mut self, len: usize) -> Result<(), Error>
{
assert_eq!(self.tokens.next(), Some(&Token::TupleStart(len)));
Ok(())
}
fn serialize_tuple_elt<T>(&mut self, _: &mut (), value: T) -> Result<(), Error>
where T: Serialize
{
assert_eq!(self.tokens.next(), Some(&Token::TupleSep));
value.serialize(self)
}
fn serialize_tuple_end(&mut self, _: ()) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::TupleEnd));
Ok(())
}
fn serialize_newtype_struct<T>(&mut self,
name: &'static str,
value: T) -> Result<(), Error>
name: &'static str,
value: T) -> Result<(), Error>
where T: Serialize,
{
assert_eq!(self.tokens.next(), Some(&Token::StructNewType(name)));
value.serialize(self)
}
fn serialize_tuple_struct<V>(&mut self, name: &str, mut visitor: V) -> Result<(), Error>
where V: SeqVisitor
fn serialize_tuple_struct(&mut self, name: &'static str, len: usize) -> Result<(), Error>
{
let len = visitor.len();
assert_eq!(self.tokens.next(), Some(&Token::TupleStructStart(name, len)));
while let Some(()) = try!(visitor.visit(self)) { }
assert_eq!(self.tokens.next(), Some(&Token::TupleStructEnd));
Ok(())
}
fn serialize_tuple_struct_elt<T>(&mut self, value: T) -> Result<(), Error>
where T: Serialize,
fn serialize_tuple_struct_elt<T>(&mut self, _: &mut (), value: T) -> Result<(), Error>
where T: Serialize
{
assert_eq!(self.tokens.next(), Some(&Token::TupleStructSep));
value.serialize(self)
}
fn serialize_tuple_variant<V>(&mut self,
name: &str,
_variant_index: usize,
variant: &str,
mut visitor: V) -> Result<(), Error>
where V: SeqVisitor
fn serialize_tuple_struct_end(&mut self, _: ()) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::TupleStructEnd));
Ok(())
}
fn serialize_tuple_variant(&mut self,
name: &str,
_variant_index: usize,
variant: &str,
len: usize) -> Result<(), Error>
{
let len = visitor.len();
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqStart(name, variant, len)));
while let Some(()) = try!(visitor.visit(self)) { }
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqEnd));
Ok(())
}
fn serialize_tuple_variant_elt<T>(&mut self, value: T) -> Result<(), Error>
where T: Serialize,
fn serialize_tuple_variant_elt<T>(&mut self, _: &mut (), value: T) -> Result<(), Error>
where T: Serialize
{
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqSep));
value.serialize(self)
}
fn serialize_map<V>(&mut self, visitor: V) -> Result<(), Error>
where V: MapVisitor
{
let len = visitor.len();
fn serialize_tuple_variant_end(&mut self, _: ()) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqEnd));
Ok(())
}
fn serialize_map(&mut self, len: Option<usize>) -> Result<(), Error>
{
assert_eq!(self.tokens.next(), Some(&Token::MapStart(len)));
self.visit_map(visitor)
Ok(())
}
fn serialize_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Error>
where K: Serialize,
V: Serialize,
{
fn serialize_map_elt<K, V>(&mut self, _: &mut (), key: K, value: V) -> Result<(), Self::Error> where K: Serialize, V: Serialize {
assert_eq!(self.tokens.next(), Some(&Token::MapSep));
try!(key.serialize(self));
value.serialize(self)
}
fn serialize_struct<V>(&mut self, name: &str, mut visitor: V) -> Result<(), Error>
where V: MapVisitor
{
let len = visitor.len();
fn serialize_map_end(&mut self, _: ()) -> Result<(), Self::Error> {
assert_eq!(self.tokens.next(), Some(&Token::MapEnd));
Ok(())
}
fn serialize_struct(&mut self, name: &str, len: usize) -> Result<(), Error>
{
assert_eq!(self.tokens.next(), Some(&Token::StructStart(name, len)));
while let Some(()) = try!(visitor.visit(self)) { }
assert_eq!(self.tokens.next(), Some(&Token::StructEnd));
Ok(())
}
fn serialize_struct_elt<T>(&mut self, key: &'static str, value: T) -> Result<(), Error>
where T: Serialize,
{
fn serialize_struct_elt<V>(&mut self, _: &mut (), key: &'static str, value: V) -> Result<(), Self::Error> where V: Serialize {
assert_eq!(self.tokens.next(), Some(&Token::StructSep));
try!(key.serialize(self));
value.serialize(self)
}
fn serialize_struct_variant<V>(&mut self,
name: &str,
_variant_index: usize,
variant: &str,
mut visitor: V) -> Result<(), Error>
where V: MapVisitor
{
let len = visitor.len();
fn serialize_struct_end(&mut self, _: ()) -> Result<(), Self::Error> {
assert_eq!(self.tokens.next(), Some(&Token::StructEnd));
Ok(())
}
fn serialize_struct_variant(&mut self,
name: &str,
_variant_index: usize,
variant: &str,
len: usize) -> Result<(), Error>
{
assert_eq!(self.tokens.next(), Some(&Token::EnumMapStart(name, variant, len)));
while let Some(()) = try!(visitor.visit(self)) { }
assert_eq!(self.tokens.next(), Some(&Token::EnumMapEnd));
Ok(())
}
fn serialize_struct_variant_elt<T>(&mut self, key: &'static str, value: T) -> Result<(), Error>
where T: Serialize,
{
fn serialize_struct_variant_elt<V>(&mut self, _: &mut (), key: &'static str, value: V) -> Result<(), Self::Error> where V: Serialize {
assert_eq!(self.tokens.next(), Some(&Token::EnumMapSep));
try!(key.serialize(self));
value.serialize(self)
}
fn serialize_struct_variant_end(&mut self, _: ()) -> Result<(), Self::Error> {
assert_eq!(self.tokens.next(), Some(&Token::EnumMapEnd));
Ok(())
}
fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> {
let mut state = try!(self.serialize_seq(Some(value.len())));
for c in value {
try!(self.serialize_seq_elt(&mut state, c));
}
self.serialize_seq_end(state)
}
}
+4 -4
View File
@@ -38,7 +38,7 @@ pub enum Token<'a> {
TupleSep,
TupleEnd,
TupleStructStart(&'a str, Option<usize>),
TupleStructStart(&'a str, usize),
TupleStructSep,
TupleStructEnd,
@@ -46,15 +46,15 @@ pub enum Token<'a> {
MapSep,
MapEnd,
StructStart(&'a str, Option<usize>),
StructStart(&'a str, usize),
StructSep,
StructEnd,
EnumSeqStart(&'a str, &'a str, Option<usize>),
EnumSeqStart(&'a str, &'a str, usize),
EnumSeqSep,
EnumSeqEnd,
EnumMapStart(&'a str, &'a str, Option<usize>),
EnumMapStart(&'a str, &'a str, usize),
EnumMapSep,
EnumMapEnd,
}
+5 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_testing"
version = "0.7.12"
version = "0.8.0-rc2"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
@@ -11,16 +11,16 @@ keywords = ["serialization"]
build = "build.rs"
[features]
nightly-testing = ["clippy", "serde/nightly-testing", "serde_codegen/nightly-testing"]
unstable-testing = ["clippy", "serde/unstable-testing", "serde_codegen/unstable-testing"]
[build-dependencies]
serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-syntex"] }
serde_codegen = { path = "../serde_codegen", features = ["with-syntex"] }
[dev-dependencies]
fnv = "1.0"
rustc-serialize = "^0.3.16"
serde = { version = "*", path = "../serde" }
serde_test = { version = "*", path = "../serde_test" }
serde = { path = "../serde" }
serde_test = { path = "../serde_test" }
[dependencies]
clippy = { version = "^0.*", optional = true }
+2 -2
View File
@@ -1,6 +1,6 @@
#![feature(test)]
#![cfg_attr(feature = "nightly", feature(plugin))]
#![cfg_attr(feature = "nightly", plugin(clippy))]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
extern crate rustc_serialize;
extern crate serde;
+2 -2
View File
@@ -1,4 +1,4 @@
#![cfg_attr(feature = "nightly", feature(plugin))]
#![cfg_attr(feature = "nightly", plugin(clippy))]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
include!(concat!(env!("OUT_DIR"), "/test.rs"));
+61 -33
View File
@@ -82,7 +82,7 @@ fn test_default_struct() {
assert_de_tokens(
&DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
&[
Token::StructStart("DefaultStruct", Some(3)),
Token::StructStart("DefaultStruct", 3),
Token::StructSep,
Token::Str("a1"),
@@ -111,7 +111,7 @@ fn test_default_struct() {
assert_de_tokens(
&DefaultStruct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 },
&[
Token::StructStart("DefaultStruct", Some(1)),
Token::StructStart("DefaultStruct", 1),
Token::StructSep,
Token::Str("a1"),
@@ -145,7 +145,7 @@ fn test_default_enum() {
assert_de_tokens(
&DefaultEnum::Struct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
&[
Token::EnumMapStart("DefaultEnum", "Struct", Some(5)),
Token::EnumMapStart("DefaultEnum", "Struct", 5),
Token::EnumMapSep,
Token::Str("a1"),
@@ -174,7 +174,7 @@ fn test_default_enum() {
assert_de_tokens(
&DefaultEnum::Struct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 },
&[
Token::EnumMapStart("DefaultEnum", "Struct", Some(5)),
Token::EnumMapStart("DefaultEnum", "Struct", 5),
Token::EnumMapSep,
Token::Str("a1"),
@@ -208,7 +208,7 @@ fn test_no_std_default() {
assert_de_tokens(
&ContainsNoStdDefault { a: NoStdDefault(123) },
&[
Token::StructStart("ContainsNoStdDefault", Some(1)),
Token::StructStart("ContainsNoStdDefault", 1),
Token::StructEnd,
]
);
@@ -216,7 +216,7 @@ fn test_no_std_default() {
assert_de_tokens(
&ContainsNoStdDefault { a: NoStdDefault(8) },
&[
Token::StructStart("ContainsNoStdDefault", Some(1)),
Token::StructStart("ContainsNoStdDefault", 1),
Token::StructSep,
Token::Str("a"),
@@ -281,7 +281,7 @@ fn test_elt_not_deserialize() {
e: NotDeserializeEnum::Trouble,
},
&[
Token::StructStart("ContainsNotDeserialize", Some(3)),
Token::StructStart("ContainsNotDeserialize", 3),
Token::StructEnd,
]
);
@@ -299,7 +299,7 @@ fn test_ignore_unknown() {
assert_de_tokens(
&DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
&[
Token::StructStart("DefaultStruct", Some(5)),
Token::StructStart("DefaultStruct", 5),
Token::StructSep,
Token::Str("whoops1"),
@@ -334,7 +334,7 @@ fn test_ignore_unknown() {
assert_de_tokens_error::<DenyUnknown>(
&[
Token::StructStart("DenyUnknown", Some(2)),
Token::StructStart("DenyUnknown", 2),
Token::StructSep,
Token::Str("a1"),
@@ -368,7 +368,7 @@ fn test_rename_struct() {
assert_tokens(
&RenameStruct { a1: 1, a2: 2 },
&[
Token::StructStart("Superhero", Some(2)),
Token::StructStart("Superhero", 2),
Token::StructSep,
Token::Str("a1"),
@@ -385,7 +385,7 @@ fn test_rename_struct() {
assert_ser_tokens(
&RenameStructSerializeDeserialize { a1: 1, a2: 2 },
&[
Token::StructStart("SuperheroSer", Some(2)),
Token::StructStart("SuperheroSer", 2),
Token::StructSep,
Token::Str("a1"),
@@ -402,7 +402,7 @@ fn test_rename_struct() {
assert_de_tokens(
&RenameStructSerializeDeserialize { a1: 1, a2: 2 },
&[
Token::StructStart("SuperheroDe", Some(2)),
Token::StructStart("SuperheroDe", 2),
Token::StructSep,
Token::Str("a1"),
@@ -465,7 +465,7 @@ fn test_rename_enum() {
assert_tokens(
&RenameEnum::WonderWoman(0, 1),
&[
Token::EnumSeqStart("Superhero", "diana_prince", Some(2)),
Token::EnumSeqStart("Superhero", "diana_prince", 2),
Token::EnumSeqSep,
Token::I8(0),
@@ -480,7 +480,7 @@ fn test_rename_enum() {
assert_tokens(
&RenameEnum::Flash { a: 1 },
&[
Token::EnumMapStart("Superhero", "barry_allan", Some(1)),
Token::EnumMapStart("Superhero", "barry_allan", 1),
Token::EnumMapSep,
Token::Str("b"),
@@ -496,7 +496,7 @@ fn test_rename_enum() {
b: String::new(),
},
&[
Token::EnumMapStart("SuperheroSer", "dick_grayson", Some(2)),
Token::EnumMapStart("SuperheroSer", "dick_grayson", 2),
Token::EnumMapSep,
Token::Str("a"),
@@ -516,7 +516,7 @@ fn test_rename_enum() {
b: String::new(),
},
&[
Token::EnumMapStart("SuperheroDe", "jason_todd", Some(2)),
Token::EnumMapStart("SuperheroDe", "jason_todd", 2),
Token::EnumMapSep,
Token::Str("a"),
@@ -550,7 +550,7 @@ fn test_skip_serializing_struct() {
c: 3,
},
&[
Token::StructStart("SkipSerializingStruct", Some(2)),
Token::StructStart("SkipSerializingStruct", 2),
Token::StructSep,
Token::Str("a"),
@@ -571,7 +571,7 @@ fn test_skip_serializing_struct() {
c: 123,
},
&[
Token::StructStart("SkipSerializingStruct", Some(1)),
Token::StructStart("SkipSerializingStruct", 1),
Token::StructSep,
Token::Str("a"),
@@ -603,7 +603,7 @@ fn test_skip_serializing_enum() {
c: 3,
},
&[
Token::EnumMapStart("SkipSerializingEnum", "Struct", Some(2)),
Token::EnumMapStart("SkipSerializingEnum", "Struct", 2),
Token::EnumMapSep,
Token::Str("a"),
@@ -624,7 +624,7 @@ fn test_skip_serializing_enum() {
c: 123,
},
&[
Token::EnumMapStart("SkipSerializingEnum", "Struct", Some(1)),
Token::EnumMapStart("SkipSerializingEnum", "Struct", 1),
Token::EnumMapSep,
Token::Str("a"),
@@ -671,7 +671,7 @@ fn test_elt_not_serialize() {
d: NotSerializeEnum::Trouble,
},
&[
Token::StructStart("ContainsNotSerialize", Some(2)),
Token::StructStart("ContainsNotSerialize", 2),
Token::StructSep,
Token::Str("a"),
@@ -703,7 +703,7 @@ fn test_serialize_with_struct() {
b: 2,
},
&[
Token::StructStart("SerializeWithStruct", Some(2)),
Token::StructStart("SerializeWithStruct", 2),
Token::StructSep,
Token::Str("a"),
@@ -723,7 +723,7 @@ fn test_serialize_with_struct() {
b: 123,
},
&[
Token::StructStart("SerializeWithStruct", Some(2)),
Token::StructStart("SerializeWithStruct", 2),
Token::StructSep,
Token::Str("a"),
@@ -756,7 +756,7 @@ fn test_serialize_with_enum() {
b: 2,
},
&[
Token::EnumMapStart("SerializeWithEnum", "Struct", Some(2)),
Token::EnumMapStart("SerializeWithEnum", "Struct", 2),
Token::EnumMapSep,
Token::Str("a"),
@@ -776,7 +776,7 @@ fn test_serialize_with_enum() {
b: 123,
},
&[
Token::EnumMapStart("SerializeWithEnum", "Struct", Some(2)),
Token::EnumMapStart("SerializeWithEnum", "Struct", 2),
Token::EnumMapSep,
Token::Str("a"),
@@ -806,7 +806,7 @@ fn test_deserialize_with_struct() {
b: 2,
},
&[
Token::StructStart("DeserializeWithStruct", Some(2)),
Token::StructStart("DeserializeWithStruct", 2),
Token::StructSep,
Token::Str("a"),
@@ -826,7 +826,7 @@ fn test_deserialize_with_struct() {
b: 123,
},
&[
Token::StructStart("DeserializeWithStruct", Some(2)),
Token::StructStart("DeserializeWithStruct", 2),
Token::StructSep,
Token::Str("a"),
@@ -858,7 +858,7 @@ fn test_deserialize_with_enum() {
b: 2,
},
&[
Token::EnumMapStart("DeserializeWithEnum", "Struct", Some(2)),
Token::EnumMapStart("DeserializeWithEnum", "Struct", 2),
Token::EnumMapSep,
Token::Str("a"),
@@ -878,7 +878,7 @@ fn test_deserialize_with_enum() {
b: 123,
},
&[
Token::EnumMapStart("DeserializeWithEnum", "Struct", Some(2)),
Token::EnumMapStart("DeserializeWithEnum", "Struct", 2),
Token::EnumMapSep,
Token::Str("a"),
@@ -897,7 +897,7 @@ fn test_deserialize_with_enum() {
fn test_missing_renamed_field_struct() {
assert_de_tokens_error::<RenameStruct>(
&[
Token::StructStart("Superhero", Some(2)),
Token::StructStart("Superhero", 2),
Token::StructSep,
Token::Str("a1"),
@@ -910,7 +910,7 @@ fn test_missing_renamed_field_struct() {
assert_de_tokens_error::<RenameStructSerializeDeserialize>(
&[
Token::StructStart("SuperheroDe", Some(2)),
Token::StructStart("SuperheroDe", 2),
Token::StructSep,
Token::Str("a1"),
@@ -926,7 +926,7 @@ fn test_missing_renamed_field_struct() {
fn test_missing_renamed_field_enum() {
assert_de_tokens_error::<RenameEnum>(
&[
Token::EnumMapStart("Superhero", "barry_allan", Some(1)),
Token::EnumMapStart("Superhero", "barry_allan", 1),
Token::EnumMapEnd,
],
@@ -935,7 +935,7 @@ fn test_missing_renamed_field_enum() {
assert_de_tokens_error::<RenameEnumSerializeDeserialize<i8>>(
&[
Token::EnumMapStart("SuperheroDe", "jason_todd", Some(2)),
Token::EnumMapStart("SuperheroDe", "jason_todd", 2),
Token::EnumMapSep,
Token::Str("a"),
@@ -946,3 +946,31 @@ fn test_missing_renamed_field_enum() {
Error::MissingField("d"),
);
}
#[derive(Debug, PartialEq, Deserialize)]
enum InvalidLengthEnum {
A(i32, i32, i32),
B(#[serde(skip_deserializing)] i32, i32, i32),
}
#[test]
fn test_invalid_length_enum() {
assert_de_tokens_error::<InvalidLengthEnum>(
&[
Token::EnumSeqStart("InvalidLengthEnum", "A", 3),
Token::EnumSeqSep,
Token::I32(1),
Token::EnumSeqEnd,
],
Error::InvalidLength(1),
);
assert_de_tokens_error::<InvalidLengthEnum>(
&[
Token::EnumSeqStart("InvalidLengthEnum", "B", 3),
Token::EnumSeqSep,
Token::I32(1),
Token::EnumSeqEnd,
],
Error::InvalidLength(1),
);
}
+158 -6
View File
@@ -52,15 +52,62 @@ impl BytesSerializer {
impl serde::Serializer for BytesSerializer {
type Error = Error;
type SeqState = ();
type MapState = ();
type TupleState = ();
type TupleStructState = ();
type TupleVariantState = ();
type StructState = ();
type StructVariantState = ();
fn serialize_unit(&mut self) -> Result<(), Error> {
Err(Error)
}
fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<(), Error> {
Err(Error)
}
fn serialize_unit_variant(&mut self, _: &'static str, _: usize, _: &'static str) -> Result<(), Error> {
Err(Error)
}
fn serialize_bool(&mut self, _v: bool) -> Result<(), Error> {
Err(Error)
}
fn serialize_isize(&mut self, _v: isize) -> Result<(), Error> {
Err(Error)
}
fn serialize_usize(&mut self, _v: usize) -> Result<(), Error> {
Err(Error)
}
fn serialize_i8(&mut self, _v: i8) -> Result<(), Error> {
Err(Error)
}
fn serialize_u8(&mut self, _v: u8) -> Result<(), Error> {
Err(Error)
}
fn serialize_i16(&mut self, _v: i16) -> Result<(), Error> {
Err(Error)
}
fn serialize_u16(&mut self, _v: u16) -> Result<(), Error> {
Err(Error)
}
fn serialize_i32(&mut self, _v: i32) -> Result<(), Error> {
Err(Error)
}
fn serialize_u32(&mut self, _v: u32) -> Result<(), Error> {
Err(Error)
}
fn serialize_i64(&mut self, _v: i64) -> Result<(), Error> {
Err(Error)
}
@@ -95,31 +142,136 @@ impl serde::Serializer for BytesSerializer {
Err(Error)
}
fn serialize_seq<V>(&mut self, _visitor: V) -> Result<(), Error>
where V: serde::ser::SeqVisitor,
fn serialize_newtype_struct<V>(&mut self, _: &'static str, _value: V) -> Result<(), Error>
where V: serde::Serialize,
{
Err(Error)
}
fn serialize_seq_elt<T>(&mut self, _value: T) -> Result<(), Error>
fn serialize_newtype_variant<V>(&mut self, _: &'static str, _: usize, _: &'static str, _value: V) -> Result<(), Error>
where V: serde::Serialize,
{
Err(Error)
}
fn serialize_seq(&mut self, _len: Option<usize>) -> Result<(), Error>
{
Err(Error)
}
fn serialize_seq_fixed_size(&mut self, _len: usize) -> Result<(), Error>
{
Err(Error)
}
fn serialize_seq_elt<T>(&mut self, _: &mut (), _value: T) -> Result<(), Error>
where T: serde::Serialize
{
Err(Error)
}
fn serialize_map<V>(&mut self, _visitor: V) -> Result<(), Error>
where V: serde::ser::MapVisitor,
fn serialize_seq_end(&mut self, _: ()) -> Result<(), Error>
{
Err(Error)
}
fn serialize_map_elt<K, V>(&mut self, _key: K, _value: V) -> Result<(), Error>
fn serialize_tuple(&mut self, _len: usize) -> Result<(), Error>
{
Err(Error)
}
fn serialize_tuple_elt<T>(&mut self, _: &mut (), _value: T) -> Result<(), Error>
where T: serde::Serialize
{
Err(Error)
}
fn serialize_tuple_end(&mut self, _: ()) -> Result<(), Error>
{
Err(Error)
}
fn serialize_tuple_struct(&mut self, _: &'static str, _len: usize) -> Result<(), Error>
{
Err(Error)
}
fn serialize_tuple_struct_elt<T>(&mut self, _: &mut (), _value: T) -> Result<(), Error>
where T: serde::Serialize
{
Err(Error)
}
fn serialize_tuple_struct_end(&mut self, _: ()) -> Result<(), Error>
{
Err(Error)
}
fn serialize_tuple_variant(&mut self, _: &'static str, _: usize, _: &'static str, _len: usize) -> Result<(), Error>
{
Err(Error)
}
fn serialize_tuple_variant_elt<T>(&mut self, _: &mut (), _value: T) -> Result<(), Error>
where T: serde::Serialize
{
Err(Error)
}
fn serialize_tuple_variant_end(&mut self, _: ()) -> Result<(), Error>
{
Err(Error)
}
fn serialize_map(&mut self, _: Option<usize>) -> Result<(), Error>
{
Err(Error)
}
fn serialize_map_elt<K, V>(&mut self, _: &mut (), _key: K, _value: V) -> Result<(), Error>
where K: serde::Serialize,
V: serde::Serialize,
{
Err(Error)
}
fn serialize_map_end(&mut self, _: ()) -> Result<(), Error>
{
Err(Error)
}
fn serialize_struct(&mut self, _: &'static str, _: usize) -> Result<(), Error>
{
Err(Error)
}
fn serialize_struct_elt<V>(&mut self, _: &mut (), _key: &'static str, _value: V) -> Result<(), Error>
where V: serde::Serialize,
{
Err(Error)
}
fn serialize_struct_end(&mut self, _: ()) -> Result<(), Error>
{
Err(Error)
}
fn serialize_struct_variant(&mut self, _: &'static str, _: usize, _: &'static str, _: usize) -> Result<(), Error>
{
Err(Error)
}
fn serialize_struct_variant_elt<V>(&mut self, _: &mut (), _key: &'static str, _value: V) -> Result<(), Error>
where V: serde::Serialize,
{
Err(Error)
}
fn serialize_struct_variant_end(&mut self, _: ()) -> Result<(), Error>
{
Err(Error)
}
fn serialize_bytes(&mut self, bytes: &[u8]) -> Result<(), Error> {
assert_eq!(self.bytes, bytes);
Ok(())
+21 -21
View File
@@ -81,9 +81,9 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token<'static>]) {
struct IgnoreBase {
a: i32,
}
let expected = IgnoreBase{a: 1};
// Embed the tokens to be ignored in the normal token
// stream for an IgnoreBase type
let concated_tokens : Vec<Token<'static>> = vec![
@@ -91,7 +91,7 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token<'static>]) {
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep,
Token::Str("ignored")
]
@@ -101,17 +101,17 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token<'static>]) {
Token::MapEnd,
].into_iter())
.collect();
let mut de = serde_test::Deserializer::new(concated_tokens.into_iter());
let v: Result<IgnoreBase, Error> = Deserialize::deserialize(&mut de);
// We run this test on every token stream for convenience, but
// some token streams don't make sense embedded as a map value,
// so we ignore those. SyntaxError is the real sign of trouble.
if let Err(Error::UnexpectedToken(_)) = v {
return;
}
assert_eq!(v.as_ref(), Ok(&expected));
assert_eq!(de.next_token(), None);
}
@@ -197,7 +197,7 @@ declare_tests! {
Token::SeqEnd,
],
() => &[
Token::TupleStructStart("Anything", Some(0)),
Token::TupleStructStart("Anything", 0),
Token::SeqEnd,
],
}
@@ -241,7 +241,7 @@ declare_tests! {
Token::SeqEnd,
],
TupleStruct(1, 2, 3) => &[
Token::TupleStructStart("TupleStruct", Some(3)),
Token::TupleStructStart("TupleStruct", 3),
Token::TupleStructSep,
Token::I32(1),
@@ -253,7 +253,7 @@ declare_tests! {
Token::TupleStructEnd,
],
TupleStruct(1, 2, 3) => &[
Token::TupleStructStart("TupleStruct", None),
Token::TupleStructStart("TupleStruct", 3),
Token::TupleStructSep,
Token::I32(1),
@@ -299,7 +299,7 @@ declare_tests! {
Token::UnitStruct("Anything"),
],
BTreeSet::<isize>::new() => &[
Token::TupleStructStart("Anything", Some(0)),
Token::TupleStructStart("Anything", 0),
Token::SeqEnd,
],
}
@@ -327,7 +327,7 @@ declare_tests! {
Token::UnitStruct("Anything"),
],
HashSet::<isize>::new() => &[
Token::TupleStructStart("Anything", Some(0)),
Token::TupleStructStart("Anything", 0),
Token::SeqEnd,
],
hashset![FnvHasher @ 1, 2, 3] => &[
@@ -377,7 +377,7 @@ declare_tests! {
Token::UnitStruct("Anything"),
],
Vec::<isize>::new() => &[
Token::TupleStructStart("Anything", Some(0)),
Token::TupleStructStart("Anything", 0),
Token::SeqEnd,
],
}
@@ -441,7 +441,7 @@ declare_tests! {
Token::UnitStruct("Anything"),
],
[0; 0] => &[
Token::TupleStructStart("Anything", Some(0)),
Token::TupleStructStart("Anything", 0),
Token::SeqEnd,
],
}
@@ -533,7 +533,7 @@ declare_tests! {
Token::UnitStruct("Anything"),
],
BTreeMap::<isize, isize>::new() => &[
Token::StructStart("Anything", Some(0)),
Token::StructStart("Anything", 0),
Token::MapEnd,
],
}
@@ -587,7 +587,7 @@ declare_tests! {
Token::UnitStruct("Anything"),
],
HashMap::<isize, isize>::new() => &[
Token::StructStart("Anything", Some(0)),
Token::StructStart("Anything", 0),
Token::MapEnd,
],
hashmap![FnvHasher @ 1 => 2, 3 => 4] => &[
@@ -615,7 +615,7 @@ declare_tests! {
Token::MapEnd,
],
Struct { a: 1, b: 2, c: 0 } => &[
Token::StructStart("Struct", Some(3)),
Token::StructStart("Struct", 3),
Token::StructSep,
Token::Str("a"),
Token::I32(1),
@@ -656,7 +656,7 @@ declare_tests! {
Token::MapEnd,
],
Struct { a: 1, b: 2, c: 0 } => &[
Token::StructStart("Struct", Some(3)),
Token::StructStart("Struct", 3),
Token::StructSep,
Token::Str("a"),
Token::I32(1),
@@ -688,7 +688,7 @@ declare_tests! {
}
test_enum_seq {
Enum::Seq(1, 2, 3) => &[
Token::EnumSeqStart("Enum", "Seq", Some(3)),
Token::EnumSeqStart("Enum", "Seq", 3),
Token::EnumSeqSep,
Token::I32(1),
@@ -702,7 +702,7 @@ declare_tests! {
}
test_enum_map {
Enum::Map { a: 1, b: 2, c: 3 } => &[
Token::EnumMapStart("Enum", "Map", Some(3)),
Token::EnumMapStart("Enum", "Map", 3),
Token::EnumMapSep,
Token::Str("a"),
Token::I32(1),
@@ -764,7 +764,7 @@ declare_tests! {
}
}
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
#[test]
fn test_net_ipaddr() {
assert_de_tokens(
@@ -803,7 +803,7 @@ declare_error_tests! {
}
test_duplicate_field_enum<Enum> {
&[
Token::EnumMapStart("Enum", "Map", Some(3)),
Token::EnumMapStart("Enum", "Map", 3),
Token::EnumMapSep,
Token::Str("a"),
Token::I32(1),
+15 -15
View File
@@ -174,7 +174,7 @@ fn test_ser_named_tuple() {
assert_ser_tokens(
&SerNamedTuple(&a, &mut b, c),
&[
Token::TupleStructStart("SerNamedTuple", Some(3)),
Token::TupleStructStart("SerNamedTuple", 3),
Token::TupleStructSep,
Token::I32(5),
@@ -211,7 +211,7 @@ fn test_de_named_tuple() {
assert_de_tokens(
&DeNamedTuple(5, 6, 7),
&[
Token::TupleStructStart("DeNamedTuple", Some(3)),
Token::TupleStructStart("DeNamedTuple", 3),
Token::TupleStructSep,
Token::I32(5),
@@ -239,7 +239,7 @@ fn test_ser_named_map() {
c: c,
},
&[
Token::StructStart("SerNamedMap", Some(3)),
Token::StructStart("SerNamedMap", 3),
Token::StructSep,
Token::Str("a"),
@@ -267,7 +267,7 @@ fn test_de_named_map() {
c: 7,
},
&[
Token::StructStart("DeNamedMap", Some(3)),
Token::StructStart("DeNamedMap", 3),
Token::StructSep,
Token::Str("a"),
@@ -315,7 +315,7 @@ fn test_ser_enum_seq() {
//f,
),
&[
Token::EnumSeqStart("SerEnum", "Seq", Some(4)),
Token::EnumSeqStart("SerEnum", "Seq", 4),
Token::EnumSeqSep,
Token::I8(1),
@@ -353,7 +353,7 @@ fn test_ser_enum_map() {
//f: f,
},
&[
Token::EnumMapStart("SerEnum", "Map", Some(4)),
Token::EnumMapStart("SerEnum", "Map", 4),
Token::EnumMapSep,
Token::Str("a"),
@@ -405,7 +405,7 @@ fn test_de_enum_seq() {
//f,
),
&[
Token::EnumSeqStart("DeEnum", "Seq", Some(4)),
Token::EnumSeqStart("DeEnum", "Seq", 4),
Token::EnumSeqSep,
Token::I8(1),
@@ -443,7 +443,7 @@ fn test_de_enum_map() {
//f: f,
},
&[
Token::EnumMapStart("DeEnum", "Map", Some(4)),
Token::EnumMapStart("DeEnum", "Map", 4),
Token::EnumMapSep,
Token::Str("a"),
@@ -489,7 +489,7 @@ fn test_lifetimes() {
assert_ser_tokens(
&Lifetimes::LifetimeMap { a: &value },
&[
Token::EnumMapStart("Lifetimes", "LifetimeMap", Some(1)),
Token::EnumMapStart("Lifetimes", "LifetimeMap", 1),
Token::EnumMapSep,
Token::Str("a"),
@@ -502,7 +502,7 @@ fn test_lifetimes() {
assert_ser_tokens(
&Lifetimes::NoLifetimeMap { a: 5 },
&[
Token::EnumMapStart("Lifetimes", "NoLifetimeMap", Some(1)),
Token::EnumMapStart("Lifetimes", "NoLifetimeMap", 1),
Token::EnumMapSep,
Token::Str("a"),
@@ -518,7 +518,7 @@ fn test_generic_struct() {
assert_tokens(
&GenericStruct { x: 5u32 },
&[
Token::StructStart("GenericStruct", Some(1)),
Token::StructStart("GenericStruct", 1),
Token::StructSep,
Token::Str("x"),
@@ -545,7 +545,7 @@ fn test_generic_tuple_struct() {
assert_tokens(
&GenericTupleStruct(5u32, 6u32),
&[
Token::TupleStructStart("GenericTupleStruct", Some(2)),
Token::TupleStructStart("GenericTupleStruct", 2),
Token::TupleStructSep,
Token::U32(5),
@@ -584,7 +584,7 @@ fn test_generic_enum_seq() {
assert_tokens(
&GenericEnum::Seq::<u32, u32>(5, 6),
&[
Token::EnumSeqStart("GenericEnum", "Seq", Some(2)),
Token::EnumSeqStart("GenericEnum", "Seq", 2),
Token::EnumSeqSep,
Token::U32(5),
@@ -602,7 +602,7 @@ fn test_generic_enum_map() {
assert_tokens(
&GenericEnum::Map::<u32, u32> { x: 5, y: 6 },
&[
Token::EnumMapStart("GenericEnum", "Map", Some(2)),
Token::EnumMapStart("GenericEnum", "Map", 2),
Token::EnumMapSep,
Token::Str("x"),
@@ -622,7 +622,7 @@ fn test_default_ty_param() {
assert_tokens(
&DefaultTyParam::<i32> { phantom: PhantomData },
&[
Token::StructStart("DefaultTyParam", Some(1)),
Token::StructStart("DefaultTyParam", 1),
Token::StructSep,
Token::Str("phantom"),
+5 -5
View File
@@ -256,7 +256,7 @@ declare_ser_tests! {
}
test_tuple_struct {
TupleStruct(1, 2, 3) => &[
Token::TupleStructStart("TupleStruct", Some(3)),
Token::TupleStructStart("TupleStruct", 3),
Token::TupleStructSep,
Token::I32(1),
@@ -270,7 +270,7 @@ declare_ser_tests! {
}
test_struct {
Struct { a: 1, b: 2, c: 3 } => &[
Token::StructStart("Struct", Some(3)),
Token::StructStart("Struct", 3),
Token::StructSep,
Token::Str("a"),
Token::I32(1),
@@ -289,7 +289,7 @@ declare_ser_tests! {
Enum::Unit => &[Token::EnumUnit("Enum", "Unit")],
Enum::One(42) => &[Token::EnumNewType("Enum", "One"), Token::I32(42)],
Enum::Seq(1, 2) => &[
Token::EnumSeqStart("Enum", "Seq", Some(2)),
Token::EnumSeqStart("Enum", "Seq", 2),
Token::EnumSeqSep,
Token::I32(1),
@@ -298,7 +298,7 @@ declare_ser_tests! {
Token::EnumSeqEnd,
],
Enum::Map { a: 1, b: 2 } => &[
Token::EnumMapStart("Enum", "Map", Some(2)),
Token::EnumMapStart("Enum", "Map", 2),
Token::EnumMapSep,
Token::Str("a"),
Token::I32(1),
@@ -347,7 +347,7 @@ declare_ser_tests! {
}
}
#[cfg(feature = "nightly")]
#[cfg(feature = "unstable")]
#[test]
fn test_net_ipaddr() {
assert_ser_tokens(