Compare commits

...

44 Commits

Author SHA1 Message Date
David Tolnay 78e74886be Update syntex to 0.39 2016-07-26 09:22:33 -07: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
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 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
David Tolnay 5deba439c3 Merge pull request #417 from serde-rs/bump
Update syntex to 0.37
2016-07-03 08:53:56 -07:00
David Tolnay d450de1482 Update syntex to 0.37 2016-07-02 20:20:44 -07:00
David Tolnay 47c7387279 Merge pull request #416 from dtolnay/filter
Remove filter no longer necessary for rustc >=1.7
2016-07-01 22:53:45 -07:00
David Tolnay dc8d209f29 Remove filter no longer necessary for rustc >=1.7 2016-07-01 22:34:15 -07:00
David Tolnay 831802adc8 Merge pull request #407 from dtolnay/internals
Rename serde_item to serde_codegen_internals
2016-06-30 20:06:12 -07:00
David Tolnay 2d5a26dfc0 Rename serde_internals to serde_codegen_internals 2016-06-30 19:53:57 -07:00
David Tolnay c6b6e2a5d9 Rename serde_item to serde_internals 2016-06-30 19:42:55 -07:00
Oliver Schneider d1be5ef187 Merge pull request #412 from dtolnay/test
Move Token De/Serializer to serde_test crate
2016-06-29 10:05:36 +02:00
David Tolnay f531be1524 Turn comments into doc comments 2016-06-29 00:58:33 -07:00
David Tolnay 10b1508d4a Sync serde_test version with the other crates 2016-06-29 00:17:50 -07:00
David Tolnay 041d5c0842 Make serde_test asserts more consistent 2016-06-28 23:50:19 -07:00
David Tolnay 7d09053bb8 Fix declare_ser_tests to work on old rustc 2016-06-28 23:09:37 -07:00
David Tolnay 8e87926bc2 Round out the Error variants 2016-06-28 22:57:53 -07:00
David Tolnay d6a462b862 Add serde_test to dev dependencies of serde_macros 2016-06-28 22:50:58 -07:00
David Tolnay cfc2f9adc0 Remove Error from name of Error variants 2016-06-28 22:49:13 -07:00
David Tolnay 00f94290a6 Add message to CustomError 2016-06-28 22:36:29 -07:00
David Tolnay 093201abfb Assert tokens are empty after reaching error 2016-06-28 22:23:38 -07:00
David Tolnay 6d64104375 Factor the Token De/Serializer into serde_test 2016-06-28 21:54:51 -07:00
David Tolnay fb0e62951f Rename serde_tests to testing 2016-06-28 20:43:59 -07:00
Erick Tryzelaar 18e077eda9 Add a contributing guide 2016-06-22 07:04:13 -07:00
50 changed files with 1391 additions and 1065 deletions
+7
View File
@@ -0,0 +1,7 @@
paths = [
"serde",
"serde_codegen",
"serde_codegen_internals",
"serde_macros",
"serde_test",
]
+5 -5
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:
@@ -22,15 +22,15 @@ script:
- (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 serde_tests && travis-cargo --skip nightly test)
- (cd serde_tests && travis-cargo --only nightly test -- --features nightly-testing)
- (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 serde && travis-cargo --only stable doc)
after_success:
- (cd serde && travis-cargo --only stable doc-upload)
- (cd serde_tests && travis-cargo --only stable coveralls --no-sudo)
- (cd testing && travis-cargo --only stable coveralls --no-sudo)
env:
global:
- TRAVIS_CARGO_NIGHTLY_FEATURE=""
+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",
]
+4 -4
View File
@@ -9,9 +9,9 @@ default = ["serde_codegen"]
nightly = ["serde_macros"]
[build-dependencies]
serde_codegen = { version = "^0.7.11", optional = true }
serde_codegen = { version = "^0.7", optional = true }
[dependencies]
serde = "^0.7.11"
serde_json = "^0.7.0"
serde_macros = { version = "^0.7.11", optional = true }
serde = "^0.7"
serde_json = "^0.7"
serde_macros = { version = "^0.7", optional = true }
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "0.7.11"
version = "0.7.15"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
+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.
+10 -10
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_codegen"
version = "0.7.11"
version = "0.7.15"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
@@ -18,20 +18,20 @@ with-syntex = [
"quasi/with-syntex",
"quasi_codegen",
"quasi_codegen/with-syntex",
"serde_item/with-syntex",
"serde_codegen_internals/with-syntex",
"syntex",
"syntex_syntax",
]
[build-dependencies]
quasi_codegen = { version = "^0.13.0", optional = true }
syntex = { version = "^0.36.0", optional = true }
quasi_codegen = { version = "^0.16.0", optional = true }
syntex = { version = "^0.39.0", optional = true }
[dependencies]
aster = { version = "^0.19.0", default-features = false }
aster = { version = "^0.22.0", default-features = false }
clippy = { version = "^0.*", optional = true }
quasi = { version = "^0.13.0", default-features = false }
quasi_macros = { version = "^0.13.0", optional = true }
serde_item = { version = "^0.2.0", path = "../serde_item", default-features = false }
syntex = { version = "^0.36.0", optional = true }
syntex_syntax = { version = "^0.36.0", optional = true }
quasi = { version = "^0.16.0", default-features = false }
quasi_macros = { version = "^0.16.0", optional = true }
serde_codegen_internals = { version = "^0.4.0", default-features = false }
syntex = { version = "^0.39.0", optional = true }
syntex_syntax = { version = "^0.39.0", optional = true }
+4 -45
View File
@@ -1,12 +1,11 @@
use std::collections::HashSet;
use aster::AstBuilder;
use syntax::ast;
use syntax::ptr::P;
use syntax::visit;
use item::{attr, Item};
use internals::ast::Item;
use internals::attr;
// Remove the default from every type parameter because in the generated impls
// they look like associated types: "error: associated type bindings are not
@@ -62,8 +61,6 @@ pub fn with_bound<F>(
item.body.all_fields()
.filter(|&field| filter(&field.attrs))
.map(|field| &field.ty)
// TODO this filter can be removed later, see comment on function
.filter(|ty| contains_generic(ty, generics))
.filter(|ty| !contains_recursion(ty, item.ident))
.map(|ty| strip_reference(ty))
.map(|ty| builder.where_predicate()
@@ -75,44 +72,6 @@ pub fn with_bound<F>(
.build()
}
// Rust <1.7 enforces that `where` clauses involve generic type parameters. The
// corresponding compiler error is E0193. It is no longer enforced in Rust >=1.7
// so this filtering can be removed in the future when we stop supporting <1.7.
//
// E0193 means we must not generate a `where` clause like `i32: Serialize`
// because even though i32 implements Serialize, i32 is not a generic type
// parameter. Clauses like `T: Serialize` and `Option<T>: Serialize` are okay.
// This function decides whether a given type references any of the generic type
// parameters in the input `Generics`.
fn contains_generic(ty: &ast::Ty, generics: &ast::Generics) -> bool {
struct FindGeneric<'a> {
generic_names: &'a HashSet<ast::Name>,
found_generic: bool,
}
impl<'a, 'v> visit::Visitor<'v> for FindGeneric<'a> {
fn visit_path(&mut self, path: &'v ast::Path, _id: ast::NodeId) {
if !path.global
&& path.segments.len() == 1
&& self.generic_names.contains(&path.segments[0].identifier.name) {
self.found_generic = true;
} else {
visit::walk_path(self, path);
}
}
}
let generic_names: HashSet<_> = generics.ty_params.iter()
.map(|ty_param| ty_param.ident.name)
.collect();
let mut visitor = FindGeneric {
generic_names: &generic_names,
found_generic: false,
};
visit::walk_ty(&mut visitor, ty);
visitor.found_generic
}
// We do not attempt to generate any bounds based on field types that are
// directly recursive, as in:
//
@@ -137,8 +96,8 @@ fn contains_recursion(ty: &ast::Ty, ident: ast::Ident) -> bool {
ident: ast::Ident,
found_recursion: bool,
}
impl<'v> visit::Visitor<'v> for FindRecursion {
fn visit_path(&mut self, path: &'v ast::Path, _id: ast::NodeId) {
impl visit::Visitor for FindRecursion {
fn visit_path(&mut self, path: &ast::Path, _id: ast::NodeId) {
if !path.global
&& path.segments.len() == 1
&& path.segments[0].identifier == self.ident {
+42 -36
View File
@@ -5,10 +5,12 @@ use syntax::codemap::Span;
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use syntax::tokenstream::TokenTree;
use bound;
use error::Error;
use item::{self, attr};
use span;
use internals::ast::{Body, Field, Item, Style, Variant};
use internals::{attr, Error};
pub fn expand_derive_deserialize(
cx: &mut ExtCtxt,
@@ -27,9 +29,9 @@ pub fn expand_derive_deserialize(
}
};
let item = match item::Item::from_ast(cx, item) {
let item = match Item::from_ast(cx, item) {
Ok(item) => item,
Err(item::Error::UnexpectedItemKind) => {
Err(Error::UnexpectedItemKind) => {
cx.span_err(item.span,
"`#[derive(Deserialize)]` may only be applied to structs and enums");
return;
@@ -43,13 +45,13 @@ 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(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &item::Item,
item: &Item,
) -> P<ast::Item> {
let impl_generics = build_impl_generics(builder, &item);
@@ -88,7 +90,7 @@ fn deserialize_item(
// each generic field type that will be set to a default value.
fn build_impl_generics(
builder: &aster::AstBuilder,
item: &item::Item,
item: &Item,
) -> ast::Generics {
let generics = bound::without_defaults(item.generics);
@@ -131,12 +133,12 @@ fn requires_default(attrs: &attr::Field) -> bool {
fn deserialize_body(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &item::Item,
item: &Item,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
) -> P<ast::Expr> {
match item.body {
item::Body::Enum(ref variants) => {
Body::Enum(ref variants) => {
deserialize_item_enum(
cx,
builder,
@@ -146,7 +148,7 @@ fn deserialize_body(
variants,
&item.attrs)
}
item::Body::Struct(item::Style::Struct, ref fields) => {
Body::Struct(Style::Struct, ref fields) => {
if fields.iter().any(|field| field.ident.is_none()) {
cx.span_bug(item.span, "struct has unnamed fields")
}
@@ -161,8 +163,8 @@ fn deserialize_body(
fields,
&item.attrs)
}
item::Body::Struct(item::Style::Tuple, ref fields) |
item::Body::Struct(item::Style::Newtype, ref fields) => {
Body::Struct(Style::Tuple, ref fields) |
Body::Struct(Style::Newtype, ref fields) => {
if fields.iter().any(|field| field.ident.is_some()) {
cx.span_bug(item.span, "tuple struct has named fields")
}
@@ -177,7 +179,7 @@ fn deserialize_body(
fields,
&item.attrs)
}
item::Body::Struct(item::Style::Unit, _) => {
Body::Struct(Style::Unit, _) => {
deserialize_unit_struct(
cx,
builder,
@@ -308,7 +310,7 @@ fn deserialize_tuple(
variant_ident: Option<Ident>,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
fields: &[item::Field],
fields: &[Field],
item_attrs: &attr::Item,
) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause;
@@ -390,9 +392,10 @@ fn deserialize_seq(
type_ident: Ident,
type_path: ast::Path,
impl_generics: &ast::Generics,
fields: &[item::Field],
fields: &[Field],
is_struct: bool,
) -> P<ast::Expr> {
let mut index_in_seq = 0usize;
let let_values: Vec<_> = fields.iter()
.enumerate()
.map(|(i, field)| {
@@ -418,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();
@@ -470,8 +476,8 @@ fn deserialize_newtype_struct(
type_ident: Ident,
type_path: &ast::Path,
impl_generics: &ast::Generics,
field: &item::Field,
) -> Vec<ast::TokenTree> {
field: &Field,
) -> Vec<TokenTree> {
let value = match field.attrs.deserialize_with() {
None => {
let field_ty = &field.ty;
@@ -505,7 +511,7 @@ fn deserialize_struct(
variant_ident: Option<Ident>,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
fields: &[item::Field],
fields: &[Field],
item_attrs: &attr::Item,
) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause;
@@ -587,7 +593,7 @@ fn deserialize_item_enum(
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
variants: &[item::Variant],
variants: &[Variant],
item_attrs: &attr::Item
) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause;
@@ -678,19 +684,19 @@ fn deserialize_variant(
type_ident: Ident,
generics: &ast::Generics,
ty: P<ast::Ty>,
variant: &item::Variant,
variant: &Variant,
item_attrs: &attr::Item,
) -> P<ast::Expr> {
let variant_ident = variant.ident;
match variant.style {
item::Style::Unit => {
Style::Unit => {
quote_expr!(cx, {
try!(visitor.visit_unit());
Ok($type_ident::$variant_ident)
})
}
item::Style::Newtype => {
Style::Newtype => {
deserialize_newtype_variant(
cx,
builder,
@@ -700,7 +706,7 @@ fn deserialize_variant(
&variant.fields[0],
)
}
item::Style::Tuple => {
Style::Tuple => {
deserialize_tuple(
cx,
builder,
@@ -712,7 +718,7 @@ fn deserialize_variant(
item_attrs,
)
}
item::Style::Struct => {
Style::Struct => {
deserialize_struct(
cx,
builder,
@@ -733,7 +739,7 @@ fn deserialize_newtype_variant(
type_ident: Ident,
variant_ident: Ident,
impl_generics: &ast::Generics,
field: &item::Field,
field: &Field,
) -> P<ast::Expr> {
let visit = match field.attrs.deserialize_with() {
None => {
@@ -919,7 +925,7 @@ fn deserialize_struct_visitor(
type_ident: Ident,
struct_path: ast::Path,
impl_generics: &ast::Generics,
fields: &[item::Field],
fields: &[Field],
item_attrs: &attr::Item,
) -> (Vec<P<ast::Item>>, ast::Stmt, P<ast::Expr>) {
let field_exprs = fields.iter()
@@ -971,7 +977,7 @@ fn deserialize_map(
type_ident: Ident,
struct_path: ast::Path,
impl_generics: &ast::Generics,
fields: &[item::Field],
fields: &[Field],
item_attrs: &attr::Item,
) -> P<ast::Expr> {
// Create the field names for the fields.
@@ -1091,10 +1097,10 @@ fn deserialize_map(
}
}
$extract_values
try!(visitor.end());
$extract_values
Ok($result)
})
}
@@ -1187,14 +1193,14 @@ fn name_expr(
fn check_no_str(
cx: &ExtCtxt,
item: &item::Item,
) -> Result<(), Error> {
let fail = |field: &item::Field| {
item: &Item,
) -> Result<(), ()> {
let fail = |field: &Field| {
cx.span_err(
field.span,
"Serde does not support deserializing fields of type &str; \
consider using String instead");
Err(Error)
Err(())
};
for field in item.body.all_fields() {
-2
View File
@@ -1,2 +0,0 @@
/// Error returned if failed to parse attribute.
pub struct Error;
+1 -1
View File
@@ -7,7 +7,7 @@
extern crate aster;
extern crate quasi;
extern crate serde_item as item;
extern crate serde_codegen_internals as internals;
#[cfg(feature = "with-syntex")]
extern crate syntex;
+1 -1
View File
@@ -1,4 +1,4 @@
mod bound;
mod de;
mod error;
mod ser;
mod span;
+28 -26
View File
@@ -6,7 +6,9 @@ use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ptr::P;
use bound;
use item::{self, attr};
use span;
use internals::ast::{Body, Field, Item, Style, Variant};
use internals::{attr, Error};
pub fn expand_derive_serialize(
cx: &mut ExtCtxt,
@@ -25,9 +27,9 @@ pub fn expand_derive_serialize(
}
};
let item = match item::Item::from_ast(cx, item) {
let item = match Item::from_ast(cx, item) {
Ok(item) => item,
Err(item::Error::UnexpectedItemKind) => {
Err(Error::UnexpectedItemKind) => {
cx.span_err(item.span,
"`#[derive(Serialize)]` may only be applied to structs and enums");
return;
@@ -37,13 +39,13 @@ 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(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &item::Item,
item: &Item,
) -> P<ast::Item> {
let impl_generics = build_impl_generics(builder, &item);
@@ -81,7 +83,7 @@ fn serialize_item(
// field type that will be serialized by us.
fn build_impl_generics(
builder: &aster::AstBuilder,
item: &item::Item,
item: &Item,
) -> ast::Generics {
let generics = bound::without_defaults(item.generics);
@@ -114,12 +116,12 @@ fn needs_serialize_bound(attrs: &attr::Field) -> bool {
fn serialize_body(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &item::Item,
item: &Item,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
) -> P<ast::Expr> {
match item.body {
item::Body::Enum(ref variants) => {
Body::Enum(ref variants) => {
serialize_item_enum(
cx,
builder,
@@ -129,7 +131,7 @@ fn serialize_body(
variants,
&item.attrs)
}
item::Body::Struct(item::Style::Struct, ref fields) => {
Body::Struct(Style::Struct, ref fields) => {
if fields.iter().any(|field| field.ident.is_none()) {
cx.span_bug(item.span, "struct has unnamed fields")
}
@@ -142,7 +144,7 @@ fn serialize_body(
fields,
&item.attrs)
}
item::Body::Struct(item::Style::Tuple, ref fields) => {
Body::Struct(Style::Tuple, ref fields) => {
if fields.iter().any(|field| field.ident.is_some()) {
cx.span_bug(item.span, "tuple struct has named fields")
}
@@ -155,7 +157,7 @@ fn serialize_body(
fields,
&item.attrs)
}
item::Body::Struct(item::Style::Newtype, ref fields) => {
Body::Struct(Style::Newtype, ref fields) => {
serialize_newtype_struct(
cx,
builder,
@@ -164,7 +166,7 @@ fn serialize_body(
&fields[0],
&item.attrs)
}
item::Body::Struct(item::Style::Unit, _) => {
Body::Struct(Style::Unit, _) => {
serialize_unit_struct(
cx,
builder,
@@ -190,7 +192,7 @@ fn serialize_newtype_struct(
builder: &aster::AstBuilder,
impl_generics: &ast::Generics,
item_ty: P<ast::Ty>,
field: &item::Field,
field: &Field,
item_attrs: &attr::Item,
) -> P<ast::Expr> {
let type_name = name_expr(builder, item_attrs.name());
@@ -211,7 +213,7 @@ fn serialize_tuple_struct(
builder: &aster::AstBuilder,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
fields: &[item::Field],
fields: &[Field],
item_attrs: &attr::Item,
) -> P<ast::Expr> {
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
@@ -246,7 +248,7 @@ fn serialize_struct(
builder: &aster::AstBuilder,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
fields: &[item::Field],
fields: &[Field],
item_attrs: &attr::Item,
) -> P<ast::Expr> {
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
@@ -282,7 +284,7 @@ fn serialize_item_enum(
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
variants: &[item::Variant],
variants: &[Variant],
item_attrs: &attr::Item,
) -> P<ast::Expr> {
let arms: Vec<_> =
@@ -315,7 +317,7 @@ fn serialize_variant(
type_ident: Ident,
generics: &ast::Generics,
ty: P<ast::Ty>,
variant: &item::Variant,
variant: &Variant,
variant_index: usize,
item_attrs: &attr::Item,
) -> ast::Arm {
@@ -325,7 +327,7 @@ fn serialize_variant(
let variant_name = name_expr(builder, variant.attrs.name());
match variant.style {
item::Style::Unit => {
Style::Unit => {
quote_arm!(cx,
$type_ident::$variant_ident => {
_serde::ser::Serializer::serialize_unit_variant(
@@ -337,7 +339,7 @@ fn serialize_variant(
}
)
},
item::Style::Newtype => {
Style::Newtype => {
let expr = serialize_newtype_variant(
cx,
builder,
@@ -353,7 +355,7 @@ fn serialize_variant(
$type_ident::$variant_ident(ref __simple_value) => { $expr }
)
},
item::Style::Tuple => {
Style::Tuple => {
let field_names: Vec<ast::Ident> = (0 .. variant.fields.len())
.map(|i| builder.id(format!("__field{}", i)))
.collect();
@@ -382,7 +384,7 @@ fn serialize_variant(
$pat => { $expr }
)
}
item::Style::Struct => {
Style::Struct => {
let field_names: Vec<_> = (0 .. variant.fields.len())
.map(|i| builder.id(format!("__field{}", i)))
.collect();
@@ -432,7 +434,7 @@ fn serialize_newtype_variant(
variant_name: P<ast::Expr>,
item_ty: P<ast::Ty>,
generics: &ast::Generics,
field: &item::Field,
field: &Field,
) -> P<ast::Expr> {
let mut field_expr = quote_expr!(cx, __simple_value);
if let Some(path) = field.attrs.serialize_with() {
@@ -459,7 +461,7 @@ fn serialize_tuple_variant(
variant_name: P<ast::Expr>,
generics: &ast::Generics,
structure_ty: P<ast::Ty>,
fields: &[item::Field],
fields: &[Field],
field_names: Vec<Ident>,
) -> P<ast::Expr> {
let variant_ty = builder.ty().tuple()
@@ -510,7 +512,7 @@ fn serialize_struct_variant(
variant_name: P<ast::Expr>,
generics: &ast::Generics,
ty: P<ast::Ty>,
fields: &[item::Field],
fields: &[Field],
field_names: Vec<Ident>,
item_attrs: &attr::Item,
) -> P<ast::Expr> {
@@ -597,7 +599,7 @@ fn serialize_tuple_struct_visitor(
structure_ty: P<ast::Ty>,
variant_ty: P<ast::Ty>,
serializer_method: ast::Ident,
fields: &[item::Field],
fields: &[Field],
generics: &ast::Generics,
is_enum: bool,
) -> (P<ast::Item>, P<ast::Item>) {
@@ -678,7 +680,7 @@ fn serialize_struct_visitor(
structure_ty: P<ast::Ty>,
variant_ty: P<ast::Ty>,
serializer_method: ast::Ident,
fields: &[item::Field],
fields: &[Field],
generics: &ast::Generics,
is_enum: bool,
) -> (P<ast::Item>, P<ast::Item>) {
+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)
}
}
@@ -1,6 +1,6 @@
[package]
name = "serde_item"
version = "0.2.0"
name = "serde_codegen_internals"
version = "0.4.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "AST representation used by Serde codegen. Unstable."
@@ -12,8 +12,9 @@ include = ["Cargo.toml", "src/**/*.rs"]
[features]
default = ["with-syntex"]
nightly-testing = ["clippy"]
with-syntex = ["syntex_syntax"]
with-syntex = ["syntex_syntax", "syntex_errors"]
[dependencies]
clippy = { version = "^0.*", optional = true }
syntex_syntax = { version = "^0.36.0", optional = true }
syntex_syntax = { version = "^0.39.0", optional = true }
syntex_errors = { version = "^0.39.0", optional = true }
@@ -1,24 +1,10 @@
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
#![cfg_attr(feature = "nightly-testing", feature(plugin))]
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
#[cfg(feature = "with-syntex")]
#[macro_use]
extern crate syntex_syntax as syntax;
#[cfg(not(feature = "with-syntex"))]
#[macro_use]
extern crate syntax;
use syntax::ast;
use syntax::codemap;
use syntax::ext::base::ExtCtxt;
use syntax::ptr::P;
pub mod attr;
mod error;
pub use error::Error;
use attr;
use Error;
pub struct Item<'a> {
pub ident: ast::Ident,
@@ -1,7 +1,7 @@
use std::rc::Rc;
use syntax::ast::{self, TokenTree};
use syntax::attr;
use syntax::ast;
use syntax::attr::{self, HasAttrs};
use syntax::codemap::{Span, Spanned, respan};
use syntax::ext::base::ExtCtxt;
use syntax::fold::Folder;
@@ -10,6 +10,7 @@ use syntax::parse::token::{self, InternedString};
use syntax::parse;
use syntax::print::pprust::{lit_to_string, meta_item_to_string};
use syntax::ptr::P;
use syntax::tokenstream::{self, TokenTree};
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
// are `attr::Item::from_ast`, `attr::Variant::from_ast`, and
@@ -529,7 +530,7 @@ impl<'a, 'b> Folder for Respanner<'a, 'b> {
TokenTree::Delimited(span, ref delimed) => {
TokenTree::Delimited(
self.new_span(span),
Rc::new(ast::Delimited {
Rc::new(tokenstream::Delimited {
delim: delimed.delim,
open_span: delimed.open_span,
tts: self.fold_tts(&delimed.tts),
@@ -540,7 +541,7 @@ impl<'a, 'b> Folder for Respanner<'a, 'b> {
TokenTree::Sequence(span, ref seq) => {
TokenTree::Sequence(
self.new_span(span),
Rc::new(ast::SequenceRepetition {
Rc::new(tokenstream::SequenceRepetition {
tts: self.fold_tts(&seq.tts),
separator: seq.separator.clone().map(|tok| self.fold_token(tok)),
..**seq
+21
View File
@@ -0,0 +1,21 @@
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
#![cfg_attr(feature = "nightly-testing", feature(plugin))]
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
#[cfg(feature = "with-syntex")]
#[macro_use]
extern crate syntex_syntax as syntax;
#[cfg(feature = "with-syntex")]
extern crate syntex_errors as errors;
#[cfg(not(feature = "with-syntex"))]
#[macro_use]
extern crate syntax;
#[cfg(not(feature = "with-syntex"))]
extern crate rustc_errors as errors;
pub mod ast;
pub mod attr;
mod error;
pub use error::Error;
+5 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_macros"
version = "0.7.11"
version = "0.7.15"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
@@ -18,13 +18,15 @@ nightly-testing = ["clippy", "serde/nightly-testing", "serde_codegen/nightly-tes
[dependencies]
clippy = { version = "^0.*", optional = true }
serde_codegen = { version = "^0.7.11", path = "../serde_codegen", default-features = false, features = ["nightly"] }
serde_codegen = { version = "^0.7.15", default-features = false, features = ["nightly"] }
[dev-dependencies]
clippy = "^0.0.79"
compiletest_rs = "^0.2.0"
fnv = "1.0"
rustc-serialize = "^0.3.16"
serde = { version = "^0.7.11", path = "../serde" }
serde = "0.7.15"
serde_test = "0.7.15"
[[test]]
name = "test"
+1 -1
View File
@@ -6,4 +6,4 @@ extern crate rustc_serialize;
extern crate serde;
extern crate test;
include!("../../serde_tests/benches/bench.rs.in");
include!("../../testing/benches/bench.rs.in");
+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() {}
+1 -1
View File
@@ -4,6 +4,6 @@
extern crate serde;
extern crate test;
include!("../../serde_tests/tests/test.rs.in");
include!("../../testing/tests/test.rs.in");
mod compile_tests;
+14
View File
@@ -0,0 +1,14 @@
[package]
name = "serde_test"
version = "0.7.15"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations"
repository = "https://github.com/serde-rs/serde"
documentation = "https://serde-rs.github.io/serde/serde/"
readme = "../README.md"
keywords = ["serde", "serialization"]
include = ["Cargo.toml", "src/**/*.rs"]
[dependencies]
serde = "0.7.15"
+54
View File
@@ -0,0 +1,54 @@
use serde::{Serialize, Deserialize};
use de::Deserializer;
use error::Error;
use ser::Serializer;
use token::Token;
use std::fmt::Debug;
pub fn assert_tokens<T>(value: &T, tokens: &[Token<'static>])
where T: Serialize + Deserialize + PartialEq + Debug,
{
assert_ser_tokens(value, tokens);
assert_de_tokens(value, tokens);
}
pub fn assert_ser_tokens<T>(value: &T, tokens: &[Token])
where T: Serialize,
{
let mut ser = Serializer::new(tokens.iter());
assert_eq!(Serialize::serialize(value, &mut ser), Ok(()));
assert_eq!(ser.next_token(), None);
}
/// Expect an error serializing `T`.
pub fn assert_ser_tokens_error<T>(value: &T, tokens: &[Token], error: Error)
where T: Serialize + PartialEq + Debug,
{
let mut ser = Serializer::new(tokens.iter());
let v: Result<(), Error> = Serialize::serialize(value, &mut ser);
assert_eq!(v.as_ref(), Err(&error));
assert_eq!(ser.next_token(), None);
}
pub fn assert_de_tokens<T>(value: &T, tokens: &[Token<'static>])
where T: Deserialize + PartialEq + Debug,
{
let mut de = Deserializer::new(tokens.to_vec().into_iter());
let v: Result<T, Error> = Deserialize::deserialize(&mut de);
assert_eq!(v.as_ref(), Ok(value));
assert_eq!(de.next_token(), None);
}
/// Expect an error deserializing tokens into a `T`.
pub fn assert_de_tokens_error<T>(tokens: &[Token<'static>], error: Error)
where T: Deserialize + PartialEq + Debug,
{
let mut de = Deserializer::new(tokens.to_vec().into_iter());
let v: Result<T, Error> = Deserialize::deserialize(&mut de);
assert_eq!(v, Err(error));
// There may be one token left if a peek caused the error
de.next_token();
assert_eq!(de.next_token(), None);
}
File diff suppressed because it is too large Load Diff
+87
View File
@@ -0,0 +1,87 @@
use std::{error, fmt};
use serde::{ser, de};
use token::Token;
#[derive(Clone, PartialEq, Debug)]
pub enum Error {
// Shared
Custom(String),
InvalidValue(String),
// De
EndOfStream,
InvalidType(de::Type),
InvalidLength(usize),
UnknownVariant(String),
UnknownField(String),
MissingField(&'static str),
DuplicateField(&'static str),
InvalidName(&'static str),
UnexpectedToken(Token<'static>),
}
impl ser::Error for Error {
fn custom<T: Into<String>>(msg: T) -> Error {
Error::Custom(msg.into())
}
fn invalid_value(msg: &str) -> Error {
Error::InvalidValue(msg.to_owned())
}
}
impl de::Error for Error {
fn custom<T: Into<String>>(msg: T) -> Error {
Error::Custom(msg.into())
}
fn end_of_stream() -> Error {
Error::EndOfStream
}
fn invalid_type(ty: de::Type) -> Error {
Error::InvalidType(ty)
}
fn invalid_value(msg: &str) -> Error {
Error::InvalidValue(msg.to_owned())
}
fn invalid_length(len: usize) -> Error {
Error::InvalidLength(len)
}
fn unknown_variant(variant: &str) -> Error {
Error::UnknownVariant(variant.to_owned())
}
fn unknown_field(field: &str) -> Error {
Error::UnknownField(field.to_owned())
}
fn missing_field(field: &'static str) -> Error {
Error::MissingField(field)
}
fn duplicate_field(field: &'static str) -> Error {
Error::DuplicateField(field)
}
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(format!("{:?}", self).as_ref())
}
}
impl error::Error for Error {
fn description(&self) -> &str {
"Serde Error"
}
fn cause(&self) -> Option<&error::Error> {
None
}
}
+22
View File
@@ -0,0 +1,22 @@
extern crate serde;
mod assert;
pub use assert::{
assert_tokens,
assert_ser_tokens,
assert_ser_tokens_error,
assert_de_tokens,
assert_de_tokens_error,
};
mod ser;
pub use ser::Serializer;
mod de;
pub use de::Deserializer;
mod token;
pub use token::Token;
mod error;
pub use error::Error;
+350
View File
@@ -0,0 +1,350 @@
use std::marker::PhantomData;
use serde::ser::{
self,
MapVisitor,
SeqVisitor,
Serialize,
};
use error::Error;
use token::Token;
pub struct Serializer<'a, I>
where I: Iterator<Item=&'a Token<'a>>,
{
tokens: I,
phantom: PhantomData<&'a Token<'a>>,
}
impl<'a, I> Serializer<'a, I>
where I: Iterator<Item=&'a Token<'a>>,
{
pub fn new(tokens: I) -> Serializer<'a, I> {
Serializer {
tokens: tokens,
phantom: PhantomData,
}
}
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;
fn serialize_unit(&mut self) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Unit));
Ok(())
}
fn serialize_newtype_variant<T>(&mut self,
name: &str,
_variant_index: usize,
variant: &str,
value: T) -> Result<(), Error>
where T: Serialize,
{
assert_eq!(self.tokens.next(), Some(&Token::EnumNewType(name, variant)));
value.serialize(self)
}
fn serialize_unit_struct(&mut self, name: &str) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::UnitStruct(name)));
Ok(())
}
fn serialize_unit_variant(&mut self,
name: &str,
_variant_index: usize,
variant: &str) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::EnumUnit(name, variant)));
Ok(())
}
fn serialize_bool(&mut self, v: bool) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Bool(v)));
Ok(())
}
fn serialize_isize(&mut self, v: isize) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Isize(v)));
Ok(())
}
fn serialize_i8(&mut self, v: i8) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::I8(v)));
Ok(())
}
fn serialize_i16(&mut self, v: i16) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::I16(v)));
Ok(())
}
fn serialize_i32(&mut self, v: i32) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::I32(v)));
Ok(())
}
fn serialize_i64(&mut self, v: i64) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::I64(v)));
Ok(())
}
fn serialize_usize(&mut self, v: usize) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Usize(v)));
Ok(())
}
fn serialize_u8(&mut self, v: u8) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::U8(v)));
Ok(())
}
fn serialize_u16(&mut self, v: u16) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::U16(v)));
Ok(())
}
fn serialize_u32(&mut self, v: u32) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::U32(v)));
Ok(())
}
fn serialize_u64(&mut self, v: u64) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::U64(v)));
Ok(())
}
fn serialize_f32(&mut self, v: f32) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::F32(v)));
Ok(())
}
fn serialize_f64(&mut self, v: f64) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::F64(v)));
Ok(())
}
fn serialize_char(&mut self, v: char) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Char(v)));
Ok(())
}
fn serialize_str(&mut self, v: &str) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Str(v)));
Ok(())
}
fn serialize_none(&mut self) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Option(false)));
Ok(())
}
fn serialize_some<V>(&mut self, value: V) -> Result<(), Error>
where V: Serialize,
{
assert_eq!(self.tokens.next(), Some(&Token::Option(true)));
value.serialize(self)
}
fn serialize_seq<V>(&mut self, visitor: V) -> Result<(), Error>
where V: SeqVisitor
{
let len = visitor.len();
assert_eq!(self.tokens.next(), Some(&Token::SeqStart(len)));
self.visit_seq(visitor)
}
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>
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));
Ok(())
}
fn serialize_tuple_elt<T>(&mut self, value: T) -> Result<(), Error>
where T: Serialize
{
assert_eq!(self.tokens.next(), Some(&Token::TupleSep));
value.serialize(self)
}
fn serialize_newtype_struct<T>(&mut self,
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
{
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,
{
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
{
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,
{
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();
assert_eq!(self.tokens.next(), Some(&Token::MapStart(len)));
self.visit_map(visitor)
}
fn serialize_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), 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();
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,
{
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();
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,
{
assert_eq!(self.tokens.next(), Some(&Token::EnumMapSep));
try!(key.serialize(self));
value.serialize(self)
}
}
+60
View File
@@ -0,0 +1,60 @@
#[derive(Clone, PartialEq, Debug)]
pub enum Token<'a> {
Bool(bool),
Isize(isize),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
Usize(usize),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
F32(f32),
F64(f64),
Char(char),
Str(&'a str),
String(String),
Bytes(&'a [u8]),
Option(bool),
Unit,
UnitStruct(&'a str),
StructNewType(&'a str),
EnumStart(&'a str),
EnumUnit(&'a str, &'a str),
EnumNewType(&'a str, &'a str),
SeqStart(Option<usize>),
SeqArrayStart(usize),
SeqSep,
SeqEnd,
TupleStart(usize),
TupleSep,
TupleEnd,
TupleStructStart(&'a str, Option<usize>),
TupleStructSep,
TupleStructEnd,
MapStart(Option<usize>),
MapSep,
MapEnd,
StructStart(&'a str, Option<usize>),
StructSep,
StructEnd,
EnumSeqStart(&'a str, &'a str, Option<usize>),
EnumSeqSep,
EnumSeqEnd,
EnumMapStart(&'a str, &'a str, Option<usize>),
EnumMapSep,
EnumMapEnd,
}
@@ -1,6 +1,6 @@
[package]
name = "serde_tests"
version = "0.7.11"
name = "serde_testing"
version = "0.7.15"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
@@ -14,12 +14,13 @@ build = "build.rs"
nightly-testing = ["clippy", "serde/nightly-testing", "serde_codegen/nightly-testing"]
[build-dependencies]
serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-syntex"] }
serde_codegen = { version = "*", features = ["with-syntex"] }
[dev-dependencies]
fnv = "1.0"
rustc-serialize = "^0.3.16"
serde = { version = "*", path = "../serde" }
serde = "*"
serde_test = "*"
[dependencies]
clippy = { version = "^0.*", optional = true }
@@ -5,7 +5,7 @@ macro_rules! declare_ser_tests {
#[test]
fn $name() {
$(
::token::assert_ser_tokens(&$value, $tokens);
assert_ser_tokens(&$value, $tokens);
)+
}
)+
@@ -1,8 +1,6 @@
#[macro_use]
mod macros;
mod token;
mod test_annotations;
mod test_bytes;
mod test_de;
@@ -1,7 +1,8 @@
extern crate serde;
use self::serde::{Serialize, Serializer, Deserialize, Deserializer};
use token::{
extern crate serde_test;
use self::serde_test::{
Error,
Token,
assert_tokens,
@@ -80,7 +81,7 @@ struct DefaultStruct<A, B, C, D, E>
fn test_default_struct() {
assert_de_tokens(
&DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
vec![
&[
Token::StructStart("DefaultStruct", Some(3)),
Token::StructSep,
@@ -109,7 +110,7 @@ fn test_default_struct() {
assert_de_tokens(
&DefaultStruct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 },
vec![
&[
Token::StructStart("DefaultStruct", Some(1)),
Token::StructSep,
@@ -143,7 +144,7 @@ enum DefaultEnum<A, B, C, D, E>
fn test_default_enum() {
assert_de_tokens(
&DefaultEnum::Struct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
vec![
&[
Token::EnumMapStart("DefaultEnum", "Struct", Some(5)),
Token::EnumMapSep,
@@ -172,7 +173,7 @@ fn test_default_enum() {
assert_de_tokens(
&DefaultEnum::Struct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 },
vec![
&[
Token::EnumMapStart("DefaultEnum", "Struct", Some(5)),
Token::EnumMapSep,
@@ -206,7 +207,7 @@ struct ContainsNoStdDefault<A: MyDefault> {
fn test_no_std_default() {
assert_de_tokens(
&ContainsNoStdDefault { a: NoStdDefault(123) },
vec![
&[
Token::StructStart("ContainsNoStdDefault", Some(1)),
Token::StructEnd,
]
@@ -214,7 +215,7 @@ fn test_no_std_default() {
assert_de_tokens(
&ContainsNoStdDefault { a: NoStdDefault(8) },
vec![
&[
Token::StructStart("ContainsNoStdDefault", Some(1)),
Token::StructSep,
@@ -279,7 +280,7 @@ fn test_elt_not_deserialize() {
c: NotDeserializeStruct(123),
e: NotDeserializeEnum::Trouble,
},
vec![
&[
Token::StructStart("ContainsNotDeserialize", Some(3)),
Token::StructEnd,
]
@@ -297,7 +298,7 @@ fn test_ignore_unknown() {
// 'Default' allows unknown. Basic smoke test of ignore...
assert_de_tokens(
&DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
vec![
&[
Token::StructStart("DefaultStruct", Some(5)),
Token::StructSep,
@@ -332,7 +333,7 @@ fn test_ignore_unknown() {
);
assert_de_tokens_error::<DenyUnknown>(
vec![
&[
Token::StructStart("DenyUnknown", Some(2)),
Token::StructSep,
@@ -341,11 +342,8 @@ fn test_ignore_unknown() {
Token::StructSep,
Token::Str("whoops"),
Token::I32(2),
Token::StructEnd,
],
Error::UnknownFieldError("whoops".to_owned())
Error::UnknownField("whoops".to_owned())
);
}
@@ -369,7 +367,7 @@ struct RenameStructSerializeDeserialize {
fn test_rename_struct() {
assert_tokens(
&RenameStruct { a1: 1, a2: 2 },
vec![
&[
Token::StructStart("Superhero", Some(2)),
Token::StructSep,
@@ -403,7 +401,7 @@ fn test_rename_struct() {
assert_de_tokens(
&RenameStructSerializeDeserialize { a1: 1, a2: 2 },
vec![
&[
Token::StructStart("SuperheroDe", Some(2)),
Token::StructSep,
@@ -451,14 +449,14 @@ enum RenameEnumSerializeDeserialize<A> {
fn test_rename_enum() {
assert_tokens(
&RenameEnum::Batman,
vec![
&[
Token::EnumUnit("Superhero", "bruce_wayne"),
]
);
assert_tokens(
&RenameEnum::Superman(0),
vec![
&[
Token::EnumNewType("Superhero", "clark_kent"),
Token::I8(0),
]
@@ -466,7 +464,7 @@ fn test_rename_enum() {
assert_tokens(
&RenameEnum::WonderWoman(0, 1),
vec![
&[
Token::EnumSeqStart("Superhero", "diana_prince", Some(2)),
Token::EnumSeqSep,
@@ -481,7 +479,7 @@ fn test_rename_enum() {
assert_tokens(
&RenameEnum::Flash { a: 1 },
vec![
&[
Token::EnumMapStart("Superhero", "barry_allan", Some(1)),
Token::EnumMapSep,
@@ -517,7 +515,7 @@ fn test_rename_enum() {
a: 0,
b: String::new(),
},
vec![
&[
Token::EnumMapStart("SuperheroDe", "jason_todd", Some(2)),
Token::EnumMapSep,
@@ -807,7 +805,7 @@ fn test_deserialize_with_struct() {
a: 1,
b: 2,
},
vec![
&[
Token::StructStart("DeserializeWithStruct", Some(2)),
Token::StructSep,
@@ -827,7 +825,7 @@ fn test_deserialize_with_struct() {
a: 1,
b: 123,
},
vec![
&[
Token::StructStart("DeserializeWithStruct", Some(2)),
Token::StructSep,
@@ -859,7 +857,7 @@ fn test_deserialize_with_enum() {
a: 1,
b: 2,
},
vec![
&[
Token::EnumMapStart("DeserializeWithEnum", "Struct", Some(2)),
Token::EnumMapSep,
@@ -879,7 +877,7 @@ fn test_deserialize_with_enum() {
a: 1,
b: 123,
},
vec![
&[
Token::EnumMapStart("DeserializeWithEnum", "Struct", Some(2)),
Token::EnumMapSep,
@@ -898,7 +896,7 @@ fn test_deserialize_with_enum() {
#[test]
fn test_missing_renamed_field_struct() {
assert_de_tokens_error::<RenameStruct>(
vec![
&[
Token::StructStart("Superhero", Some(2)),
Token::StructSep,
@@ -907,11 +905,11 @@ fn test_missing_renamed_field_struct() {
Token::StructEnd,
],
Error::MissingFieldError("a3"),
Error::MissingField("a3"),
);
assert_de_tokens_error::<RenameStructSerializeDeserialize>(
vec![
&[
Token::StructStart("SuperheroDe", Some(2)),
Token::StructSep,
@@ -920,23 +918,23 @@ fn test_missing_renamed_field_struct() {
Token::StructEnd,
],
Error::MissingFieldError("a5"),
Error::MissingField("a5"),
);
}
#[test]
fn test_missing_renamed_field_enum() {
assert_de_tokens_error::<RenameEnum>(
vec![
&[
Token::EnumMapStart("Superhero", "barry_allan", Some(1)),
Token::EnumMapEnd,
],
Error::MissingFieldError("b"),
Error::MissingField("b"),
);
assert_de_tokens_error::<RenameEnumSerializeDeserialize<i8>>(
vec![
&[
Token::EnumMapStart("SuperheroDe", "jason_todd", Some(2)),
Token::EnumMapSep,
@@ -945,6 +943,34 @@ fn test_missing_renamed_field_enum() {
Token::EnumMapEnd,
],
Error::MissingFieldError("d"),
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", Some(3)),
Token::EnumSeqSep,
Token::I32(1),
Token::EnumSeqEnd,
],
Error::InvalidLength(1),
);
assert_de_tokens_error::<InvalidLengthEnum>(
&[
Token::EnumSeqStart("InvalidLengthEnum", "B", Some(3)),
Token::EnumSeqSep,
Token::I32(1),
Token::EnumSeqEnd,
],
Error::InvalidLength(1),
);
}
@@ -2,14 +2,17 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::net;
use std::path::PathBuf;
extern crate serde;
use self::serde::Deserialize;
extern crate fnv;
use self::fnv::FnvHasher;
use token::{
extern crate serde_test;
use self::serde_test::{
Error,
Token,
assert_de_tokens,
assert_de_tokens_ignore,
assert_de_tokens_error,
};
@@ -73,107 +76,147 @@ macro_rules! declare_error_tests {
}
}
fn assert_de_tokens_ignore(ignorable_tokens: &[Token<'static>]) {
#[derive(PartialEq, Debug, Deserialize)]
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![
Token::MapStart(Some(2)),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep,
Token::Str("ignored")
]
.into_iter()
.chain(ignorable_tokens.to_vec().into_iter())
.chain(vec![
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);
}
//////////////////////////////////////////////////////////////////////////
declare_tests! {
test_bool {
true => vec![Token::Bool(true)],
false => vec![Token::Bool(false)],
true => &[Token::Bool(true)],
false => &[Token::Bool(false)],
}
test_isize {
0isize => vec![Token::Isize(0)],
0isize => vec![Token::I8(0)],
0isize => vec![Token::I16(0)],
0isize => vec![Token::I32(0)],
0isize => vec![Token::I64(0)],
0isize => vec![Token::Usize(0)],
0isize => vec![Token::U8(0)],
0isize => vec![Token::U16(0)],
0isize => vec![Token::U32(0)],
0isize => vec![Token::U64(0)],
0isize => vec![Token::F32(0.)],
0isize => vec![Token::F64(0.)],
0isize => &[Token::Isize(0)],
0isize => &[Token::I8(0)],
0isize => &[Token::I16(0)],
0isize => &[Token::I32(0)],
0isize => &[Token::I64(0)],
0isize => &[Token::Usize(0)],
0isize => &[Token::U8(0)],
0isize => &[Token::U16(0)],
0isize => &[Token::U32(0)],
0isize => &[Token::U64(0)],
0isize => &[Token::F32(0.)],
0isize => &[Token::F64(0.)],
}
test_ints {
0isize => vec![Token::Isize(0)],
0i8 => vec![Token::I8(0)],
0i16 => vec![Token::I16(0)],
0i32 => vec![Token::I32(0)],
0i64 => vec![Token::I64(0)],
0isize => &[Token::Isize(0)],
0i8 => &[Token::I8(0)],
0i16 => &[Token::I16(0)],
0i32 => &[Token::I32(0)],
0i64 => &[Token::I64(0)],
}
test_uints {
0usize => vec![Token::Usize(0)],
0u8 => vec![Token::U8(0)],
0u16 => vec![Token::U16(0)],
0u32 => vec![Token::U32(0)],
0u64 => vec![Token::U64(0)],
0usize => &[Token::Usize(0)],
0u8 => &[Token::U8(0)],
0u16 => &[Token::U16(0)],
0u32 => &[Token::U32(0)],
0u64 => &[Token::U64(0)],
}
test_floats {
0f32 => vec![Token::F32(0.)],
0f64 => vec![Token::F64(0.)],
0f32 => &[Token::F32(0.)],
0f64 => &[Token::F64(0.)],
}
test_char {
'a' => vec![Token::Char('a')],
'a' => vec![Token::Str("a")],
'a' => vec![Token::String("a".to_owned())],
'a' => &[Token::Char('a')],
'a' => &[Token::Str("a")],
'a' => &[Token::String("a".to_owned())],
}
test_string {
"abc".to_owned() => vec![Token::Str("abc")],
"abc".to_owned() => vec![Token::String("abc".to_owned())],
"a".to_owned() => vec![Token::Char('a')],
"abc".to_owned() => &[Token::Str("abc")],
"abc".to_owned() => &[Token::String("abc".to_owned())],
"a".to_owned() => &[Token::Char('a')],
}
test_option {
None::<i32> => vec![Token::Unit],
None::<i32> => vec![Token::Option(false)],
Some(1) => vec![Token::I32(1)],
Some(1) => vec![
None::<i32> => &[Token::Unit],
None::<i32> => &[Token::Option(false)],
Some(1) => &[Token::I32(1)],
Some(1) => &[
Token::Option(true),
Token::I32(1),
],
}
test_result {
Ok::<i32, i32>(0) => vec![
Ok::<i32, i32>(0) => &[
Token::EnumStart("Result"),
Token::Str("Ok"),
Token::I32(0),
],
Err::<i32, i32>(1) => vec![
Err::<i32, i32>(1) => &[
Token::EnumStart("Result"),
Token::Str("Err"),
Token::I32(1),
],
}
test_unit {
() => vec![Token::Unit],
() => vec![
() => &[Token::Unit],
() => &[
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
() => vec![
() => &[
Token::SeqStart(None),
Token::SeqEnd,
],
() => vec![
() => &[
Token::TupleStructStart("Anything", Some(0)),
Token::SeqEnd,
],
}
test_unit_struct {
UnitStruct => vec![Token::Unit],
UnitStruct => vec![
UnitStruct => &[Token::Unit],
UnitStruct => &[
Token::UnitStruct("UnitStruct"),
],
UnitStruct => vec![
UnitStruct => &[
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
UnitStruct => vec![
UnitStruct => &[
Token::SeqStart(None),
Token::SeqEnd,
],
}
test_tuple_struct {
TupleStruct(1, 2, 3) => vec![
TupleStruct(1, 2, 3) => &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
@@ -185,7 +228,7 @@ declare_tests! {
Token::I32(3),
Token::SeqEnd,
],
TupleStruct(1, 2, 3) => vec![
TupleStruct(1, 2, 3) => &[
Token::SeqStart(None),
Token::SeqSep,
Token::I32(1),
@@ -197,7 +240,7 @@ declare_tests! {
Token::I32(3),
Token::SeqEnd,
],
TupleStruct(1, 2, 3) => vec![
TupleStruct(1, 2, 3) => &[
Token::TupleStructStart("TupleStruct", Some(3)),
Token::TupleStructSep,
Token::I32(1),
@@ -209,7 +252,7 @@ declare_tests! {
Token::I32(3),
Token::TupleStructEnd,
],
TupleStruct(1, 2, 3) => vec![
TupleStruct(1, 2, 3) => &[
Token::TupleStructStart("TupleStruct", None),
Token::TupleStructSep,
Token::I32(1),
@@ -223,14 +266,14 @@ declare_tests! {
],
}
test_btreeset {
BTreeSet::<isize>::new() => vec![
BTreeSet::<isize>::new() => &[
Token::Unit,
],
BTreeSet::<isize>::new() => vec![
BTreeSet::<isize>::new() => &[
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
btreeset![btreeset![], btreeset![1], btreeset![2, 3]] => vec![
btreeset![btreeset![], btreeset![1], btreeset![2, 3]] => &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::SeqStart(Some(0)),
@@ -252,23 +295,23 @@ declare_tests! {
Token::SeqEnd,
Token::SeqEnd,
],
BTreeSet::<isize>::new() => vec![
BTreeSet::<isize>::new() => &[
Token::UnitStruct("Anything"),
],
BTreeSet::<isize>::new() => vec![
BTreeSet::<isize>::new() => &[
Token::TupleStructStart("Anything", Some(0)),
Token::SeqEnd,
],
}
test_hashset {
HashSet::<isize>::new() => vec![
HashSet::<isize>::new() => &[
Token::Unit,
],
HashSet::<isize>::new() => vec![
HashSet::<isize>::new() => &[
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
hashset![1, 2, 3] => vec![
hashset![1, 2, 3] => &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
@@ -280,14 +323,14 @@ declare_tests! {
Token::I32(3),
Token::SeqEnd,
],
HashSet::<isize>::new() => vec![
HashSet::<isize>::new() => &[
Token::UnitStruct("Anything"),
],
HashSet::<isize>::new() => vec![
HashSet::<isize>::new() => &[
Token::TupleStructStart("Anything", Some(0)),
Token::SeqEnd,
],
hashset![FnvHasher @ 1, 2, 3] => vec![
hashset![FnvHasher @ 1, 2, 3] => &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
@@ -301,14 +344,14 @@ declare_tests! {
],
}
test_vec {
Vec::<isize>::new() => vec![
Vec::<isize>::new() => &[
Token::Unit,
],
Vec::<isize>::new() => vec![
Vec::<isize>::new() => &[
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
vec![vec![], vec![1], vec![2, 3]] => vec![
vec![vec![], vec![1], vec![2, 3]] => &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::SeqStart(Some(0)),
@@ -330,27 +373,27 @@ declare_tests! {
Token::SeqEnd,
Token::SeqEnd,
],
Vec::<isize>::new() => vec![
Vec::<isize>::new() => &[
Token::UnitStruct("Anything"),
],
Vec::<isize>::new() => vec![
Vec::<isize>::new() => &[
Token::TupleStructStart("Anything", Some(0)),
Token::SeqEnd,
],
}
test_array {
[0; 0] => vec![
[0; 0] => &[
Token::Unit,
],
[0; 0] => vec![
[0; 0] => &[
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
[0; 0] => vec![
[0; 0] => &[
Token::SeqArrayStart(0),
Token::SeqEnd,
],
([0; 0], [1], [2, 3]) => vec![
([0; 0], [1], [2, 3]) => &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::SeqStart(Some(0)),
@@ -372,7 +415,7 @@ declare_tests! {
Token::SeqEnd,
Token::SeqEnd,
],
([0; 0], [1], [2, 3]) => vec![
([0; 0], [1], [2, 3]) => &[
Token::SeqArrayStart(3),
Token::SeqSep,
Token::SeqArrayStart(0),
@@ -394,22 +437,22 @@ declare_tests! {
Token::SeqEnd,
Token::SeqEnd,
],
[0; 0] => vec![
[0; 0] => &[
Token::UnitStruct("Anything"),
],
[0; 0] => vec![
[0; 0] => &[
Token::TupleStructStart("Anything", Some(0)),
Token::SeqEnd,
],
}
test_tuple {
(1,) => vec![
(1,) => &[
Token::SeqStart(Some(1)),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
],
(1, 2, 3) => vec![
(1, 2, 3) => &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
@@ -421,13 +464,13 @@ declare_tests! {
Token::I32(3),
Token::SeqEnd,
],
(1,) => vec![
(1,) => &[
Token::TupleStart(1),
Token::TupleSep,
Token::I32(1),
Token::TupleEnd,
],
(1, 2, 3) => vec![
(1, 2, 3) => &[
Token::TupleStart(3),
Token::TupleSep,
Token::I32(1),
@@ -441,21 +484,21 @@ declare_tests! {
],
}
test_btreemap {
BTreeMap::<isize, isize>::new() => vec![
BTreeMap::<isize, isize>::new() => &[
Token::Unit,
],
BTreeMap::<isize, isize>::new() => vec![
BTreeMap::<isize, isize>::new() => &[
Token::MapStart(Some(0)),
Token::MapEnd,
],
btreemap![1 => 2] => vec![
btreemap![1 => 2] => &[
Token::MapStart(Some(1)),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapEnd,
],
btreemap![1 => 2, 3 => 4] => vec![
btreemap![1 => 2, 3 => 4] => &[
Token::MapStart(Some(2)),
Token::MapSep,
Token::I32(1),
@@ -466,7 +509,7 @@ declare_tests! {
Token::I32(4),
Token::MapEnd,
],
btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![
btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => &[
Token::MapStart(Some(2)),
Token::MapSep,
Token::I32(1),
@@ -486,30 +529,30 @@ declare_tests! {
Token::MapEnd,
Token::MapEnd,
],
BTreeMap::<isize, isize>::new() => vec![
BTreeMap::<isize, isize>::new() => &[
Token::UnitStruct("Anything"),
],
BTreeMap::<isize, isize>::new() => vec![
BTreeMap::<isize, isize>::new() => &[
Token::StructStart("Anything", Some(0)),
Token::MapEnd,
],
}
test_hashmap {
HashMap::<isize, isize>::new() => vec![
HashMap::<isize, isize>::new() => &[
Token::Unit,
],
HashMap::<isize, isize>::new() => vec![
HashMap::<isize, isize>::new() => &[
Token::MapStart(Some(0)),
Token::MapEnd,
],
hashmap![1 => 2] => vec![
hashmap![1 => 2] => &[
Token::MapStart(Some(1)),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapEnd,
],
hashmap![1 => 2, 3 => 4] => vec![
hashmap![1 => 2, 3 => 4] => &[
Token::MapStart(Some(2)),
Token::MapSep,
Token::I32(1),
@@ -520,7 +563,7 @@ declare_tests! {
Token::I32(4),
Token::MapEnd,
],
hashmap![1 => hashmap![], 2 => hashmap![3 => 4, 5 => 6]] => vec![
hashmap![1 => hashmap![], 2 => hashmap![3 => 4, 5 => 6]] => &[
Token::MapStart(Some(2)),
Token::MapSep,
Token::I32(1),
@@ -540,14 +583,14 @@ declare_tests! {
Token::MapEnd,
Token::MapEnd,
],
HashMap::<isize, isize>::new() => vec![
HashMap::<isize, isize>::new() => &[
Token::UnitStruct("Anything"),
],
HashMap::<isize, isize>::new() => vec![
HashMap::<isize, isize>::new() => &[
Token::StructStart("Anything", Some(0)),
Token::MapEnd,
],
hashmap![FnvHasher @ 1 => 2, 3 => 4] => vec![
hashmap![FnvHasher @ 1 => 2, 3 => 4] => &[
Token::MapStart(Some(2)),
Token::MapSep,
Token::I32(1),
@@ -560,7 +603,7 @@ declare_tests! {
],
}
test_struct {
Struct { a: 1, b: 2, c: 0 } => vec![
Struct { a: 1, b: 2, c: 0 } => &[
Token::MapStart(Some(3)),
Token::MapSep,
Token::Str("a"),
@@ -571,7 +614,7 @@ declare_tests! {
Token::I32(2),
Token::MapEnd,
],
Struct { a: 1, b: 2, c: 0 } => vec![
Struct { a: 1, b: 2, c: 0 } => &[
Token::StructStart("Struct", Some(3)),
Token::StructSep,
Token::Str("a"),
@@ -582,7 +625,7 @@ declare_tests! {
Token::I32(2),
Token::StructEnd,
],
Struct { a: 1, b: 2, c: 0 } => vec![
Struct { a: 1, b: 2, c: 0 } => &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
@@ -593,7 +636,7 @@ declare_tests! {
],
}
test_struct_with_skip {
Struct { a: 1, b: 2, c: 0 } => vec![
Struct { a: 1, b: 2, c: 0 } => &[
Token::MapStart(Some(3)),
Token::MapSep,
Token::Str("a"),
@@ -612,7 +655,7 @@ declare_tests! {
Token::I32(4),
Token::MapEnd,
],
Struct { a: 1, b: 2, c: 0 } => vec![
Struct { a: 1, b: 2, c: 0 } => &[
Token::StructStart("Struct", Some(3)),
Token::StructSep,
Token::Str("a"),
@@ -633,18 +676,18 @@ declare_tests! {
],
}
test_enum_unit {
Enum::Unit => vec![
Enum::Unit => &[
Token::EnumUnit("Enum", "Unit"),
],
}
test_enum_simple {
Enum::Simple(1) => vec![
Enum::Simple(1) => &[
Token::EnumNewType("Enum", "Simple"),
Token::I32(1),
],
}
test_enum_seq {
Enum::Seq(1, 2, 3) => vec![
Enum::Seq(1, 2, 3) => &[
Token::EnumSeqStart("Enum", "Seq", Some(3)),
Token::EnumSeqSep,
Token::I32(1),
@@ -658,7 +701,7 @@ declare_tests! {
],
}
test_enum_map {
Enum::Map { a: 1, b: 2, c: 3 } => vec![
Enum::Map { a: 1, b: 2, c: 3 } => &[
Token::EnumMapStart("Enum", "Map", Some(3)),
Token::EnumMapSep,
Token::Str("a"),
@@ -675,24 +718,24 @@ declare_tests! {
],
}
test_enum_unit_usize {
Enum::Unit => vec![
Enum::Unit => &[
Token::EnumStart("Enum"),
Token::Usize(0),
Token::Unit,
],
}
test_enum_unit_bytes {
Enum::Unit => vec![
Enum::Unit => &[
Token::EnumStart("Enum"),
Token::Bytes(b"Unit"),
Token::Unit,
],
}
test_box {
Box::new(0i32) => vec![Token::I32(0)],
Box::new(0i32) => &[Token::I32(0)],
}
test_boxed_slice {
Box::new([0, 1, 2]) => vec![
Box::new([0, 1, 2]) => &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(0),
@@ -704,18 +747,18 @@ declare_tests! {
],
}
test_net_ipv4addr {
"1.2.3.4".parse::<net::Ipv4Addr>().unwrap() => vec![Token::Str("1.2.3.4")],
"1.2.3.4".parse::<net::Ipv4Addr>().unwrap() => &[Token::Str("1.2.3.4")],
}
test_net_ipv6addr {
"::1".parse::<net::Ipv6Addr>().unwrap() => vec![Token::Str("::1")],
"::1".parse::<net::Ipv6Addr>().unwrap() => &[Token::Str("::1")],
}
test_net_socketaddr {
"1.2.3.4:1234".parse::<net::SocketAddr>().unwrap() => vec![Token::Str("1.2.3.4:1234")],
"1.2.3.4:1234".parse::<net::SocketAddrV4>().unwrap() => vec![Token::Str("1.2.3.4:1234")],
"[::1]:1234".parse::<net::SocketAddrV6>().unwrap() => vec![Token::Str("[::1]:1234")],
"1.2.3.4:1234".parse::<net::SocketAddr>().unwrap() => &[Token::Str("1.2.3.4:1234")],
"1.2.3.4:1234".parse::<net::SocketAddrV4>().unwrap() => &[Token::Str("1.2.3.4:1234")],
"[::1]:1234".parse::<net::SocketAddrV6>().unwrap() => &[Token::Str("[::1]:1234")],
}
test_path_buf {
PathBuf::from("/usr/local/lib") => vec![
PathBuf::from("/usr/local/lib") => &[
Token::String("/usr/local/lib".to_owned()),
],
}
@@ -726,30 +769,28 @@ declare_tests! {
fn test_net_ipaddr() {
assert_de_tokens(
"1.2.3.4".parse::<net::IpAddr>().unwrap(),
vec![Token::Str("1.2.3.4")],
&[Token::Str("1.2.3.4")],
);
}
declare_error_tests! {
test_unknown_variant<Enum> {
vec![
&[
Token::EnumUnit("Enum", "Foo"),
],
Error::UnknownVariantError("Foo".to_owned()),
Error::UnknownVariant("Foo".to_owned()),
}
test_struct_seq_too_long<Struct> {
vec![
&[
Token::SeqStart(Some(4)),
Token::SeqSep, Token::I32(1),
Token::SeqSep, Token::I32(2),
Token::SeqSep, Token::I32(3),
Token::SeqSep, Token::I32(4),
Token::SeqEnd,
],
Error::UnexpectedToken(Token::SeqSep),
}
test_duplicate_field_struct<Struct> {
vec![
&[
Token::MapStart(Some(3)),
Token::MapSep,
Token::Str("a"),
@@ -757,13 +798,11 @@ declare_error_tests! {
Token::MapSep,
Token::Str("a"),
Token::I32(3),
Token::MapEnd,
],
Error::DuplicateFieldError("a"),
Error::DuplicateField("a"),
}
test_duplicate_field_enum<Enum> {
vec![
&[
Token::EnumMapStart("Enum", "Map", Some(3)),
Token::EnumMapSep,
Token::Str("a"),
@@ -771,9 +810,7 @@ declare_error_tests! {
Token::EnumMapSep,
Token::Str("a"),
Token::I32(3),
Token::EnumMapEnd,
],
Error::DuplicateFieldError("a"),
Error::DuplicateField("a"),
}
}
@@ -1,11 +1,12 @@
use std::marker::PhantomData;
use token::{Token, assert_tokens, assert_ser_tokens, assert_de_tokens};
extern crate serde_test;
use self::serde_test::{
Token,
assert_tokens,
assert_ser_tokens,
assert_de_tokens,
};
/*
trait Trait {
type Type;
}
*/
use std::marker::PhantomData;
// That tests that the derived Serialize implementation doesn't trigger
// any warning about `serializer` not being used, in case of empty enums.
@@ -161,7 +162,7 @@ struct DefaultTyParam<T: AssociatedType<X=i32> = i32> {
fn test_named_unit() {
assert_tokens(
&NamedUnit,
vec![Token::UnitStruct("NamedUnit")]
&[Token::UnitStruct("NamedUnit")]
);
}
@@ -192,7 +193,7 @@ fn test_ser_named_tuple() {
fn test_de_named_tuple() {
assert_de_tokens(
&DeNamedTuple(5, 6, 7),
vec![
&[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(5),
@@ -209,7 +210,7 @@ fn test_de_named_tuple() {
assert_de_tokens(
&DeNamedTuple(5, 6, 7),
vec![
&[
Token::TupleStructStart("DeNamedTuple", Some(3)),
Token::TupleStructSep,
Token::I32(5),
@@ -265,7 +266,7 @@ fn test_de_named_map() {
b: 6,
c: 7,
},
vec![
&[
Token::StructStart("DeNamedMap", Some(3)),
Token::StructSep,
@@ -379,7 +380,7 @@ fn test_ser_enum_map() {
fn test_de_enum_unit() {
assert_tokens(
&DeEnum::Unit::<u32, u32, u32>,
vec![
&[
Token::EnumUnit("DeEnum", "Unit"),
],
);
@@ -403,7 +404,7 @@ fn test_de_enum_seq() {
e,
//f,
),
vec![
&[
Token::EnumSeqStart("DeEnum", "Seq", Some(4)),
Token::EnumSeqSep,
@@ -441,7 +442,7 @@ fn test_de_enum_map() {
e: e,
//f: f,
},
vec![
&[
Token::EnumMapStart("DeEnum", "Map", Some(4)),
Token::EnumMapSep,
@@ -516,7 +517,7 @@ fn test_lifetimes() {
fn test_generic_struct() {
assert_tokens(
&GenericStruct { x: 5u32 },
vec![
&[
Token::StructStart("GenericStruct", Some(1)),
Token::StructSep,
@@ -532,7 +533,7 @@ fn test_generic_struct() {
fn test_generic_newtype_struct() {
assert_tokens(
&GenericNewTypeStruct(5u32),
vec![
&[
Token::StructNewType("GenericNewTypeStruct"),
Token::U32(5),
]
@@ -543,7 +544,7 @@ fn test_generic_newtype_struct() {
fn test_generic_tuple_struct() {
assert_tokens(
&GenericTupleStruct(5u32, 6u32),
vec![
&[
Token::TupleStructStart("GenericTupleStruct", Some(2)),
Token::TupleStructSep,
@@ -561,7 +562,7 @@ fn test_generic_tuple_struct() {
fn test_generic_enum_unit() {
assert_tokens(
&GenericEnum::Unit::<u32, u32>,
vec![
&[
Token::EnumUnit("GenericEnum", "Unit"),
]
);
@@ -571,7 +572,7 @@ fn test_generic_enum_unit() {
fn test_generic_enum_newtype() {
assert_tokens(
&GenericEnum::NewType::<u32, u32>(5),
vec![
&[
Token::EnumNewType("GenericEnum", "NewType"),
Token::U32(5),
]
@@ -582,7 +583,7 @@ fn test_generic_enum_newtype() {
fn test_generic_enum_seq() {
assert_tokens(
&GenericEnum::Seq::<u32, u32>(5, 6),
vec![
&[
Token::EnumSeqStart("GenericEnum", "Seq", Some(2)),
Token::EnumSeqSep,
@@ -600,7 +601,7 @@ fn test_generic_enum_seq() {
fn test_generic_enum_map() {
assert_tokens(
&GenericEnum::Map::<u32, u32> { x: 5, y: 6 },
vec![
&[
Token::EnumMapStart("GenericEnum", "Map", Some(2)),
Token::EnumMapSep,
@@ -620,7 +621,7 @@ fn test_generic_enum_map() {
fn test_default_ty_param() {
assert_tokens(
&DefaultTyParam::<i32> { phantom: PhantomData },
vec![
&[
Token::StructStart("DefaultTyParam", Some(1)),
Token::StructSep,
@@ -3,7 +3,13 @@ use std::net;
use std::path::{Path, PathBuf};
use std::str;
use token::{self, Token};
extern crate serde_test;
use self::serde_test::{
Error,
Token,
assert_ser_tokens,
assert_ser_tokens_error,
};
extern crate fnv;
use self::fnv::FnvHasher;
@@ -355,16 +361,16 @@ fn test_cannot_serialize_paths() {
let path = unsafe {
str::from_utf8_unchecked(b"Hello \xF0\x90\x80World")
};
token::assert_ser_tokens_error(
assert_ser_tokens_error(
&Path::new(path),
&[Token::Str("Hello World")],
token::Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
&[],
Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
let mut path_buf = PathBuf::new();
path_buf.push(path);
token::assert_ser_tokens_error(
assert_ser_tokens_error(
&path_buf,
&[Token::Str("Hello World")],
token::Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
&[],
Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
}