Compare commits

...

111 Commits

Author SHA1 Message Date
Erick Tryzelaar cab653e7c7 Version bump 2015-08-18 12:50:39 -07:00
Erick Tryzelaar 8d999a8edd VecMap was removed from libcollections 2015-08-18 12:49:50 -07:00
Erick Tryzelaar 7b773ac088 Merge pull request #138 from erickt/master
Expose serde_json::from_{iter,reader,slice}
2015-08-13 22:32:34 -07:00
Erick Tryzelaar fc58ea7487 Expose serde_json::from_{iter,reader,slice} 2015-08-13 21:19:27 -07:00
Erick Tryzelaar c61cea0eb1 Merge pull request #136 from erickt/visit
Have deserializer numeric visits chain
2015-08-13 21:19:19 -07:00
Erick Tryzelaar 764b25bd07 Have Deserializer::visit_{usize,u8,...,isize,i8,...,f32} call visit_{u64,i64,f64}
This cuts down the amount of overloading needed by a format like
toml which wants to prevent casting a float to an integer and
vice versa.
2015-08-13 08:40:19 -07:00
Erick Tryzelaar a66cd25787 Merge pull request #135 from erickt/doc
Add a table pointing to the serializers that support serde
2015-08-11 07:02:22 -07:00
Erick Tryzelaar 0e8d94750b Add a table pointing to the serializers that support serde 2015-08-11 07:00:59 -07:00
Erick Tryzelaar 3c915189f4 version bump 2015-08-10 10:09:37 -07:00
Erick Tryzelaar c5541cddeb Merge pull request #134 from erickt/err
Add Error::length_mismatch, Error::type_mismatch, and de::Type
2015-08-10 10:07:51 -07:00
Erick Tryzelaar 63561609a6 Add Error::length_mismatch, Error::type_mismatch, and de::Type
This improves error handling to match the needs of msgpack
2015-08-09 21:42:42 -07:00
Erick Tryzelaar 5dc356ddb0 Merge pull request #133 from erickt/fixup
Fix doc links, recover some json deserialization speed
2015-08-09 18:17:02 -07:00
Erick Tryzelaar dc36fd38d6 Gain back 10MB/s on the json deserialization benchmark 2015-08-09 16:45:55 -07:00
Erick Tryzelaar 26873bf3d5 Don't use sudo in the travis 2015-08-09 16:40:35 -07:00
Erick Tryzelaar ff53323790 Correct the documentation links in the crates 2015-08-09 16:38:10 -07:00
Erick Tryzelaar fd3869d380 Update the README 2015-08-09 16:37:21 -07:00
Erick Tryzelaar 1d538bc59d Merge pull request #132 from Byron/fix-codegen
Use fully qualified `Result` type
2015-08-08 15:48:49 -07:00
Sebastian Thiel 784cfcd49e Use fully qualified Result type
If that is not the case, the generated code might attempt to use a
custom `Result` type with incompatible type parameters.
2015-08-08 12:33:29 +02:00
Erick Tryzelaar a142d319e7 Point the serde_json readme at the root readme 2015-08-07 12:05:01 -07:00
Erick Tryzelaar da3bf3c20a Merge pull request #130 from oli-obk/fix
json deser from Value adjusted to be equal to deser from strings
2015-08-07 09:45:37 -07:00
Erick Tryzelaar 1672306fa1 Merge pull request #129 from erickt/remove-error
Remove "_error" from de::Error methods, add string argument to Error::syntax()
2015-08-07 09:45:11 -07:00
Oliver Schneider 7fc780ba1b json deser from Value adjusted to be equal to deser from strings 2015-08-07 18:31:42 +02:00
Erick Tryzelaar 7fb2bd50bf Add a string argument to Error::syntax() 2015-08-07 08:08:56 -07:00
Erick Tryzelaar 2aeb51ad51 Remove "_error" from de::Error::*_error 2015-08-07 07:53:22 -07:00
Erick Tryzelaar 0482b756e8 Merge pull request #127 from erickt/json3
Rewrite json parser to not require consuming the full stream
2015-08-07 07:52:52 -07:00
Erick Tryzelaar 1d9c707a76 Rewrite json parser to not require consuming the full stream
Closes #89
2015-08-06 11:12:37 -07:00
Erick Tryzelaar 199ed417bd Merge pull request #126 from erickt/json-f64
Update json number parsing to switch to floats if the number gets too big
2015-08-06 10:08:31 -07:00
Erick Tryzelaar 199a02cb68 i64::wrapping_neg is not stable yet 2015-08-06 09:31:37 -07:00
Erick Tryzelaar b6371f045f Simplify parsing a number 2015-08-06 07:12:00 -07:00
Erick Tryzelaar fd84aec485 Fix parsing min, max, and epsilon f64 values 2015-08-05 08:15:47 -07:00
Erick Tryzelaar ed6777e59f Fix json parsing i64::MIN, add tests for min and max i64 and u64 values 2015-08-03 09:09:44 -07:00
Erick Tryzelaar 22024a2b71 Simplify parsing floating point decimals and exponents 2015-08-01 14:26:53 -07:00
Erick Tryzelaar 8eff38b6f6 Eliminate some code duplication parsing an exponent as an integer 2015-08-01 13:50:42 -07:00
Erick Tryzelaar fa562d449d Minor optimization to not check if JSON number starts with '-' twice 2015-08-01 13:50:24 -07:00
Erick Tryzelaar c9d55362d6 Add a serde_json::Result helper type 2015-08-01 13:49:57 -07:00
Erick Tryzelaar 23031d057f Add test for parsing json "0" and "0.0" 2015-07-31 07:33:23 -07:00
Erick Tryzelaar 882d394352 Remove a debug comment 2015-07-31 07:28:07 -07:00
Erick Tryzelaar fbdede68a4 Build the serde_json docs 2015-07-31 07:24:05 -07:00
Erick Tryzelaar e88ef4715c Explicitly make the visit_struct_{,variant}_elt key a &'static str 2015-07-31 07:22:14 -07:00
Erick Tryzelaar 94f3dd25d8 Allow VariantVisitor::visit_newtype to default to calling visit_tuple 2015-07-31 07:22:13 -07:00
Erick Tryzelaar 2c58a9c11d Expose TupleVisitor*::new 2015-07-31 07:22:13 -07:00
Erick Tryzelaar 97528b59cf Add support for serializing newtype structs
This enables formats like JSON to serialize newtype wrapper
structs without the normal object wrapper. Consider types like:

```rust
struct Point {
    x: u32,
    y: u32,
}

stuct MyPoint(Point);
```

Before this patch, `MyPoint(1,2)` would get serialized as
`[{"x":1,"y":2}]`, but now it gets serialized as `{"x":1,"y"2}`.
2015-07-31 07:22:13 -07:00
Erick Tryzelaar 6715fb6652 Rename visit_simple to visit_newtype 2015-07-31 07:22:13 -07:00
Erick Tryzelaar fefc010deb Rename visit_enum_simple to visit_newtype_variant 2015-07-31 07:22:13 -07:00
Erick Tryzelaar 6cbb72decf Inlne the visit_seq method 2015-07-31 07:22:13 -07:00
Erick Tryzelaar 7e25ed863c Merge pull request #120 from erickt/enum-fields
Add enum fields and tuple length to deserialization visitor methods, renamed some more methods
2015-07-30 09:51:01 -07:00
Erick Tryzelaar 5a56394814 Add test to deserialize variants from usize and &[u8] 2015-07-30 08:06:04 -07:00
Erick Tryzelaar de1059f648 Allow Result<T, E> to use usize variant names 2015-07-30 08:06:04 -07:00
Erick Tryzelaar 97f08086dd Have visit_enum_simple default to calling visit_tuple_variant 2015-07-30 08:06:04 -07:00
Erick Tryzelaar 0348a3914d Pass variant index to visit_enum_simple 2015-07-30 08:06:04 -07:00
Erick Tryzelaar 5dc245d2ce Switch serializing Result to using simple enums 2015-07-30 08:06:04 -07:00
Erick Tryzelaar 71cc95248c Allow Option<T> to be used directly as a ser::SeqVisitor 2015-07-30 08:06:04 -07:00
Erick Tryzelaar 2cb7d66767 Add test for deserializing a simple enum 2015-07-30 08:06:04 -07:00
Erick Tryzelaar 49fa208242 Minor cleanup 2015-07-30 08:06:04 -07:00
Erick Tryzelaar d2fef27721 Rename ser::Serializer::visit_enum_{unit,seq,map} to visit_{unit,tuple,struct}_variant 2015-07-30 06:45:21 -07:00
Erick Tryzelaar 351b7039a8 Rename de::VariantVisitor::visit_{map,seq} to visit_{struct,tuple} 2015-07-30 06:45:21 -07:00
Erick Tryzelaar 7585ce9ed4 Re-indent 2015-07-30 06:45:21 -07:00
Erick Tryzelaar 578a0178b5 Make sure the visit_{enum,struct,tuple_struct} name is a &'static str 2015-07-30 06:45:21 -07:00
Erick Tryzelaar 6c9cebdcc3 Pass the variant fields and tuple lengths into visit_{enum,tuple,tuple_struct} 2015-07-30 06:45:21 -07:00
Erick Tryzelaar 35e2022e9a Point at github.com/serde-rs/serde 2015-07-30 06:43:20 -07:00
Erick Tryzelaar 0058e3a8d4 Merge pull request #111 from oli-obk/master
tuple enums with single element should not be a json-array
2015-07-29 13:35:43 -07:00
Erick Tryzelaar abf28ee167 Merge pull request #118 from erickt/ignore-fields
Add `#[serde(skip_serializing)] to skip serializing some fields
2015-07-29 10:08:19 -07:00
Oliver Schneider 5f1cb9b96c rebased again 2015-07-24 09:31:35 +02:00
Oliver 'ker' Schneider 8f8fc6f3ff nits and rebase fallout 2015-07-24 09:10:58 +02:00
Oliver Schneider 24787195a1 serialize tuple enums with single element directly as the value instead of a sequence 2015-07-24 09:10:58 +02:00
Oliver Schneider 5885111863 deserialize tuple enums with single element directly as the value instead of a sequence 2015-07-24 09:10:58 +02:00
Erick Tryzelaar b1cb5379de Add `#[serde(skip_serializing)] to skip serializing some fields
Closes #99
2015-07-23 08:07:49 -07:00
Erick Tryzelaar 447d08bd91 Merge pull request #117 from erickt/fix-json
Fix deriving traits for fully generic types.
2015-07-23 08:04:46 -07:00
Erick Tryzelaar b0512a4479 Fix deriving traits for fully generic types.
Closes #100
2015-07-23 07:25:27 -07:00
Erick Tryzelaar 8663435a05 Merge remote-tracking branch 'remotes/origin/master' into v5-5
# Conflicts:
#	serde_tests/tests/test_json.rs
2015-07-23 07:04:10 -07:00
Erick Tryzelaar 327990bc5f Merge pull request #115 from erickt/fix-json
Fix serializing maps/sequences with no size hint
2015-07-23 06:58:18 -07:00
Erick Tryzelaar 57753c9044 Fix references to serde::json 2015-07-22 10:44:43 -07:00
Erick Tryzelaar e35603eb85 Fix serializing maps/sequences with no size hint
Closes #101
2015-07-22 10:44:43 -07:00
Erick Tryzelaar 8fa40fe7e1 Move json into it's own crate
Not everyone needs json, so no reason to force people to build
it.
2015-07-22 10:44:43 -07:00
Erick Tryzelaar d4c20829f6 Inline enum visit_map 2015-07-22 10:44:43 -07:00
Erick Tryzelaar dbe2beacb0 Allow structs to be deserialized from sequences
This relies on the sequence to have the same ordering as the
struct field order.
2015-07-22 10:44:43 -07:00
Erick Tryzelaar b9a938a01c Some default de::Visitor::visit* should proxy to other methods 2015-07-22 10:44:43 -07:00
Erick Tryzelaar 4dd7345568 Simplify result serialization and deserialization 2015-07-22 10:44:43 -07:00
Erick Tryzelaar b3cf9375d4 Add Tuple Deserializer Visitor constructor 2015-07-22 10:44:43 -07:00
Erick Tryzelaar 1751155a3a Minor cleanup 2015-07-22 10:44:43 -07:00
Erick Tryzelaar 5dae700aec Pass struct field names to deserializer 2015-07-22 10:44:42 -07:00
Erick Tryzelaar affa9382be Expose variant index to Serializer 2015-07-22 10:44:42 -07:00
Erick Tryzelaar 10f23dddfe Rename named_* to use {enum,struct,unit}_*
This better reflects how they're used.
2015-07-22 10:44:42 -07:00
Erick Tryzelaar d30cf07254 Serializer::visit_enum_seq{,_elt} should call visit_named_seq{,_elt} 2015-07-22 10:44:42 -07:00
Erick Tryzelaar 31491b822f Version bump 2015-07-22 10:44:42 -07:00
Erick Tryzelaar 4c19cfead5 Fix serializing maps/sequences with no size hint
Closes #101
2015-07-22 10:41:51 -07:00
Erick Tryzelaar b2754c2c3b Merge pull request #116 from erickt/travis
Use new travis containers
2015-07-22 10:41:38 -07:00
Erick Tryzelaar f56976db1d Fix running serde_tests with nightly cargo 2015-07-22 10:40:06 -07:00
Erick Tryzelaar 77b8a8baa0 Use new travis containers 2015-07-22 09:51:19 -07:00
Erick Tryzelaar 0b9190cce3 Merge pull request #108 from dswd/patch-1
Make the TupleVisitors public
2015-07-18 21:21:09 -04:00
dswd 2a40c5dd24 Make the TupleVisitors public
This change is needed to use the TupleVisitor to implement a VariantVisitor
2015-07-17 09:58:55 +02:00
Erick Tryzelaar 60ab494226 Fix cd serde_macros && cargo build 2015-07-16 13:48:15 -04:00
Erick Tryzelaar ac758ed3c8 Version bump 2015-07-16 11:28:18 -04:00
Erick Tryzelaar 236d40d73e Add Serializer hooks for sequence elements 2015-07-16 10:51:01 -04:00
Erick Tryzelaar 92029a05c6 Add Deserializer type hints
This allows file formats like bincode, which do not encode it's values
with a type tag, to deserialize values.
2015-07-16 10:50:54 -04:00
Erick Tryzelaar c7b9997dd1 Add all of the stdlib collection deserialization implementations 2015-07-16 10:42:34 -04:00
Erick Tryzelaar 48309bfdd0 Add all of the stdlib collection serialization implementations 2015-07-16 10:00:22 -04:00
Erick Tryzelaar f76d1ab10d Compile serde_macros tests with the nightly features 2015-07-16 10:00:22 -04:00
Erick Tryzelaar 45f552f006 Fix feature flag use for NonZero 2015-07-16 10:00:21 -04:00
Erick Tryzelaar 4d42cfea53 Fix warnings 2015-07-16 09:36:14 -04:00
Erick Tryzelaar 7109e2d379 Fix the tests 2015-07-16 09:35:09 -04:00
Erick Tryzelaar ff214643ce Merge remote-tracking branch 'remotes/origin/master' into nonzero
# Conflicts:
#	serde/src/de/impls.rs
2015-07-16 09:34:45 -04:00
Erick Tryzelaar 04918a52eb Merge pull request #105 from jnicholls/boolvisitor
Make BoolVisitor public so it is documented as being in existence
2015-07-16 07:41:49 -04:00
Erick Tryzelaar 5dd71600f7 Merge pull request #102 from pcwalton/result
Implement serialization for `Result`.
2015-07-16 07:29:28 -04:00
Patrick Walton ea9ed22e3e Implement serialization for NonZero values in nightly. 2015-07-14 12:00:46 -07:00
Jarred Nicholls 1611daf802 Make BoolVisitor public so it is documented as being in existence 2015-07-13 12:13:00 -04:00
Patrick Walton e24f52d3ae Implement serialization for Result.
Servo wants this.
2015-07-10 15:08:59 -07:00
Erick Tryzelaar bcc9e15b05 Merge pull request #94 from cmbrandenburg/master
Fix spelling in README.md
2015-07-01 10:38:13 -07:00
Craig M. Brandenburg af835a2699 Fix spelling in README.md 2015-06-29 07:18:48 -07:00
Erick Tryzelaar 5f2d306f9b Merge pull request #92 from SkylerLipthay/cow-impls
Add impls for Cow
2015-06-21 10:07:00 -07:00
Skyler Lipthay 36fb49b522 Add impls for Cow 2015-06-19 22:50:16 -07:00
41 changed files with 2915 additions and 1260 deletions
+4 -1
View File
@@ -1,3 +1,4 @@
sudo: false
language: rust
rust:
- stable
@@ -25,10 +26,12 @@ after_success: |
(cd serde && cargo doc --no-deps) &&
(cd serde_codegen && cargo doc --no-deps) &&
(cd serde_macros && cargo doc --no-deps) &&
(cd serde_json && cargo doc --no-deps) &&
cp -r serde/target/doc target/doc/serde &&
cp -r serde_codegen/target/doc target/doc/serde_codegen &&
cp -r serde_macros/target/doc target/doc/serde_macros &&
cp -r serde_json/target/doc target/doc/serde_json &&
echo "<meta http-equiv=refresh content=0;url=`echo $TRAVIS_REPO_SLUG | cut -d '/' -f 2`/index.html>" > target/doc/index.html &&
sudo pip install ghp-import &&
pip install ghp-import &&
ghp-import -n target/doc &&
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
+199 -54
View File
@@ -10,78 +10,210 @@ 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 http://serde-rs.github.io/serde/serde
Documentation is available at:
Making a Type Serializable
==========================
* [serde](https://serde-rs.github.io/serde/serde/serde/index.html)
* [serde\_json](https://serde-rs.github.io/serde/serde_json/serde_json/index.html)
* [serde\_codegen](https://serde-rs.github.io/serde/serde_codegen/serde_codegen/index.html)
The simplest way to make a type serializable is to use the `serde_macros`
syntax extension, which comes with a `#[derive(Serialize, Deserialize)]`
annotation, which automatically generates implementations of
[Serialize](http://serde-rs.github.io/serde/serde/ser/trait.Serialize.html)
and
[Deserialize](http://serde-rs.github.io/serde/serde/de/trait.Deserialize.html)
for the annotated type:
Using Serde
===========
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`:
```toml
[package]
name = "serde_example_nightly"
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)]
extern crate serde;
extern crate serde_json;
...
#[derive(Serialize, Deserialize)]
#[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_point).unwrap();
println!("{:?}", deserialized);
}
```
Serde bundles a high performance JSON serializer and deserializer,
[serde::json](http://serde-rs.github.io/serde/serde/json/index.html),
which comes with the helper functions
[to_string](http://serde-rs.github.io/serde/serde/json/ser/fn.to_string.html)
and
[from_str](http://serde-rs.github.io/serde/serde/json/de/fn.from_str.html)
that make it easy to go to and from JSON:
When run, it produces:
```
% cargo run
{"x":1,"y":2}
Point { x: 1, y: 2 }
```
Stable Rust is a little more complicated because it does not yet support
compiler plugins. Instead we need to use the code generation library
[syntex](https://github.com/erickt/rust-syntex) for this:
```toml
[package]
name = "serde_example"
version = "0.1.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
build = "build.rs"
[build-dependencies]
serde_codegen = "*"
syntex = "*"
[dependencies]
serde = "*"
serde_json = "*"
```
`src/main.rs`:
```rust
use serde::json;
extern crate serde;
extern crate serde_json;
...
let point = Point { x: 1, y: 2 };
let serialized_point = json::to_string(&point).unwrap();
println!("{}", serialized_point); // prints: {"x":1,"y":2}
let deserialize_point: Point = json::from_str(&serialized_point).unwrap();
include!(concat!(env!("OUT_DIR"), "/main.rs"));
```
[serde::json](http://serde-rs.github.io/serde/serde/json/index.html) also
supports a generic
[Value](http://serde-rs.github.io/serde/serde/json/value/enum.Value.html)
type, which can represent any JSON value. Also, any
[Serialize](http://serde-rs.github.io/serde/serde/ser/trait.Serialize.html)
and
[Deserialize](http://serde-rs.github.io/serde/serde/de/trait.Deserialize.html)
can be converted into a
[Value](http://serde-rs.github.io/serde/serde/json/value/enum.Value.html)
with the methods
[to_value](http://serde-rs.github.io/serde/serde/json/value/fn.to_value.html)
and
[from_value](http://serde-rs.github.io/serde/serde/json/value/fn.from_value.html):
`src/main.rs.in`:
```rust
let point = Point { x: 1, y: 2 };
let point_value = json::to_value(&point).unwrap();
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
println!("{}", point_value.find("x")); // prints: Some(1)
fn main() {
let point = Point { x: 1, y: 2 };
let serialized = serde_json::to_string(&point).unwrap();
let deserialize_point: Point = json::from_value(point_value).unwrap();
println!("{}", serialized);
let deserialized: Point = serde_json::from_str(&serialized_point).unwrap();
println!("{:?}", deserialized);
}
```
This also produces:
```
% cargo run
{"x":1,"y":2}
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
deploy with Stable Rust and `serde_codegen`. It's possible to combine both
approaches in one setup:
`Cargo.toml`:
```toml
[package]
name = "serde_example"
version = "0.1.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
build = "build.rs"
[features]
default = ["serde_codegen"]
nightly = ["serde_macros"]
[build-dependencies]
serde_codegen = { version = "*", optional = true }
syntex = "*"
[dependencies]
serde = "*"
serde_json = "*"
serde_macros = { version = "*", optional = true }
```
`build.rs`:
```rust
#[cfg(not(feature = "serde_macros"))]
mod inner {
extern crate syntex;
extern crate serde_codegen;
use std::env;
use std::path::Path;
pub fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let src = Path::new("src/main.rs.in");
let dst = Path::new(&out_dir).join("main.rs");
let mut registry = syntex::Registry::new();
serde_codegen::register(&mut registry);
registry.expand("", &src, &dst).unwrap();
}
}
#[cfg(feature = "serde_macros")]
mod inner {
pub fn main() {}
}
fn main() {
inner::main();
}
```
`src/main.rs`:
```rust
#![cfg_attr(feature = "serde_macros", feature(custom_derive, plugin))]
#![cfg_attr(feature = "serde_macros", plugin(serde_macros))]
extern crate serde;
extern crate serde_json;
#[cfg(feature = "serde_macros")]
include!("main.rs.in");
#[cfg(not(feature = "serde_macros"))]
include!(concat!(env!("OUT_DIR"), "/main.rs"));
```
The `src/main.rs.in` is the same as before.
Serialization without Macros
============================
@@ -174,7 +306,7 @@ impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
```
Serializing structs follow this same pattern. In fact, structs are represented
as a named map. It's visitor uses a simple state machine to iterate through all
as a named map. Its visitor uses a simple state machine to iterate through all
the fields:
```rust
@@ -187,7 +319,7 @@ impl serde::Serialize for Point {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: serde::Serializer
{
serializer.visit_named_map("Point", PointMapVisitor {
serializer.visit_struct("Point", PointMapVisitor {
value: self,
state: 0,
})
@@ -206,11 +338,11 @@ impl<'a> serde::ser::MapVisitor for PointMapVisitor<'a> {
match self.state {
0 => {
self.state += 1;
Ok(Some(try!(serializer.visit_map_elt("x", &self.value.x))))
Ok(Some(try!(serializer.visit_struct_elt("x", &self.value.x))))
}
1 => {
self.state += 1;
Ok(Some(try!(serializer.visit_map_elt("y", &self.value.y))))
Ok(Some(try!(serializer.visit_struct_elt("y", &self.value.y))))
}
_ => {
Ok(None)
@@ -275,7 +407,7 @@ to generate an error for a few common error conditions. Here's how it could be u
fn visit_string<E>(&mut self, _: String) -> Result<i32, E>
where E: Error,
{
Err(serde::de::Error::syntax_error())
Err(serde::de::Error::syntax("expect a string"))
}
...
@@ -366,7 +498,7 @@ impl serde::Deserialize for PointField {
match value {
"x" => Ok(Field::X),
"y" => Ok(Field::Y),
_ => Err(serde::de::Error::syntax_error()),
_ => Err(serde::de::Error::syntax("expected x or y")),
}
}
}
@@ -383,7 +515,7 @@ impl serde::Deserialize for Point {
fn deserialize<D>(deserializer: &mut D) -> Result<Point, D::Error>
where D: serde::de::Deserializer
{
deserializer.visit_named_map("Point", PointVisitor)
deserializer.visit_struct("Point", PointVisitor)
}
}
@@ -392,7 +524,9 @@ struct PointVisitor;
impl serde::de::Visitor for PointVisitor {
type Value = Point;
fn visit_map<V>(&mut self, mut visitor: V) -> Result<Point, V::Error>
fn visit_struct<V>(&mut self,
_fields: &[&str],
mut visitor: V) -> Result<Point, V::Error>
where V: serde::de::MapVisitor
{
let mut x = None;
@@ -422,3 +556,14 @@ impl serde::de::Visitor for PointVisitor {
}
}
```
Serialization Formats Using Serde
=================================
| Format | Name |
| ------ | ---- |
| Bincode | [bincode](https://crates.io/crates/bincode) |
| 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) |
| YAML | [serde\_yaml](https://github.com/serde-rs/yaml/) |
+7 -3
View File
@@ -1,13 +1,17 @@
[package]
name = "serde"
version = "0.4.1"
version = "0.5.2"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
repository = "https://github.com/serde-rs/serde"
documentation = "http://serde-rs.github.io/serde/serde"
documentation = "https://serde-rs.github.io/serde/serde/serde/index.html"
readme = "../README.md"
keywords = ["serialization"]
keywords = ["serde", "serialization"]
[dependencies]
num = "*"
[features]
nightly = []
+387 -360
View File
@@ -1,4 +1,15 @@
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::borrow::Cow;
use std::collections::{
BinaryHeap,
BTreeMap,
BTreeSet,
LinkedList,
HashMap,
HashSet,
VecDeque,
};
#[cfg(feature = "nightly")]
use collections::enum_set::{CLike, EnumSet};
use std::hash::Hash;
use std::marker::PhantomData;
use std::path;
@@ -8,12 +19,21 @@ use std::sync::Arc;
use num::FromPrimitive;
#[cfg(feature = "nightly")]
use core::nonzero::{NonZero, Zeroable};
#[cfg(feature = "nightly")]
use std::num::Zero;
use de::{
Deserialize,
Deserializer,
EnumVisitor,
Error,
MapVisitor,
SeqVisitor,
Type,
VariantVisitor,
Visitor,
};
@@ -41,13 +61,13 @@ impl Deserialize for () {
fn deserialize<D>(deserializer: &mut D) -> Result<(), D::Error>
where D: Deserializer,
{
deserializer.visit(UnitVisitor)
deserializer.visit_unit(UnitVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
struct BoolVisitor;
pub struct BoolVisitor;
impl Visitor for BoolVisitor {
type Value = bool;
@@ -64,7 +84,7 @@ impl Visitor for BoolVisitor {
match s.trim() {
"true" => Ok(true),
"false" => Ok(false),
_ => Err(Error::syntax_error()),
_ => Err(Error::type_mismatch(Type::Bool)),
}
}
}
@@ -73,21 +93,21 @@ impl Deserialize for bool {
fn deserialize<D>(deserializer: &mut D) -> Result<bool, D::Error>
where D: Deserializer,
{
deserializer.visit(BoolVisitor)
deserializer.visit_bool(BoolVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_deserialize_num_method {
($src_ty:ty, $method:ident, $from_method:ident) => {
($src_ty:ty, $method:ident, $from_method:ident, $ty:expr) => {
#[inline]
fn $method<E>(&mut self, v: $src_ty) -> Result<T, E>
where E: Error,
{
match FromPrimitive::$from_method(v) {
Some(v) => Ok(v),
None => Err(Error::syntax_error()),
None => Err(Error::type_mismatch($ty)),
}
}
}
@@ -111,52 +131,52 @@ impl<
> Visitor for PrimitiveVisitor<T> {
type Value = T;
impl_deserialize_num_method!(isize, visit_isize, from_isize);
impl_deserialize_num_method!(i8, visit_i8, from_i8);
impl_deserialize_num_method!(i16, visit_i16, from_i16);
impl_deserialize_num_method!(i32, visit_i32, from_i32);
impl_deserialize_num_method!(i64, visit_i64, from_i64);
impl_deserialize_num_method!(usize, visit_usize, from_usize);
impl_deserialize_num_method!(u8, visit_u8, from_u8);
impl_deserialize_num_method!(u16, visit_u16, from_u16);
impl_deserialize_num_method!(u32, visit_u32, from_u32);
impl_deserialize_num_method!(u64, visit_u64, from_u64);
impl_deserialize_num_method!(f32, visit_f32, from_f32);
impl_deserialize_num_method!(f64, visit_f64, from_f64);
impl_deserialize_num_method!(isize, visit_isize, from_isize, Type::Isize);
impl_deserialize_num_method!(i8, visit_i8, from_i8, Type::I8);
impl_deserialize_num_method!(i16, visit_i16, from_i16, Type::I16);
impl_deserialize_num_method!(i32, visit_i32, from_i32, Type::I32);
impl_deserialize_num_method!(i64, visit_i64, from_i64, Type::I64);
impl_deserialize_num_method!(usize, visit_usize, from_usize, Type::Usize);
impl_deserialize_num_method!(u8, visit_u8, from_u8, Type::U8);
impl_deserialize_num_method!(u16, visit_u16, from_u16, Type::U16);
impl_deserialize_num_method!(u32, visit_u32, from_u32, Type::U32);
impl_deserialize_num_method!(u64, visit_u64, from_u64, Type::U64);
impl_deserialize_num_method!(f32, visit_f32, from_f32, Type::F32);
impl_deserialize_num_method!(f64, visit_f64, from_f64, Type::F64);
#[inline]
fn visit_str<E>(&mut self, v: &str) -> Result<T, E>
where E: Error,
{
str::FromStr::from_str(v.trim()).or(Err(Error::syntax_error()))
str::FromStr::from_str(v.trim()).or(Err(Error::type_mismatch(Type::Str)))
}
}
macro_rules! impl_deserialize_num {
($ty:ty) => {
($ty:ty, $method:ident) => {
impl Deserialize for $ty {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
where D: Deserializer,
{
deserializer.visit(PrimitiveVisitor::new())
deserializer.$method(PrimitiveVisitor::new())
}
}
}
}
impl_deserialize_num!(isize);
impl_deserialize_num!(i8);
impl_deserialize_num!(i16);
impl_deserialize_num!(i32);
impl_deserialize_num!(i64);
impl_deserialize_num!(usize);
impl_deserialize_num!(u8);
impl_deserialize_num!(u16);
impl_deserialize_num!(u32);
impl_deserialize_num!(u64);
impl_deserialize_num!(f32);
impl_deserialize_num!(f64);
impl_deserialize_num!(isize, visit_isize);
impl_deserialize_num!(i8, visit_i8);
impl_deserialize_num!(i16, visit_i16);
impl_deserialize_num!(i32, visit_i32);
impl_deserialize_num!(i64, visit_i64);
impl_deserialize_num!(usize, visit_usize);
impl_deserialize_num!(u8, visit_u8);
impl_deserialize_num!(u16, visit_u16);
impl_deserialize_num!(u32, visit_u32);
impl_deserialize_num!(u64, visit_u64);
impl_deserialize_num!(f32, visit_f32);
impl_deserialize_num!(f64, visit_f64);
///////////////////////////////////////////////////////////////////////////////
@@ -179,12 +199,12 @@ impl Visitor for CharVisitor {
let mut iter = v.chars();
if let Some(v) = iter.next() {
if iter.next().is_some() {
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::Char))
} else {
Ok(v)
}
} else {
Err(Error::end_of_stream_error())
Err(Error::end_of_stream())
}
}
}
@@ -194,7 +214,7 @@ impl Deserialize for char {
fn deserialize<D>(deserializer: &mut D) -> Result<char, D::Error>
where D: Deserializer,
{
deserializer.visit(CharVisitor)
deserializer.visit_char(CharVisitor)
}
}
@@ -222,7 +242,7 @@ impl Visitor for StringVisitor {
{
match str::from_utf8(v) {
Ok(s) => Ok(s.to_string()),
Err(_) => Err(Error::syntax_error()),
Err(_) => Err(Error::type_mismatch(Type::String)),
}
}
@@ -231,7 +251,7 @@ impl Visitor for StringVisitor {
{
match String::from_utf8(v) {
Ok(s) => Ok(s),
Err(_) => Err(Error::syntax_error()),
Err(_) => Err(Error::type_mismatch(Type::String)),
}
}
}
@@ -240,7 +260,7 @@ impl Deserialize for String {
fn deserialize<D>(deserializer: &mut D) -> Result<String, D::Error>
where D: Deserializer,
{
deserializer.visit(StringVisitor)
deserializer.visit_string(StringVisitor)
}
}
@@ -280,159 +300,131 @@ impl<T> Deserialize for Option<T> where T: Deserialize {
///////////////////////////////////////////////////////////////////////////////
pub struct BTreeSetVisitor<T> {
marker: PhantomData<T>,
}
macro_rules! set_impl {
(
$ty:ty,
< $($constraints:ident),* >,
$visitor_name:ident,
$visitor:ident,
$ctor:expr,
$with_capacity:expr,
$insert:expr
) => {
pub struct $visitor_name<T> {
marker: PhantomData<T>,
}
impl<T> BTreeSetVisitor<T> {
pub fn new() -> Self {
BTreeSetVisitor {
marker: PhantomData,
impl<T> $visitor_name<T> {
pub fn new() -> Self {
$visitor_name {
marker: PhantomData,
}
}
}
impl<T> Visitor for $visitor_name<T>
where T: $($constraints +)*,
{
type Value = $ty;
#[inline]
fn visit_unit<E>(&mut self) -> Result<$ty, E>
where E: Error,
{
Ok($ctor)
}
#[inline]
fn visit_seq<V>(&mut self, mut $visitor: V) -> Result<$ty, V::Error>
where V: SeqVisitor,
{
let mut values = $with_capacity;
while let Some(value) = try!($visitor.visit()) {
$insert(&mut values, value);
}
try!($visitor.end());
Ok(values)
}
}
impl<T> Deserialize for $ty
where T: $($constraints +)*,
{
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
where D: Deserializer,
{
deserializer.visit_seq($visitor_name::new())
}
}
}
}
impl<T> Visitor for BTreeSetVisitor<T>
where T: Deserialize + Eq + Ord,
{
type Value = BTreeSet<T>;
set_impl!(
BinaryHeap<T>,
<Deserialize, Ord>,
BinaryHeapVisitor,
visitor,
BinaryHeap::new(),
BinaryHeap::with_capacity(visitor.size_hint().0),
BinaryHeap::push);
#[inline]
fn visit_unit<E>(&mut self) -> Result<BTreeSet<T>, E>
where E: Error,
{
Ok(BTreeSet::new())
}
set_impl!(
BTreeSet<T>,
<Deserialize, Eq, Ord>,
BTreeSetVisitor,
visitor,
BTreeSet::new(),
BTreeSet::new(),
BTreeSet::insert);
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<BTreeSet<T>, V::Error>
where V: SeqVisitor,
{
let mut values = BTreeSet::new();
#[cfg(feature = "nightly")]
set_impl!(
EnumSet<T>,
<Deserialize, CLike>,
EnumSetVisitor,
visitor,
EnumSet::new(),
EnumSet::new(),
EnumSet::insert);
while let Some(value) = try!(visitor.visit()) {
values.insert(value);
}
set_impl!(
LinkedList<T>,
<Deserialize>,
LinkedListVisitor,
visitor,
LinkedList::new(),
LinkedList::new(),
LinkedList::push_back);
try!(visitor.end());
set_impl!(
HashSet<T>,
<Deserialize, Eq, Hash>,
HashSetVisitor,
visitor,
HashSet::new(),
HashSet::with_capacity(visitor.size_hint().0),
HashSet::insert);
Ok(values)
}
}
set_impl!(
Vec<T>,
<Deserialize>,
VecVisitor,
visitor,
Vec::new(),
Vec::with_capacity(visitor.size_hint().0),
Vec::push);
impl<T> Deserialize for BTreeSet<T>
where T: Deserialize + Eq + Ord,
{
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeSet<T>, D::Error>
where D: Deserializer,
{
deserializer.visit(BTreeSetVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct HashSetVisitor<T> {
marker: PhantomData<T>,
}
impl<T> HashSetVisitor<T> {
pub fn new() -> Self {
HashSetVisitor {
marker: PhantomData,
}
}
}
impl<T> Visitor for HashSetVisitor<T>
where T: Deserialize + Eq + Hash,
{
type Value = HashSet<T>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<HashSet<T>, E>
where E: Error,
{
Ok(HashSet::new())
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<HashSet<T>, V::Error>
where V: SeqVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = HashSet::with_capacity(len);
while let Some(value) = try!(visitor.visit()) {
values.insert(value);
}
try!(visitor.end());
Ok(values)
}
}
impl<T> Deserialize for HashSet<T>
where T: Deserialize + Eq + Hash,
{
fn deserialize<D>(deserializer: &mut D) -> Result<HashSet<T>, D::Error>
where D: Deserializer,
{
deserializer.visit(HashSetVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct VecVisitor<T> {
marker: PhantomData<T>,
}
impl<T> VecVisitor<T> {
pub fn new() -> Self {
VecVisitor {
marker: PhantomData,
}
}
}
impl<T> Visitor for VecVisitor<T> where T: Deserialize {
type Value = Vec<T>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<Vec<T>, E>
where E: Error,
{
Ok(Vec::new())
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<Vec<T>, V::Error>
where V: SeqVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = Vec::with_capacity(len);
while let Some(value) = try!(visitor.visit()) {
values.push(value);
}
try!(visitor.end());
Ok(values)
}
}
impl<T> Deserialize for Vec<T>
where T: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<Vec<T>, D::Error>
where D: Deserializer,
{
deserializer.visit_seq(VecVisitor::new())
}
}
set_impl!(
VecDeque<T>,
<Deserialize>,
VecDequeVisitor,
visitor,
VecDeque::new(),
VecDeque::with_capacity(visitor.size_hint().0),
VecDeque::push_back);
///////////////////////////////////////////////////////////////////////////////
@@ -473,7 +465,7 @@ impl<T> Deserialize for [T; 0]
fn deserialize<D>(deserializer: &mut D) -> Result<[T; 0], D::Error>
where D: Deserializer,
{
deserializer.visit(ArrayVisitor0::new())
deserializer.visit_seq(ArrayVisitor0::new())
}
}
@@ -502,7 +494,7 @@ macro_rules! array_impls {
$(
let $name = match try!(visitor.visit()) {
Some(val) => val,
None => { return Err(Error::end_of_stream_error()); }
None => { return Err(Error::end_of_stream()); }
};
)+;
@@ -518,7 +510,7 @@ macro_rules! array_impls {
fn deserialize<D>(deserializer: &mut D) -> Result<[T; $len], D::Error>
where D: Deserializer,
{
deserializer.visit($visitor::new())
deserializer.visit_seq($visitor::new())
}
}
)+
@@ -572,12 +564,21 @@ array_impls! {
macro_rules! tuple_impls {
() => {};
($($visitor:ident => ($($name:ident),+),)+) => {
($($len:expr => $visitor:ident => ($($name:ident),+),)+) => {
$(
struct $visitor<$($name,)+> {
pub struct $visitor<$($name,)+> {
marker: PhantomData<($($name,)+)>,
}
impl<
$($name: Deserialize,)+
> $visitor<$($name,)+> {
pub fn new() -> Self {
$visitor { marker: PhantomData }
}
}
impl<
$($name: Deserialize,)+
> Visitor for $visitor<$($name,)+> {
@@ -591,7 +592,7 @@ macro_rules! tuple_impls {
$(
let $name = match try!(visitor.visit()) {
Some(value) => value,
None => { return Err(Error::end_of_stream_error()); }
None => { return Err(Error::end_of_stream()); }
};
)+;
@@ -608,7 +609,7 @@ macro_rules! tuple_impls {
fn deserialize<D>(deserializer: &mut D) -> Result<($($name,)+), D::Error>
where D: Deserializer,
{
deserializer.visit_seq($visitor { marker: PhantomData })
deserializer.visit_tuple($len, $visitor::new())
}
}
)+
@@ -616,187 +617,103 @@ macro_rules! tuple_impls {
}
tuple_impls! {
TupleVisitor1 => (T0),
TupleVisitor2 => (T0, T1),
TupleVisitor3 => (T0, T1, T2),
TupleVisitor4 => (T0, T1, T2, T3),
TupleVisitor5 => (T0, T1, T2, T3, T4),
TupleVisitor6 => (T0, T1, T2, T3, T4, T5),
TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6),
TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7),
TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8),
TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9),
TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10),
TupleVisitor12 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11),
1 => TupleVisitor1 => (T0),
2 => TupleVisitor2 => (T0, T1),
3 => TupleVisitor3 => (T0, T1, T2),
4 => TupleVisitor4 => (T0, T1, T2, T3),
5 => TupleVisitor5 => (T0, T1, T2, T3, T4),
6 => TupleVisitor6 => (T0, T1, T2, T3, T4, T5),
7 => TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6),
8 => TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7),
9 => TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8),
10 => TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9),
11 => TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10),
12 => TupleVisitor12 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11),
}
///////////////////////////////////////////////////////////////////////////////
pub struct BTreeMapVisitor<K, V> {
marker: PhantomData<BTreeMap<K, V>>,
}
macro_rules! map_impl {
(
$ty:ty,
< $($constraints:ident),* >,
$visitor_name:ident,
$visitor:ident,
$ctor:expr,
$with_capacity:expr,
$insert:expr
) => {
pub struct $visitor_name<K, V> {
marker: PhantomData<$ty>,
}
impl<K, V> BTreeMapVisitor<K, V> {
#[inline]
pub fn new() -> Self {
BTreeMapVisitor {
marker: PhantomData,
impl<K, V> $visitor_name<K, V> {
pub fn new() -> Self {
$visitor_name {
marker: PhantomData,
}
}
}
impl<K, V> Visitor for $visitor_name<K, V>
where K: $($constraints +)*,
V: Deserialize,
{
type Value = $ty;
#[inline]
fn visit_unit<E>(&mut self) -> Result<$ty, E>
where E: Error,
{
Ok($ctor)
}
#[inline]
fn visit_map<Visitor>(&mut self, mut $visitor: Visitor) -> Result<$ty, Visitor::Error>
where Visitor: MapVisitor,
{
let mut values = $with_capacity;
while let Some((key, value)) = try!($visitor.visit()) {
$insert(&mut values, key, value);
}
try!($visitor.end());
Ok(values)
}
}
impl<K, V> Deserialize for $ty
where K: $($constraints +)*,
V: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<$ty, D::Error>
where D: Deserializer,
{
deserializer.visit_map($visitor_name::new())
}
}
}
}
impl<K, V> Visitor for BTreeMapVisitor<K, V>
where K: Deserialize + Ord,
V: Deserialize
{
type Value = BTreeMap<K, V>;
map_impl!(
BTreeMap<K, V>,
<Deserialize, Eq, Ord>,
BTreeMapVisitor,
visitor,
BTreeMap::new(),
BTreeMap::new(),
BTreeMap::insert);
#[inline]
fn visit_unit<E>(&mut self) -> Result<BTreeMap<K, V>, E>
where E: Error,
{
Ok(BTreeMap::new())
}
#[inline]
fn visit_map<Visitor>(&mut self, mut visitor: Visitor) -> Result<BTreeMap<K, V>, Visitor::Error>
where Visitor: MapVisitor,
{
let mut values = BTreeMap::new();
while let Some((key, value)) = try!(visitor.visit()) {
values.insert(key, value);
}
try!(visitor.end());
Ok(values)
}
}
impl<K, V> Deserialize for BTreeMap<K, V>
where K: Deserialize + Eq + Ord,
V: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeMap<K, V>, D::Error>
where D: Deserializer,
{
deserializer.visit(BTreeMapVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct HashMapVisitor<K, V> {
marker: PhantomData<HashMap<K, V>>,
}
impl<K, V> HashMapVisitor<K, V> {
#[inline]
pub fn new() -> Self {
HashMapVisitor {
marker: PhantomData,
}
}
}
impl<K, V> Visitor for HashMapVisitor<K, V>
where K: Deserialize + Eq + Hash,
V: Deserialize,
{
type Value = HashMap<K, V>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<HashMap<K, V>, E>
where E: Error,
{
Ok(HashMap::new())
}
#[inline]
fn visit_map<V_>(&mut self, mut visitor: V_) -> Result<HashMap<K, V>, V_::Error>
where V_: MapVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = HashMap::with_capacity(len);
while let Some((key, value)) = try!(visitor.visit()) {
values.insert(key, value);
}
try!(visitor.end());
Ok(values)
}
}
impl<K, V> Deserialize for HashMap<K, V>
where K: Deserialize + Eq + Hash,
V: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<HashMap<K, V>, D::Error>
where D: Deserializer,
{
deserializer.visit(HashMapVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
// FIXME: `VecMap` is unstable.
/*
pub struct VecMapVisitor<V> {
marker: PhantomData<VecMap<V>>,
}
impl<V> VecMapVisitor<V> {
#[inline]
pub fn new() -> Self {
VecMapVisitor {
marker: PhantomData,
}
}
}
impl<V> Visitor for VecMapVisitor<V>
where V: Deserialize,
{
type Value = VecMap<V>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<VecMap<V>, E>
where E: Error,
{
Ok(VecMap::new())
}
#[inline]
fn visit_map<V_>(&mut self, mut visitor: V_) -> Result<VecMap<V>, V_::Error>
where V_: MapVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = VecMap::with_capacity(len);
while let Some((key, value)) = try!(visitor.visit()) {
values.insert(key, value);
}
try!(visitor.end());
Ok(values)
}
}
impl<V> Deserialize for VecMap<V>
where V: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<VecMap<V>, D::Error>
where D: Deserializer,
{
deserializer.visit(VecMapVisitor::new())
}
}
*/
map_impl!(
HashMap<K, V>,
<Deserialize, Eq, Hash>,
HashMapVisitor,
visitor,
HashMap::new(),
HashMap::with_capacity(visitor.size_hint().0),
HashMap::insert);
///////////////////////////////////////////////////////////////////////////////
@@ -854,3 +771,113 @@ impl<T: Deserialize> Deserialize for Rc<T> {
Ok(Rc::new(val))
}
}
impl<'a, T: ?Sized> Deserialize for Cow<'a, T> where T: ToOwned, T::Owned: Deserialize, {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<Cow<'a, T>, D::Error>
where D: Deserializer,
{
let val = try!(Deserialize::deserialize(deserializer));
Ok(Cow::Owned(val))
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "nightly")]
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));
if value == Zero::zero() {
return Err(Error::syntax("expected a non-zero value"))
}
unsafe {
Ok(NonZero::new(value))
}
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
fn deserialize<D>(deserializer: &mut D) -> Result<Result<T, E>, D::Error>
where D: Deserializer {
enum Field {
Ok,
Err,
}
impl Deserialize for Field {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
where D: Deserializer
{
struct FieldVisitor;
impl ::de::Visitor for FieldVisitor {
type Value = Field;
fn visit_usize<E>(&mut self, value: usize) -> Result<Field, E> where E: Error {
match value {
0 => Ok(Field::Ok),
1 => Ok(Field::Err),
_ => Err(Error::unknown_field(&value.to_string())),
}
}
fn visit_str<E>(&mut self, value: &str) -> Result<Field, E> where E: Error {
match value {
"Ok" => Ok(Field::Ok),
"Err" => Ok(Field::Err),
_ => Err(Error::unknown_field(value)),
}
}
fn visit_bytes<E>(&mut self, value: &[u8]) -> Result<Field, E> where E: Error {
match value {
b"Ok" => Ok(Field::Ok),
b"Err" => Ok(Field::Err),
_ => {
match str::from_utf8(value) {
Ok(value) => Err(Error::unknown_field(value)),
Err(_) => Err(Error::type_mismatch(Type::String)),
}
}
}
}
}
deserializer.visit(FieldVisitor)
}
}
struct Visitor<T, E>(PhantomData<Result<T, E>>);
impl<T, E> EnumVisitor for Visitor<T, E>
where T: Deserialize,
E: Deserialize
{
type Value = Result<T, E>;
fn visit<V>(&mut self, mut visitor: V) -> Result<Result<T, E>, V::Error>
where V: VariantVisitor
{
match try!(visitor.visit_variant()) {
Field::Ok => {
let value = try!(visitor.visit_newtype());
Ok(Ok(value))
}
Field::Err => {
let value = try!(visitor.visit_newtype());
Ok(Err(value))
}
}
}
}
const VARIANTS: &'static [&'static str] = &["Ok", "Err"];
deserializer.visit_enum("Result", VARIANTS, Visitor(PhantomData))
}
}
+320 -67
View File
@@ -5,14 +5,65 @@ pub mod value;
///////////////////////////////////////////////////////////////////////////////
pub trait Error {
fn syntax_error() -> Self;
/// `Error` is a trait that allows a `Deserialize` to generically create a
/// `Deserializer` error.
pub trait Error: Sized {
/// Raised when there is general error when deserializing a type.
fn syntax(msg: &str) -> Self;
fn end_of_stream_error() -> Self;
/// Raised when a fixed sized sequence or map was passed in the wrong amount of arguments.
fn length_mismatch(_len: usize) -> Self {
Error::syntax("incorrect length")
}
fn unknown_field_error(field: &str) -> Self;
/// Raised when a `Deserialize` was passed an incorrect type.
fn type_mismatch(_type: Type) -> Self {
Error::syntax("incorrect type")
}
fn missing_field_error(field: &'static str) -> Self;
/// Raised when a `Deserialize` type unexpectedly hit the end of the stream.
fn end_of_stream() -> Self;
/// Raised when a `Deserialize` struct type received an unexpected struct field.
fn unknown_field(field: &str) -> Self;
/// Raised when a `Deserialize` struct type did not receive a field.
fn missing_field(field: &'static str) -> Self;
}
/// `Type` represents all the primitive types that can be deserialized. This is used by
/// `Error::kind_mismatch`.
pub enum Type {
Bool,
Usize,
U8,
U16,
U32,
U64,
Isize,
I8,
I16,
I32,
I64,
F32,
F64,
Char,
Str,
String,
Unit,
Option,
Seq,
Map,
UnitStruct,
NewtypeStruct,
TupleStruct,
Struct,
Tuple,
Enum,
StructVariant,
TupleVariant,
UnitVariant,
Bytes,
}
///////////////////////////////////////////////////////////////////////////////
@@ -25,18 +76,164 @@ pub trait Deserialize {
///////////////////////////////////////////////////////////////////////////////
/// `Deserializer` is an abstract trait that can deserialize values into a `Visitor`.
/// `Deserializer` is a trait that can deserialize values by threading a `Visitor` trait through a
/// value. It supports two entry point styles which enables different kinds of deserialization.
///
/// 1) The `visit` method. File formats like JSON embed the type of it's construct in it's file
/// format. This allows the `Deserializer` to deserialize into a generic type like
/// `json::Value`, which can represent all JSON types.
///
/// 2) The `visit_*` methods. File formats like bincode do not embed in it's format how to decode
/// it's values. It relies instead on the `Deserialize` type to hint to the `Deserializer` with
/// the `visit_*` methods how it should parse the next value. One downside though to only
/// supporting the `visit_*` types is that it does not allow for deserializing into a generic
/// `json::Value`-esque type.
pub trait Deserializer {
type Error: Error;
/// The `visit` method walks a visitor through a value as it is being deserialized.
/// This method walks a visitor through a value as it is being deserialized.
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor;
/// The `visit_option` method allows a `Deserialize` type to inform the `Deserializer` that
/// it's expecting an optional value. This allows deserializers that encode an optional value
/// as a nullable value to convert the null value into a `None`, and a regular value as
/// `Some(value)`.
/// This method hints that the `Deserialize` type is expecting a `bool` value.
#[inline]
fn visit_bool<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `usize` value.
#[inline]
fn visit_usize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_u64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `u8` value.
#[inline]
fn visit_u8<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_u64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `u16` value.
#[inline]
fn visit_u16<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_u64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `u32` value.
#[inline]
fn visit_u32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_u64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `u64` value.
#[inline]
fn visit_u64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `isize` value.
#[inline]
fn visit_isize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_i64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i8` value.
#[inline]
fn visit_i8<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_i64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i16` value.
#[inline]
fn visit_i16<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_i64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i32` value.
#[inline]
fn visit_i32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_i64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i64` value.
#[inline]
fn visit_i64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `f32` value.
#[inline]
fn visit_f32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_f64(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `f64` value.
#[inline]
fn visit_f64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `char` value.
#[inline]
fn visit_char<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `&str` value.
#[inline]
fn visit_str<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `String` value.
#[inline]
fn visit_string<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_str(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `unit` value.
#[inline]
fn visit_unit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `Option` value. This allows
/// deserializers that encode an optional value as a nullable value to convert the null value
/// into a `None`, and a regular value as `Some(value)`.
#[inline]
fn visit_option<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
@@ -44,9 +241,8 @@ pub trait Deserializer {
self.visit(visitor)
}
/// The `visit_seq` method allows a `Deserialize` type to inform the `Deserializer` that it's
/// expecting a sequence of values. This allows deserializers to parse sequences that aren't
/// tagged as sequences.
/// This method hints that the `Deserialize` type is expecting a sequence value. This allows
/// deserializers to parse sequences that aren't tagged as sequences.
#[inline]
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
@@ -54,9 +250,8 @@ pub trait Deserializer {
self.visit(visitor)
}
/// The `visit_map` method allows a `Deserialize` type to inform the `Deserializer` that it's
/// expecting a map of values. This allows deserializers to parse sequences that aren't tagged
/// as maps.
/// This method hints that the `Deserialize` type is expecting a map of values. This allows
/// deserializers to parse sequences that aren't tagged as maps.
#[inline]
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
@@ -64,54 +259,82 @@ pub trait Deserializer {
self.visit(visitor)
}
/// The `visit_named_unit` method allows a `Deserialize` type to inform the `Deserializer` that
/// it's expecting a named unit. This allows deserializers to a named unit that aren't tagged
/// as a named unit.
/// This method hints that the `Deserialize` type is expecting a unit struct. This allows
/// deserializers to a unit struct that aren't tagged as a unit struct.
#[inline]
fn visit_named_unit<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
fn visit_unit_struct<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
self.visit_unit(visitor)
}
/// The `visit_named_seq` method allows a `Deserialize` type to inform the `Deserializer` that
/// it's expecting a named sequence of values. This allows deserializers to parse sequences
/// that aren't tagged as sequences.
/// This method hints that the `Deserialize` type is expecting a newtype struct. This allows
/// deserializers to a newtype struct that aren't tagged as a newtype struct.
#[inline]
fn visit_named_seq<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
fn visit_newtype_struct<V>(&mut self,
name: &'static str,
visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_seq(visitor)
self.visit_tuple_struct(name, 1, visitor)
}
/// The `visit_named_map` method allows a `Deserialize` type to inform the `Deserializer` that
/// it's expecting a map of values. This allows deserializers to parse sequences that aren't
/// tagged as maps.
/// This method hints that the `Deserialize` type is expecting a tuple struct. This allows
/// deserializers to parse sequences that aren't tagged as sequences.
#[inline]
fn visit_named_map<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
fn visit_tuple_struct<V>(&mut self,
_name: &'static str,
len: usize,
visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_tuple(len, visitor)
}
/// This method hints that the `Deserialize` type is expecting a struct. This allows
/// deserializers to parse sequences that aren't tagged as maps.
#[inline]
fn visit_struct<V>(&mut self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_map(visitor)
}
/// The `visit_enum` method allows a `Deserialize` type to inform the `Deserializer` that it's
/// expecting an enum value. This allows deserializers that provide a custom enumeration
/// serialization to properly deserialize the type.
/// This method hints that the `Deserialize` type is expecting a tuple value. This allows
/// deserializers that provide a custom tuple serialization to properly deserialize the type.
#[inline]
fn visit_enum<V>(&mut self, _enum: &str, _visitor: V) -> Result<V::Value, Self::Error>
where V: EnumVisitor,
fn visit_tuple<V>(&mut self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
Err(Error::syntax_error())
self.visit_seq(visitor)
}
/// The `visit_bytes` method allows a `Deserialize` type to inform the `Deserializer` that it's
/// expecting a `Vec<u8>`. This allows deserializers that provide a custom byte vector
/// serialization to properly deserialize the type.
/// This method hints that the `Deserialize` type is expecting an enum value. This allows
/// deserializers that provide a custom enumeration serialization to properly deserialize the
/// type.
#[inline]
fn visit_enum<V>(&mut self,
_enum: &'static str,
_variants: &'static [&'static str],
_visitor: V) -> Result<V::Value, Self::Error>
where V: EnumVisitor,
{
Err(Error::syntax("expected an enum"))
}
/// This method hints that the `Deserialize` type is expecting a `Vec<u8>`. This allows
/// deserializers that provide a custom byte vector serialization to properly deserialize the
/// type.
#[inline]
fn visit_bytes<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
self.visit_seq(visitor)
}
/// Specify a format string for the deserializer.
@@ -132,7 +355,7 @@ pub trait Visitor {
fn visit_bool<E>(&mut self, _v: bool) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::Bool))
}
fn visit_isize<E>(&mut self, v: isize) -> Result<Self::Value, E>
@@ -162,7 +385,7 @@ pub trait Visitor {
fn visit_i64<E>(&mut self, _v: i64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::I64))
}
fn visit_usize<E>(&mut self, v: usize) -> Result<Self::Value, E>
@@ -192,7 +415,7 @@ pub trait Visitor {
fn visit_u64<E>(&mut self, _v: u64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::U64))
}
fn visit_f32<E>(&mut self, v: f32) -> Result<Self::Value, E>
@@ -204,7 +427,7 @@ pub trait Visitor {
fn visit_f64<E>(&mut self, _v: f64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::F64))
}
#[inline]
@@ -219,7 +442,7 @@ pub trait Visitor {
fn visit_str<E>(&mut self, _v: &str) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::Str))
}
#[inline]
@@ -232,11 +455,11 @@ pub trait Visitor {
fn visit_unit<E>(&mut self) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::Unit))
}
#[inline]
fn visit_named_unit<E>(&mut self, _name: &str) -> Result<Self::Value, E>
fn visit_unit_struct<E>(&mut self, _name: &'static str) -> Result<Self::Value, E>
where E: Error,
{
self.visit_unit()
@@ -245,31 +468,37 @@ pub trait Visitor {
fn visit_none<E>(&mut self) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::Option))
}
fn visit_some<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
where D: Deserializer,
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::Option))
}
fn visit_newtype_struct<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
where D: Deserializer,
{
Err(Error::type_mismatch(Type::NewtypeStruct))
}
fn visit_seq<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor,
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::Seq))
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor,
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::Map))
}
fn visit_bytes<E>(&mut self, _v: &[u8]) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::Bytes))
}
fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<Self::Value, E>
@@ -351,7 +580,7 @@ pub trait MapVisitor {
fn missing_field<V>(&mut self, field: &'static str) -> Result<V, Self::Error>
where V: Deserialize,
{
Err(Error::missing_field_error(field))
Err(Error::missing_field(field))
}
}
@@ -415,21 +644,35 @@ pub trait VariantVisitor {
/// `visit_unit` is called when deserializing a variant with no values.
fn visit_unit(&mut self) -> Result<(), Self::Error> {
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::UnitVariant))
}
/// `visit_seq` is called when deserializing a tuple-like variant.
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor
/// `visit_newtype` is called when deserializing a variant with a single value. By default this
/// uses the `visit_tuple` method to deserialize the value.
#[inline]
fn visit_newtype<T>(&mut self) -> Result<T, Self::Error>
where T: Deserialize,
{
Err(Error::syntax_error())
let (value,) = try!(self.visit_tuple(1, impls::TupleVisitor1::new()));
Ok(value)
}
/// `visit_map` is called when deserializing a struct-like variant.
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
/// `visit_tuple` is called when deserializing a tuple-like variant.
fn visit_tuple<V>(&mut self,
_len: usize,
_visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor
{
Err(Error::syntax_error())
Err(Error::type_mismatch(Type::TupleVariant))
}
/// `visit_struct` is called when deserializing a struct-like variant.
fn visit_struct<V>(&mut self,
_fields: &'static [&'static str],
_visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor
{
Err(Error::type_mismatch(Type::StructVariant))
}
}
@@ -446,16 +689,26 @@ impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor {
(**self).visit_unit()
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
fn visit_newtype<D>(&mut self) -> Result<D, T::Error>
where D: Deserialize,
{
(**self).visit_seq(visitor)
(**self).visit_newtype()
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
fn visit_tuple<V>(&mut self,
len: usize,
visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{
(**self).visit_map(visitor)
(**self).visit_tuple(len, visitor)
}
fn visit_struct<V>(&mut self,
fields: &'static [&'static str],
visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{
(**self).visit_struct(fields, visitor)
}
}
+20 -14
View File
@@ -24,10 +24,10 @@ pub enum Error {
}
impl de::Error for Error {
fn syntax_error() -> Self { Error::SyntaxError }
fn end_of_stream_error() -> Self { Error::EndOfStreamError }
fn unknown_field_error(field: &str) -> Self { Error::UnknownFieldError(field.to_string()) }
fn missing_field_error(field: &'static str) -> Self { Error::MissingFieldError(field) }
fn syntax(_: &str) -> Self { Error::SyntaxError }
fn end_of_stream() -> Self { Error::EndOfStreamError }
fn unknown_field(field: &str) -> Self { Error::UnknownFieldError(String::from(field)) }
fn missing_field(field: &'static str) -> Self { Error::MissingFieldError(field) }
}
///////////////////////////////////////////////////////////////////////////////
@@ -89,7 +89,7 @@ macro_rules! primitive_deserializer {
{
match self.0.take() {
Some(v) => visitor.$method(v),
None => Err(de::Error::end_of_stream_error()),
None => Err(de::Error::end_of_stream()),
}
}
}
@@ -132,11 +132,14 @@ impl<'a> de::Deserializer for StrDeserializer<'a> {
{
match self.0.take() {
Some(v) => visitor.visit_str(v),
None => Err(de::Error::end_of_stream_error()),
None => Err(de::Error::end_of_stream()),
}
}
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_enum<V>(&mut self,
_name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
visitor.visit(self)
@@ -178,11 +181,14 @@ impl de::Deserializer for StringDeserializer {
{
match self.0.take() {
Some(string) => visitor.visit_string(string),
None => Err(de::Error::end_of_stream_error()),
None => Err(de::Error::end_of_stream()),
}
}
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_enum<V>(&mut self,
_name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
visitor.visit(self)
@@ -255,7 +261,7 @@ impl<I, T> de::SeqVisitor for SeqDeserializer<I>
if self.len == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream_error())
Err(de::Error::length_mismatch(self.len))
}
}
@@ -368,7 +374,7 @@ impl<I, K, V> de::MapVisitor for MapDeserializer<I, K, V>
let mut de = value.into_deserializer();
de::Deserialize::deserialize(&mut de)
}
None => Err(de::Error::syntax_error())
None => Err(de::Error::syntax("expected a map value"))
}
}
@@ -376,7 +382,7 @@ impl<I, K, V> de::MapVisitor for MapDeserializer<I, K, V>
if self.len == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream_error())
Err(de::Error::length_mismatch(self.len))
}
}
@@ -432,7 +438,7 @@ impl<'a> de::Deserializer for BytesDeserializer<'a> {
{
match self.0.take() {
Some(bytes) => visitor.visit_bytes(bytes),
None => Err(de::Error::end_of_stream_error()),
None => Err(de::Error::end_of_stream()),
}
}
}
@@ -459,7 +465,7 @@ impl de::Deserializer for ByteBufDeserializer {
{
match self.0.take() {
Some(bytes) => visitor.visit_byte_buf(bytes),
None => Err(de::Error::end_of_stream_error()),
None => Err(de::Error::end_of_stream()),
}
}
}
+8 -2
View File
@@ -5,15 +5,21 @@
//! 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.
#![doc(html_root_url="http://erickt.github.io/rust-serde")]
#![doc(html_root_url="https://serde-rs.github.io/serde/serde")]
#![cfg_attr(feature = "nightly", feature(collections, core, enumset, nonzero, step_trait, zero_one))]
extern crate num;
#[cfg(feature = "nightly")]
extern crate collections;
#[cfg(feature = "nightly")]
extern crate core;
pub use ser::{Serialize, Serializer};
pub use de::{Deserialize, Deserializer, Error};
pub mod bytes;
pub mod de;
pub mod iter;
pub mod json;
pub mod ser;
+138 -22
View File
@@ -1,9 +1,29 @@
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::borrow::Cow;
use std::collections::{
BinaryHeap,
BTreeMap,
BTreeSet,
LinkedList,
HashMap,
HashSet,
VecDeque,
};
#[cfg(feature = "nightly")]
use collections::enum_set::{CLike, EnumSet};
use std::hash::Hash;
#[cfg(feature = "nightly")]
use std::iter;
#[cfg(feature = "nightly")]
use std::num;
#[cfg(feature = "nightly")]
use std::ops;
use std::path;
use std::rc::Rc;
use std::sync::Arc;
#[cfg(feature = "nightly")]
use core::nonzero::{NonZero, Zeroable};
use super::{
Serialize,
Serializer,
@@ -75,6 +95,26 @@ 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.visit_seq_elt(value));
Ok(Some(()))
}
None => Ok(None),
}
}
#[inline]
fn len(&self) -> Option<usize> {
Some(if self.is_some() { 1 } else { 0 })
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct SeqIteratorVisitor<Iter> {
@@ -104,8 +144,8 @@ impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
{
match self.iter.next() {
Some(value) => {
let value = try!(serializer.visit_seq_elt(value));
Ok(Some(value))
try!(serializer.visit_seq_elt(value));
Ok(Some(()))
}
None => Ok(None),
}
@@ -119,7 +159,7 @@ impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
///////////////////////////////////////////////////////////////////////////////
impl<'a, T> Serialize for &'a [T]
impl<T> Serialize for [T]
where T: Serialize,
{
#[inline]
@@ -177,12 +217,16 @@ array_impls!(30);
array_impls!(31);
array_impls!(32);
impl<T> Serialize for Vec<T> where T: Serialize {
///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for BinaryHeap<T>
where T: Serialize + Ord
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(&self[..]).serialize(serializer)
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
@@ -197,6 +241,18 @@ impl<T> Serialize for BTreeSet<T>
}
}
#[cfg(feature = "nightly")]
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.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
impl<T> Serialize for HashSet<T>
where T: Serialize + Eq + Hash,
{
@@ -208,6 +264,49 @@ impl<T> Serialize for HashSet<T>
}
}
impl<T> Serialize for LinkedList<T>
where T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
#[cfg(feature = "nightly")]
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>,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
let len = iter::Step::steps_between(&self.start, &self.end, &A::one());
serializer.visit_seq(SeqIteratorVisitor::new(self.clone(), len))
}
}
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)
}
}
impl<T> Serialize for VecDeque<T> where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for () {
@@ -257,7 +356,7 @@ macro_rules! tuple_impls {
$(
$state => {
self.state += 1;
Ok(Some(try!(serializer.visit_seq_elt(&e!(self.tuple.$idx)))))
Ok(Some(try!(serializer.visit_tuple_elt(&e!(self.tuple.$idx)))))
}
)+
_ => {
@@ -276,7 +375,7 @@ macro_rules! tuple_impls {
{
#[inline]
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
serializer.visit_seq($TupleVisitor::new(self))
serializer.visit_tuple($TupleVisitor::new(self))
}
}
)+
@@ -457,20 +556,6 @@ impl<K, V> Serialize for HashMap<K, V>
}
}
// FIXME: `VecMap` is unstable.
/*
impl<V> Serialize for VecMap<V>
where V: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
*/
///////////////////////////////////////////////////////////////////////////////
impl<'a, T: ?Sized> Serialize for &'a T where T: Serialize {
@@ -518,6 +603,30 @@ impl<T> Serialize for Arc<T> where T: Serialize, {
}
}
impl<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned, {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(**self).serialize(serializer)
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
match *self {
Result::Ok(ref value) => {
serializer.visit_newtype_variant("Result", 0, "Ok", value)
}
Result::Err(ref value) => {
serializer.visit_newtype_variant("Result", 1, "Err", value)
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for path::Path {
@@ -535,3 +644,10 @@ impl Serialize for path::PathBuf {
self.to_str().unwrap().serialize(serializer)
}
}
#[cfg(feature = "nightly")]
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)
}
}
+121 -42
View File
@@ -113,17 +113,48 @@ pub trait Serializer {
fn visit_unit(&mut self) -> Result<(), Self::Error>;
#[inline]
fn visit_named_unit(&mut self, _name: &str) -> Result<(), Self::Error> {
fn visit_unit_struct(&mut self, _name: &'static str) -> Result<(), Self::Error> {
self.visit_unit()
}
#[inline]
fn visit_enum_unit(&mut self,
_name: &str,
_variant: &str) -> Result<(), Self::Error> {
fn visit_unit_variant(&mut self,
_name: &'static str,
_variant_index: usize,
_variant: &'static str) -> Result<(), Self::Error> {
self.visit_unit()
}
/// The `visit_newtype_struct` 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 visit_newtype_struct<T>(&mut self,
name: &'static str,
value: T) -> Result<(), Self::Error>
where T: Serialize,
{
self.visit_tuple_struct(name, Some(value))
}
/// The `visit_newtype_variant` 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 visit_newtype_variant<T>(&mut self,
name: &'static str,
variant_index: usize,
variant: &'static str,
value: T) -> Result<(), Self::Error>
where T: Serialize,
{
self.visit_tuple_variant(
name,
variant_index,
variant,
Some(value))
}
fn visit_none(&mut self) -> Result<(), Self::Error>;
fn visit_some<V>(&mut self, value: V) -> Result<(), Self::Error>
@@ -132,54 +163,102 @@ pub trait Serializer {
fn visit_seq<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor;
#[inline]
fn visit_named_seq<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.visit_seq(visitor)
}
#[inline]
fn visit_enum_seq<V>(&mut self,
_name: &'static str,
_variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.visit_seq(visitor)
}
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize;
#[inline]
fn visit_tuple<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.visit_seq(visitor)
}
#[inline]
fn visit_tuple_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.visit_seq_elt(value)
}
#[inline]
fn visit_tuple_struct<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.visit_tuple(visitor)
}
#[inline]
fn visit_tuple_struct_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.visit_tuple_elt(value)
}
#[inline]
fn visit_tuple_variant<V>(&mut self,
_name: &'static str,
_variant_index: usize,
variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.visit_tuple_struct(variant, visitor)
}
#[inline]
fn visit_tuple_variant_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.visit_tuple_struct_elt(value)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: MapVisitor;
#[inline]
fn visit_named_map<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.visit_map(visitor)
}
#[inline]
fn visit_enum_map<V>(&mut self,
_name: &'static str,
_variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.visit_map(visitor)
}
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
where K: Serialize,
V: Serialize;
#[inline]
fn visit_struct<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.visit_map(visitor)
}
#[inline]
fn visit_struct_elt<V>(&mut self,
key: &'static str,
value: V) -> Result<(), Self::Error>
where V: Serialize,
{
self.visit_map_elt(key, value)
}
#[inline]
fn visit_struct_variant<V>(&mut self,
_name: &'static str,
_variant_index: usize,
variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.visit_struct(variant, visitor)
}
#[inline]
fn visit_struct_variant_elt<V>(&mut self,
key: &'static str,
value: V) -> Result<(), Self::Error>
where V: Serialize,
{
self.visit_struct_elt(key, value)
}
/// Specify a format string for the serializer.
///
/// The serializer format is used to determine which format
+5 -3
View File
@@ -1,16 +1,18 @@
[package]
name = "serde_codegen"
version = "0.4.1"
version = "0.5.1"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
repository = "https://github.com/erickt/rust-serde"
repository = "https://github.com/serde-rs/serde"
documentation = "https://serde-rs.github.io/serde/serde_codegen/serde_codegen/index.html"
build = "build.rs"
keywords = ["serde", "serialization"]
[features]
default = ["with-syntex"]
nightly = ["quasi_macros"]
with-syntex = ["quasi/with-syntex", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"]
with-syntex = ["quasi/with-syntex", "quasi_codegen", "quasi_codegen/with-syntex", "syntex", "syntex_syntax"]
[build-dependencies]
quasi_codegen = { verision = "*", optional = true }
+16 -4
View File
@@ -16,15 +16,20 @@ pub enum FieldNames {
/// Represents field attribute information
pub struct FieldAttrs {
skip_serializing_field: bool,
names: FieldNames,
use_default: bool,
}
impl FieldAttrs {
/// Create a FieldAttr with a single default field name
pub fn new(default_value: bool, name: P<ast::Expr>) -> FieldAttrs {
pub fn new(
skip_serializing_field: bool,
default_value: bool,
name: P<ast::Expr>,
) -> FieldAttrs {
FieldAttrs {
skip_serializing_field: skip_serializing_field,
names: FieldNames::Global(name),
use_default: default_value,
}
@@ -32,12 +37,14 @@ impl FieldAttrs {
/// Create a FieldAttr with format specific field names
pub fn new_with_formats(
skip_serializing_field: bool,
default_value: bool,
default_name: P<ast::Expr>,
formats: HashMap<P<ast::Expr>, P<ast::Expr>>,
) -> FieldAttrs {
) -> FieldAttrs {
FieldAttrs {
names: FieldNames::Format {
skip_serializing_field: skip_serializing_field,
names: FieldNames::Format {
formats: formats,
default: default_name,
},
@@ -105,4 +112,9 @@ impl FieldAttrs {
pub fn use_default(&self) -> bool {
self.use_default
}
/// Predicate for ignoring a field when serializing a value
pub fn skip_serializing_field(&self) -> bool {
self.skip_serializing_field
}
}
+278 -54
View File
@@ -129,15 +129,24 @@ fn deserialize_item_struct(
}
}
match (named_fields.is_empty(), unnamed_fields == 0) {
(true, true) => {
match (named_fields.is_empty(), unnamed_fields) {
(true, 0) => {
deserialize_unit_struct(
cx,
&builder,
item.ident,
)
}
(true, false) => {
(true, 1) => {
deserialize_newtype_struct(
cx,
&builder,
item.ident,
impl_generics,
ty,
)
}
(true, _) => {
deserialize_tuple_struct(
cx,
&builder,
@@ -147,7 +156,7 @@ fn deserialize_item_struct(
unnamed_fields,
)
}
(false, true) => {
(false, 0) => {
deserialize_struct(
cx,
&builder,
@@ -157,7 +166,7 @@ fn deserialize_item_struct(
struct_def,
)
}
(false, false) => {
(false, _) => {
cx.bug("struct has named and unnamed fields")
}
}
@@ -190,11 +199,25 @@ fn deserialize_visitor(
(
builder.item().tuple_struct("__Visitor")
.generics().with(trait_generics.clone()).build()
.with_tys(
trait_generics.ty_params.iter().map(|ty_param| {
builder.ty().phantom_data().id(ty_param.ident)
})
)
.with_tys({
let lifetimes = trait_generics.lifetimes.iter()
.map(|lifetime_def| {
builder.ty()
.phantom_data()
.ref_().lifetime(lifetime_def.lifetime.name)
.ty()
.unit()
});
let ty_params = trait_generics.ty_params.iter()
.map(|ty_param| {
builder.ty()
.phantom_data()
.id(ty_param.ident)
});
lifetimes.chain(ty_params)
})
.build(),
builder.ty().path()
.segment("__Visitor").with_generics(trait_generics.clone()).build()
@@ -204,11 +227,11 @@ fn deserialize_visitor(
.with_tys(forward_tys)
.with_tys(placeholders)
.build().build()
.with_args(
trait_generics.ty_params.iter().map(|_| {
builder.expr().phantom_data()
})
)
.with_args({
let len = trait_generics.lifetimes.len() + trait_generics.ty_params.len();
(0 .. len).map(|_| builder.expr().phantom_data())
})
.build(),
trait_generics,
)
@@ -260,7 +283,59 @@ fn deserialize_unit_struct(
}
}
deserializer.visit_named_unit($type_name, __Visitor)
deserializer.visit_unit_struct($type_name, __Visitor)
})
}
fn deserialize_newtype_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause;
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) =
deserialize_visitor(
builder,
impl_generics,
vec![deserializer_ty_param(builder)],
vec![deserializer_ty_arg(builder)],
);
let visit_seq_expr = deserialize_seq(
cx,
builder,
builder.path().id(type_ident).build(),
1,
);
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, {
$visitor_item
impl $visitor_generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
#[inline]
fn visit_newtype_struct<D>(&mut self, deserializer: &mut D) -> ::std::result::Result<Self::Value, D::Error>
where D: ::serde::de::Deserializer,
{
let value = try!(::serde::de::Deserialize::deserialize(deserializer));
Ok($type_ident(value))
}
#[inline]
fn visit_seq<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::SeqVisitor,
{
$visit_seq_expr
}
}
deserializer.visit_newtype_struct($type_name, $visitor_expr)
})
}
@@ -297,6 +372,7 @@ fn deserialize_tuple_struct(
impl $visitor_generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
#[inline]
fn visit_seq<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::SeqVisitor,
{
@@ -304,7 +380,7 @@ fn deserialize_tuple_struct(
}
}
deserializer.visit_named_seq($type_name, $visitor_expr)
deserializer.visit_tuple_struct($type_name, $fields, $visitor_expr)
})
}
@@ -321,7 +397,7 @@ fn deserialize_seq(
let $name = match try!(visitor.visit()) {
Some(value) => { value },
None => {
return Err(::serde::de::Error::end_of_stream_error());
return Err(::serde::de::Error::end_of_stream());
}
};
).unwrap()
@@ -342,6 +418,51 @@ fn deserialize_seq(
})
}
fn deserialize_struct_as_seq(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
struct_path: ast::Path,
struct_def: &StructDef,
) -> P<ast::Expr> {
let let_values: Vec<P<ast::Stmt>> = (0 .. struct_def.fields.len())
.map(|i| {
let name = builder.id(format!("__field{}", i));
quote_stmt!(cx,
let $name = match try!(visitor.visit()) {
Some(value) => { value },
None => {
return Err(::serde::de::Error::end_of_stream());
}
};
).unwrap()
})
.collect();
let result = builder.expr().struct_path(struct_path)
.with_id_exprs(
struct_def.fields.iter()
.enumerate()
.map(|(i, field)| {
(
match field.node.kind {
ast::NamedField(name, _) => name.clone(),
ast::UnnamedField(_) => panic!("struct contains unnamed fields"),
},
builder.expr().id(format!("__field{}", i)),
)
})
)
.build();
quote_expr!(cx, {
$let_values
try!(visitor.end());
Ok($result)
})
}
fn deserialize_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
@@ -352,19 +473,27 @@ fn deserialize_struct(
) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause;
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) =
deserialize_visitor(
builder,
&impl_generics,
vec![deserializer_ty_param(builder)],
vec![deserializer_ty_arg(builder)],
);
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) = deserialize_visitor(
builder,
&impl_generics,
vec![deserializer_ty_param(builder)],
vec![deserializer_ty_arg(builder)],
);
let (field_visitor, visit_map_expr) = deserialize_struct_visitor(
let type_path = builder.path().id(type_ident).build();
let visit_seq_expr = deserialize_struct_as_seq(
cx,
builder,
type_path.clone(),
struct_def
);
let (field_visitor, fields_stmt, visit_map_expr) = deserialize_struct_visitor(
cx,
builder,
struct_def,
builder.path().id(type_ident).build(),
type_path.clone()
);
let type_name = builder.expr().str(type_ident);
@@ -377,6 +506,13 @@ fn deserialize_struct(
impl $visitor_generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
#[inline]
fn visit_seq<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::SeqVisitor,
{
$visit_seq_expr
}
#[inline]
fn visit_map<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::MapVisitor,
@@ -385,7 +521,9 @@ fn deserialize_struct(
}
}
deserializer.visit_named_map($type_name, $visitor_expr)
$fields_stmt
deserializer.visit_struct($type_name, FIELDS, $visitor_expr)
})
}
@@ -407,11 +545,25 @@ fn deserialize_item_enum(
enum_def.variants.iter()
.map(|variant|
attr::FieldAttrs::new(
false,
true,
builder.expr().str(variant.node.name)))
.collect()
);
let variants_expr = builder.expr().addr_of().slice()
.with_exprs(
enum_def.variants.iter()
.map(|variant| {
builder.expr().str(variant.node.name)
})
)
.build();
let variants_stmt = quote_stmt!(cx,
const VARIANTS: &'static [&'static str] = $variants_expr;
).unwrap();
// Match arms to extract a variant from a string
let variant_arms: Vec<_> = enum_def.variants.iter()
.enumerate()
@@ -458,7 +610,9 @@ fn deserialize_item_enum(
}
}
deserializer.visit_enum($type_name, $visitor_expr)
$variants_stmt
deserializer.visit_enum($type_name, VARIANTS, $visitor_expr)
})
}
@@ -479,6 +633,12 @@ fn deserialize_variant(
Ok($type_ident::$variant_ident)
})
}
ast::TupleVariantKind(ref args) if args.len() == 1 => {
quote_expr!(cx, {
let val = try!(visitor.visit_newtype());
Ok($type_ident::$variant_ident(val))
})
}
ast::TupleVariantKind(ref args) => {
deserialize_tuple_variant(
cx,
@@ -543,7 +703,7 @@ fn deserialize_tuple_variant(
}
}
visitor.visit_seq($visitor_expr)
visitor.visit_tuple($fields, $visitor_expr)
})
}
@@ -558,11 +718,23 @@ fn deserialize_struct_variant(
) -> P<ast::Expr> {
let where_clause = &generics.where_clause;
let (field_visitor, field_expr) = deserialize_struct_visitor(
let type_path = builder.path()
.id(type_ident)
.id(variant_ident)
.build();
let visit_seq_expr = deserialize_struct_as_seq(
cx,
builder,
type_path.clone(),
struct_def
);
let (field_visitor, fields_stmt, field_expr) = deserialize_struct_visitor(
cx,
builder,
struct_def,
builder.path().id(type_ident).id(variant_ident).build(),
type_path
);
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) =
@@ -581,6 +753,14 @@ fn deserialize_struct_variant(
impl $visitor_generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
#[inline]
fn visit_seq<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::SeqVisitor,
{
$visit_seq_expr
}
#[inline]
fn visit_map<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::MapVisitor,
{
@@ -588,7 +768,9 @@ fn deserialize_struct_variant(
}
}
visitor.visit_map($visitor_expr)
$fields_stmt
visitor.visit_struct(FIELDS, $visitor_expr)
})
}
@@ -612,6 +794,20 @@ fn deserialize_field_visitor(
)
.build();
let index_field_arms: Vec<_> = field_idents.iter()
.enumerate()
.map(|(field_index, field_ident)| {
quote_arm!(cx, $field_index => { Ok(__Field::$field_ident) })
})
.collect();
let index_body = quote_expr!(cx,
match value {
$index_field_arms
_ => { Err(::serde::de::Error::syntax("expected a field")) }
}
);
// A set of all the formats that have specialized field attributes
let formats = field_attrs.iter()
.fold(HashSet::new(), |mut set, field_expr| {
@@ -628,15 +824,15 @@ fn deserialize_field_visitor(
})
.collect();
let body = if formats.is_empty() {
let str_body = if formats.is_empty() {
// No formats specific attributes, so no match on format required
quote_expr!(cx,
match value {
$default_field_arms
_ => { Err(::serde::de::Error::unknown_field_error(value)) }
})
match value {
$default_field_arms
_ => { Err(::serde::de::Error::unknown_field(value)) }
})
} else {
let field_arms : Vec<_> = formats.iter()
let field_arms: Vec<_> = formats.iter()
.map(|fmt| {
field_idents.iter()
.zip(field_attrs.iter())
@@ -648,27 +844,28 @@ fn deserialize_field_visitor(
})
.collect();
let fmt_matches : Vec<_> = formats.iter()
let fmt_matches: Vec<_> = formats.iter()
.zip(field_arms.iter())
.map(|(ref fmt, ref arms)| {
quote_arm!(cx, $fmt => {
match value {
$arms
_ => {
Err(::serde::de::Error::unknown_field_error(value))
Err(::serde::de::Error::unknown_field(value))
}
}})
})
.collect();
quote_expr!(cx,
match __D::format() {
$fmt_matches
_ => match value {
$default_field_arms
_ => { Err(::serde::de::Error::unknown_field_error(value)) }
}
})
match __D::format() {
$fmt_matches
_ => match value {
$default_field_arms
_ => { Err(::serde::de::Error::unknown_field(value)) }
}
}
)
};
let impl_item = quote_item!(cx,
@@ -688,10 +885,16 @@ fn deserialize_field_visitor(
{
type Value = __Field;
fn visit_usize<E>(&mut self, value: usize) -> ::std::result::Result<__Field, E>
where E: ::serde::de::Error,
{
$index_body
}
fn visit_str<E>(&mut self, value: &str) -> ::std::result::Result<__Field, E>
where E: ::serde::de::Error,
{
$body
$str_body
}
fn visit_bytes<E>(&mut self, value: &[u8]) -> ::std::result::Result<__Field, E>
@@ -700,13 +903,18 @@ fn deserialize_field_visitor(
// TODO: would be better to generate a byte string literal match
match ::std::str::from_utf8(value) {
Ok(s) => self.visit_str(s),
_ => Err(::serde::de::Error::syntax_error()),
_ => {
Err(
::serde::de::Error::syntax(
"could not convert a byte string to a String"
)
)
}
}
}
}
deserializer.visit(
__FieldVisitor::<D>{ phantom: PhantomData })
deserializer.visit(__FieldVisitor::<D>{ phantom: PhantomData })
}
}
).unwrap();
@@ -719,7 +927,7 @@ fn deserialize_struct_visitor(
builder: &aster::AstBuilder,
struct_def: &ast::StructDef,
struct_path: ast::Path,
) -> (Vec<P<ast::Item>>, P<ast::Expr>) {
) -> (Vec<P<ast::Item>>, P<ast::Stmt>, P<ast::Expr>) {
let field_visitor = deserialize_field_visitor(
cx,
builder,
@@ -733,7 +941,23 @@ fn deserialize_struct_visitor(
struct_def,
);
(field_visitor, visit_map_expr)
let fields_expr = builder.expr().addr_of().slice()
.with_exprs(
struct_def.fields.iter()
.map(|field| {
match field.node.kind {
ast::NamedField(name, _) => builder.expr().str(name),
ast::UnnamedField(_) => panic!("struct contains unnamed fields"),
}
})
)
.build();
let fields_stmt = quote_stmt!(cx,
const FIELDS: &'static [&'static str] = $fields_expr;
).unwrap();
(field_visitor, fields_stmt, visit_map_expr)
}
fn deserialize_map(
+24 -10
View File
@@ -58,10 +58,18 @@ fn default_value(mi: &ast::MetaItem) -> bool {
}
}
fn skip_serializing_field(mi: &ast::MetaItem) -> bool {
if let ast::MetaItem_::MetaWord(ref n) = mi.node {
n == &"skip_serializing"
} else {
false
}
}
fn field_attrs<'a>(
builder: &aster::AstBuilder,
field: &'a ast::StructField,
) -> (Rename<'a>, bool) {
) -> (Rename<'a>, bool, bool) {
field.node.attrs.iter()
.find(|sa| {
if let ast::MetaList(ref n, _) = sa.node.value.node {
@@ -73,15 +81,18 @@ fn field_attrs<'a>(
.and_then(|sa| {
if let ast::MetaList(_, ref vals) = sa.node.value.node {
attr::mark_used(&sa);
Some((vals.iter()
.fold(None, |v, mi| v.or(rename(builder, mi)))
.unwrap_or(Rename::None),
vals.iter().any(|mi| default_value(mi))))
Some((
vals.iter()
.fold(None, |v, mi| v.or(rename(builder, mi)))
.unwrap_or(Rename::None),
vals.iter().any(|mi| default_value(mi)),
vals.iter().any(|mi| skip_serializing_field(mi)),
))
} else {
Some((Rename::None, false))
Some((Rename::None, false, false))
}
})
.unwrap_or((Rename::None, false))
.unwrap_or((Rename::None, false, false))
}
pub fn struct_field_attrs(
@@ -92,23 +103,26 @@ pub fn struct_field_attrs(
struct_def.fields.iter()
.map(|field| {
match field_attrs(builder, field) {
(Rename::Global(rename), default_value) =>
(Rename::Global(rename), default_value, skip_serializing_field) =>
FieldAttrs::new(
skip_serializing_field,
default_value,
builder.expr().build_lit(P(rename.clone()))),
(Rename::Format(renames), default_value) => {
(Rename::Format(renames), default_value, skip_serializing_field) => {
let mut res = HashMap::new();
res.extend(
renames.into_iter()
.map(|(k,v)|
(k, builder.expr().build_lit(P(v.clone())))));
FieldAttrs::new_with_formats(
skip_serializing_field,
default_value,
default_field_name(cx, builder, field.node.kind),
res)
},
(Rename::None, default_value) => {
(Rename::None, default_value, skip_serializing_field) => {
FieldAttrs::new(
skip_serializing_field,
default_value,
default_field_name(cx, builder, field.node.kind))
}
+79 -49
View File
@@ -55,10 +55,7 @@ pub fn expand_derive_serialize(
&builder,
&item,
&impl_generics,
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(ty.clone()),
ty.clone(),
);
let where_clause = &impl_generics.where_clause;
@@ -127,15 +124,22 @@ fn serialize_item_struct(
}
}
match (named_fields.is_empty(), unnamed_fields == 0) {
(true, true) => {
match (named_fields.is_empty(), unnamed_fields) {
(true, 0) => {
serialize_unit_struct(
cx,
&builder,
item.ident,
)
}
(true, false) => {
(true, 1) => {
serialize_newtype_struct(
cx,
&builder,
item.ident,
)
}
(true, _) => {
serialize_tuple_struct(
cx,
&builder,
@@ -145,7 +149,7 @@ fn serialize_item_struct(
unnamed_fields,
)
}
(false, true) => {
(false, 0) => {
serialize_struct(
cx,
&builder,
@@ -156,7 +160,7 @@ fn serialize_item_struct(
named_fields,
)
}
(false, false) => {
(false, _) => {
cx.bug("struct has named and unnamed fields")
}
}
@@ -169,7 +173,17 @@ fn serialize_unit_struct(
) -> P<ast::Expr> {
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, serializer.visit_named_unit($type_name))
quote_expr!(cx, serializer.visit_unit_struct($type_name))
}
fn serialize_newtype_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident
) -> P<ast::Expr> {
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, serializer.visit_newtype_struct($type_name, &self.0))
}
fn serialize_tuple_struct(
@@ -184,7 +198,10 @@ fn serialize_tuple_struct(
cx,
builder,
ty.clone(),
ty,
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(ty.clone()),
fields,
impl_generics,
);
@@ -194,10 +211,10 @@ fn serialize_tuple_struct(
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_named_seq($type_name, Visitor {
serializer.visit_tuple_struct($type_name, Visitor {
value: self,
state: 0,
_structure_ty: ::std::marker::PhantomData,
_structure_ty: ::std::marker::PhantomData::<&$ty>,
})
})
}
@@ -215,7 +232,10 @@ fn serialize_struct(
cx,
builder,
ty.clone(),
ty,
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(ty.clone()),
struct_def,
impl_generics,
fields.iter().map(|field| quote_expr!(cx, &self.value.$field)),
@@ -226,10 +246,10 @@ fn serialize_struct(
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_named_map($type_name, Visitor {
serializer.visit_struct($type_name, Visitor {
value: self,
state: 0,
_structure_ty: ::std::marker::PhantomData,
_structure_ty: ::std::marker::PhantomData::<&$ty>,
})
})
}
@@ -243,7 +263,8 @@ fn serialize_item_enum(
enum_def: &ast::EnumDef,
) -> P<ast::Expr> {
let arms: Vec<ast::Arm> = enum_def.variants.iter()
.map(|variant| {
.enumerate()
.map(|(variant_index, variant)| {
serialize_variant(
cx,
builder,
@@ -251,6 +272,7 @@ fn serialize_item_enum(
impl_generics,
ty.clone(),
variant,
variant_index,
)
})
.collect();
@@ -269,6 +291,7 @@ fn serialize_variant(
generics: &ast::Generics,
ty: P<ast::Ty>,
variant: &ast::Variant,
variant_index: usize,
) -> ast::Arm {
let type_name = builder.expr().str(type_ident);
let variant_ident = variant.node.name;
@@ -282,14 +305,34 @@ fn serialize_variant(
quote_arm!(cx,
$pat => {
::serde::ser::Serializer::visit_enum_unit(
::serde::ser::Serializer::visit_unit_variant(
serializer,
$type_name,
$variant_index,
$variant_name,
)
}
)
}
},
ast::TupleVariantKind(ref args) if args.len() == 1 => {
let field = builder.id("__simple_value");
let field = builder.pat().ref_id(field);
let pat = builder.pat().enum_()
.id(type_ident).id(variant_ident).build()
.with_pats(Some(field).into_iter())
.build();
quote_arm!(cx,
$pat => {
::serde::ser::Serializer::visit_newtype_variant(
serializer,
$type_name,
$variant_index,
$variant_name,
__simple_value,
)
}
)
},
ast::TupleVariantKind(ref args) => {
let fields: Vec<ast::Ident> = (0 .. args.len())
.map(|i| builder.id(format!("__field{}", i)))
@@ -304,6 +347,7 @@ fn serialize_variant(
cx,
builder,
type_name,
variant_index,
variant_name,
generics,
ty,
@@ -340,6 +384,7 @@ fn serialize_variant(
cx,
builder,
type_name,
variant_index,
variant_name,
generics,
ty,
@@ -356,6 +401,7 @@ fn serialize_tuple_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_name: P<ast::Expr>,
variant_index: usize,
variant_name: P<ast::Expr>,
generics: &ast::Generics,
structure_ty: P<ast::Ty>,
@@ -376,7 +422,7 @@ fn serialize_tuple_variant(
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
cx,
builder,
structure_ty,
structure_ty.clone(),
variant_ty,
args.len(),
generics,
@@ -385,9 +431,7 @@ fn serialize_tuple_variant(
let value_expr = builder.expr().tuple()
.with_exprs(
fields.iter().map(|field| {
builder.expr()
.addr_of()
.id(field)
builder.expr().id(field)
})
)
.build();
@@ -395,10 +439,10 @@ fn serialize_tuple_variant(
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_enum_seq($type_name, $variant_name, Visitor {
serializer.visit_tuple_variant($type_name, $variant_index, $variant_name, Visitor {
value: $value_expr,
state: 0,
_structure_ty: ::std::marker::PhantomData,
_structure_ty: ::std::marker::PhantomData::<&$structure_ty>,
})
})
}
@@ -407,6 +451,7 @@ fn serialize_struct_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_name: P<ast::Expr>,
variant_index: usize,
variant_name: P<ast::Expr>,
generics: &ast::Generics,
structure_ty: P<ast::Ty>,
@@ -427,9 +472,7 @@ fn serialize_struct_variant(
let value_expr = builder.expr().tuple()
.with_exprs(
fields.iter().map(|field| {
builder.expr()
.addr_of()
.id(field)
builder.expr().id(field)
})
)
.build();
@@ -437,7 +480,7 @@ fn serialize_struct_variant(
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
cx,
builder,
structure_ty,
structure_ty.clone(),
value_ty,
struct_def,
generics,
@@ -451,10 +494,10 @@ fn serialize_struct_variant(
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_enum_map($type_name, $variant_name, Visitor {
serializer.visit_struct_variant($type_name, $variant_index, $variant_name, Visitor {
value: $value_expr,
state: 0,
_structure_ty: ::std::marker::PhantomData,
_structure_ty: ::std::marker::PhantomData::<&$structure_ty>,
})
})
}
@@ -476,7 +519,7 @@ fn serialize_tuple_struct_visitor(
quote_arm!(cx,
$i => {
self.state += 1;
let v = try!(serializer.visit_seq_elt(&$expr));
let v = try!(serializer.visit_tuple_struct_elt(&$expr));
Ok(Some(v))
}
)
@@ -494,19 +537,12 @@ fn serialize_tuple_struct_visitor(
.strip_bounds()
.build();
// Variants don't necessarily reference all generic lifetimes and type parameters,
// so to avoid a compilation failure, we'll just add a phantom type to capture these
// unused values.
let structure_ty = builder.ty()
.phantom_data()
.build(structure_ty);
(
quote_item!(cx,
struct Visitor $visitor_impl_generics $where_clause {
state: usize,
value: $variant_ty,
_structure_ty: $structure_ty,
_structure_ty: ::std::marker::PhantomData<&'__a $structure_ty>,
}
).unwrap(),
@@ -550,6 +586,7 @@ fn serialize_struct_visitor<I>(
let arms: Vec<ast::Arm> = field_attrs.into_iter()
.zip(value_exprs)
.filter(|&(ref field, _)| !field.skip_serializing_field())
.enumerate()
.map(|(i, (field, value_expr))| {
let key_expr = field.serializer_key_expr(cx);
@@ -559,7 +596,7 @@ fn serialize_struct_visitor<I>(
Ok(
Some(
try!(
serializer.visit_map_elt(
serializer.visit_struct_elt(
$key_expr,
$value_expr,
)
@@ -582,19 +619,12 @@ fn serialize_struct_visitor<I>(
.strip_bounds()
.build();
// Variants don't necessarily reference all generic lifetimes and type parameters,
// so to avoid a compilation failure, we'll just add a phantom type to capture these
// unused values.
let structure_ty = builder.ty()
.phantom_data()
.build(structure_ty);
(
quote_item!(cx,
struct Visitor $visitor_impl_generics $where_clause {
state: usize,
value: $variant_ty,
_structure_ty: $structure_ty,
_structure_ty: ::std::marker::PhantomData<&'__a $structure_ty>,
}
).unwrap(),
+14
View File
@@ -0,0 +1,14 @@
[package]
name = "serde_json"
version = "0.5.1"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A JSON serialization file format"
repository = "https://github.com/serde-rs/serde"
documentation = "https://serde-rs.github.io/serde/serde_json/serde_json/index.html"
readme = "../README.md"
keywords = ["json", "serde", "serialization"]
[dependencies]
num = "*"
serde = { version = "*", path = "../serde" }
@@ -10,8 +10,9 @@
use std::collections::BTreeMap;
use ser::{self, Serialize};
use json::value::{self, Value};
use serde::ser::{self, Serialize};
use value::{self, Value};
pub struct ArrayBuilder {
array: Vec<Value>,
+372 -246
View File
@@ -3,10 +3,10 @@ use std::i32;
use std::io;
use std::str;
use de;
use iter::LineColIterator;
use serde::de;
use serde::iter::LineColIterator;
use super::error::{Error, ErrorCode};
use super::error::{Error, ErrorCode, Result};
pub struct Deserializer<Iter: Iterator<Item=io::Result<u8>>> {
rdr: LineColIterator<Iter>,
@@ -28,98 +28,128 @@ impl<Iter> Deserializer<Iter>
{
/// Creates the JSON parser from an `std::iter::Iterator`.
#[inline]
pub fn new(rdr: Iter) -> Result<Deserializer<Iter>, Error> {
let mut deserializer = Deserializer {
pub fn new(rdr: Iter) -> Deserializer<Iter> {
Deserializer {
rdr: LineColIterator::new(rdr),
ch: None,
str_buf: Vec::with_capacity(128),
};
try!(deserializer.bump());
Ok(deserializer)
}
}
#[inline]
pub fn end(&mut self) -> Result<(), Error> {
pub fn end(&mut self) -> Result<()> {
try!(self.parse_whitespace());
if self.eof() {
if try!(self.eof()) {
Ok(())
} else {
Err(self.error(ErrorCode::TrailingCharacters))
}
}
fn eof(&self) -> bool { self.ch.is_none() }
fn ch_or_null(&self) -> u8 { self.ch.unwrap_or(b'\x00') }
fn bump(&mut self) -> Result<(), Error> {
self.ch = match self.rdr.next() {
Some(Err(err)) => { return Err(Error::IoError(err)); }
Some(Ok(ch)) => Some(ch),
None => None,
};
Ok(())
fn eof(&mut self) -> Result<bool> {
Ok(try!(self.peek()).is_none())
}
fn next_char(&mut self) -> Result<Option<u8>, Error> {
try!(self.bump());
Ok(self.ch)
fn peek(&mut self) -> Result<Option<u8>> {
match self.ch {
Some(ch) => Ok(Some(ch)),
None => {
match self.rdr.next() {
Some(Err(err)) => Err(Error::IoError(err)),
Some(Ok(ch)) => {
self.ch = Some(ch);
Ok(self.ch)
}
None => Ok(None),
}
}
}
}
fn ch_is(&self, c: u8) -> bool {
self.ch == Some(c)
fn peek_or_null(&mut self) -> Result<u8> {
Ok(try!(self.peek()).unwrap_or(b'\x00'))
}
fn eat_char(&mut self) {
self.ch = None;
}
fn next_char(&mut self) -> Result<Option<u8>> {
match self.ch.take() {
Some(ch) => Ok(Some(ch)),
None => {
match self.rdr.next() {
Some(Err(err)) => Err(Error::IoError(err)),
Some(Ok(ch)) => Ok(Some(ch)),
None => Ok(None),
}
}
}
}
fn next_char_or_null(&mut self) -> Result<u8> {
Ok(try!(self.next_char()).unwrap_or(b'\x00'))
}
fn error(&mut self, reason: ErrorCode) -> Error {
Error::SyntaxError(reason, self.rdr.line(), self.rdr.col())
}
fn parse_whitespace(&mut self) -> Result<(), Error> {
while self.ch_is(b' ') ||
self.ch_is(b'\n') ||
self.ch_is(b'\t') ||
self.ch_is(b'\r') { try!(self.bump()); }
Ok(())
fn parse_whitespace(&mut self) -> Result<()> {
loop {
match try!(self.peek_or_null()) {
b' ' | b'\n' | b'\t' | b'\r' => {
self.eat_char();
}
_ => { return Ok(()); }
}
}
}
fn parse_value<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
fn parse_value<V>(&mut self, mut visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
try!(self.parse_whitespace());
if self.eof() {
if try!(self.eof()) {
return Err(self.error(ErrorCode::EOFWhileParsingValue));
}
let value = match self.ch_or_null() {
let value = match try!(self.peek_or_null()) {
b'n' => {
self.eat_char();
try!(self.parse_ident(b"ull"));
visitor.visit_unit()
}
b't' => {
self.eat_char();
try!(self.parse_ident(b"rue"));
visitor.visit_bool(true)
}
b'f' => {
self.eat_char();
try!(self.parse_ident(b"alse"));
visitor.visit_bool(false)
}
b'0' ... b'9' | b'-' => self.parse_number(visitor),
b'-' => {
self.eat_char();
self.parse_integer(false, visitor)
}
b'0' ... b'9' => {
self.parse_integer(true, visitor)
}
b'"' => {
self.eat_char();
try!(self.parse_string());
let s = str::from_utf8(&self.str_buf).unwrap();
visitor.visit_str(s)
}
b'[' => {
try!(self.bump());
self.eat_char();
visitor.visit_seq(SeqVisitor::new(self))
}
b'{' => {
try!(self.bump());
self.eat_char();
visitor.visit_map(MapVisitor::new(self))
}
_ => {
@@ -134,147 +164,207 @@ impl<Iter> Deserializer<Iter>
}
}
fn parse_ident(&mut self, ident: &[u8]) -> Result<(), Error> {
fn parse_ident(&mut self, ident: &[u8]) -> Result<()> {
for c in ident {
if Some(*c) != try!(self.next_char()) {
return Err(self.error(ErrorCode::ExpectedSomeIdent));
}
}
try!(self.bump());
Ok(())
}
fn parse_number<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
fn parse_integer<V>(&mut self, pos: bool, visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
let mut neg = false;
if self.ch_is(b'-') {
try!(self.bump());
neg = true;
}
let res = try!(self.parse_integer());
if self.ch_is(b'.') || self.ch_is(b'e') || self.ch_is(b'E') {
let mut res = res as f64;
if self.ch_is(b'.') {
res = try!(self.parse_decimal(res));
}
if self.ch_is(b'e') || self.ch_is(b'E') {
res = try!(self.parse_exponent(res));
}
if neg {
visitor.visit_f64(-res)
} else {
visitor.visit_f64(res)
}
} else {
if neg {
let res = -(res as i64);
// Make sure we didn't underflow.
if res > 0 {
Err(self.error(ErrorCode::InvalidNumber))
} else {
visitor.visit_i64(res)
}
} else {
visitor.visit_u64(res)
}
}
}
fn parse_integer(&mut self) -> Result<u64, Error> {
let mut accum: u64 = 0;
match self.ch_or_null() {
match try!(self.next_char_or_null()) {
b'0' => {
try!(self.bump());
// There can be only one leading '0'.
match self.ch_or_null() {
match try!(self.peek_or_null()) {
b'0' ... b'9' => {
return Err(self.error(ErrorCode::InvalidNumber));
Err(self.error(ErrorCode::InvalidNumber))
}
_ => {
self.parse_number(pos, 0, visitor)
}
_ => ()
}
},
b'1' ... b'9' => {
while !self.eof() {
match self.ch_or_null() {
c @ b'0' ... b'9' => {
accum = try_or_invalid!(self, accum.checked_mul(10));
accum = try_or_invalid!(self, accum.checked_add((c as u64) - ('0' as u64)));
c @ b'1' ... b'9' => {
let mut res: u64 = (c as u64) - ('0' as u64);
try!(self.bump());
loop {
match try!(self.peek_or_null()) {
c @ b'0' ... b'9' => {
self.eat_char();
let digit = (c as u64) - ('0' as u64);
// We need to be careful with overflow. If we can, try to keep the
// number as a `u64` until we grow too large. At that point, switch to
// parsing the value as a `f64`.
match res.checked_mul(10).and_then(|val| val.checked_add(digit)) {
Some(res_) => { res = res_; }
None => {
return self.parse_float(
pos,
(res as f64) * 10.0 + (digit as f64),
visitor);
}
}
}
_ => {
return self.parse_number(pos, res, visitor);
}
_ => break,
}
}
}
_ => { return Err(self.error(ErrorCode::InvalidNumber)); }
_ => {
Err(self.error(ErrorCode::InvalidNumber))
}
}
Ok(accum)
}
fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> {
try!(self.bump());
fn parse_float<V>(&mut self,
pos: bool,
mut res: f64,
mut visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
loop {
match try!(self.next_char_or_null()) {
c @ b'0' ... b'9' => {
let digit = (c as u64) - ('0' as u64);
res *= 10.0;
res += digit as f64;
}
_ => {
match try!(self.peek_or_null()) {
b'.' => {
return self.parse_decimal(pos, res, visitor);
}
b'e' | b'E' => {
return self.parse_exponent(pos, res, visitor);
}
_ => {
if !pos {
res = -res;
}
return visitor.visit_f64(res);
}
}
}
}
}
}
fn parse_number<V>(&mut self,
pos: bool,
res: u64,
mut visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
match try!(self.peek_or_null()) {
b'.' => {
self.parse_decimal(pos, res as f64, visitor)
}
b'e' | b'E' => {
self.parse_exponent(pos, res as f64, visitor)
}
_ => {
if pos {
visitor.visit_u64(res)
} else {
// FIXME: `wrapping_neg` will be stable in Rust 1.2
//let res_i64 = (res as i64).wrapping_neg();
let res_i64 = (!res + 1) as i64;
// Convert into a float if we underflow.
if res_i64 > 0 {
visitor.visit_f64(-(res as f64))
} else {
visitor.visit_i64(res_i64)
}
}
}
}
}
fn parse_decimal<V>(&mut self,
pos: bool,
mut res: f64,
mut visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
self.eat_char();
let mut dec = 0.1;
// Make sure a digit follows the decimal place.
match self.ch_or_null() {
b'0' ... b'9' => (),
match try!(self.next_char_or_null()) {
c @ b'0' ... b'9' => {
res += (((c as u64) - (b'0' as u64)) as f64) * dec;
}
_ => { return Err(self.error(ErrorCode::InvalidNumber)); }
}
let mut res = res;
let mut dec = 1.0;
while !self.eof() {
match self.ch_or_null() {
loop {
match try!(self.peek_or_null()) {
c @ b'0' ... b'9' => {
self.eat_char();
dec /= 10.0;
res += (((c as u64) - (b'0' as u64)) as f64) * dec;
try!(self.bump());
}
_ => break,
_ => { break; }
}
}
match try!(self.peek_or_null()) {
b'e' | b'E' => {
self.parse_exponent(pos, res, visitor)
}
_ => {
if pos {
visitor.visit_f64(res)
} else {
visitor.visit_f64(-res)
}
}
}
Ok(res)
}
fn parse_exponent(&mut self, mut res: f64) -> Result<f64, Error> {
try!(self.bump());
fn parse_exponent<V>(&mut self,
pos: bool,
mut res: f64,
mut visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
self.eat_char();
let mut exp: u64 = 0;
let mut neg_exp = false;
if self.ch_is(b'+') {
try!(self.bump());
} else if self.ch_is(b'-') {
try!(self.bump());
neg_exp = true;
}
let pos_exp = match try!(self.peek_or_null()) {
b'+' => { self.eat_char(); true }
b'-' => { self.eat_char(); false }
_ => { true }
};
// Make sure a digit follows the exponent place.
match self.ch_or_null() {
b'0' ... b'9' => (),
let mut exp = match try!(self.next_char_or_null()) {
c @ b'0' ... b'9' => { (c as u64) - (b'0' as u64) }
_ => { return Err(self.error(ErrorCode::InvalidNumber)); }
}
while !self.eof() {
match self.ch_or_null() {
};
loop {
match try!(self.peek_or_null()) {
c @ b'0' ... b'9' => {
self.eat_char();
exp = try_or_invalid!(self, exp.checked_mul(10));
exp = try_or_invalid!(self, exp.checked_add((c as u64) - (b'0' as u64)));
try!(self.bump());
}
_ => break
_ => { break; }
}
}
@@ -284,21 +374,24 @@ impl<Iter> Deserializer<Iter>
return Err(self.error(ErrorCode::InvalidNumber));
};
if neg_exp {
res /= exp;
} else {
if pos_exp {
res *= exp;
} else {
res /= exp;
}
Ok(res)
if pos {
visitor.visit_f64(res)
} else {
visitor.visit_f64(-res)
}
}
fn decode_hex_escape(&mut self) -> Result<u16, Error> {
fn decode_hex_escape(&mut self) -> Result<u16> {
let mut i = 0;
let mut n = 0u16;
while i < 4 && !self.eof() {
try!(self.bump());
n = match self.ch_or_null() {
while i < 4 && !try!(self.eof()) {
n = match try!(self.next_char_or_null()) {
c @ b'0' ... b'9' => n * 16_u16 + ((c as u16) - (b'0' as u16)),
b'a' | b'A' => n * 16_u16 + 10_u16,
b'b' | b'B' => n * 16_u16 + 11_u16,
@@ -320,7 +413,7 @@ impl<Iter> Deserializer<Iter>
Ok(n)
}
fn parse_string(&mut self) -> Result<(), Error> {
fn parse_string(&mut self) -> Result<()> {
self.str_buf.clear();
loop {
@@ -331,7 +424,6 @@ impl<Iter> Deserializer<Iter>
match ch {
b'"' => {
try!(self.bump());
return Ok(());
}
b'\\' => {
@@ -409,16 +501,13 @@ impl<Iter> Deserializer<Iter>
}
}
fn parse_object_colon(&mut self) -> Result<(), Error> {
fn parse_object_colon(&mut self) -> Result<()> {
try!(self.parse_whitespace());
if self.ch_is(b':') {
try!(self.bump());
Ok(())
} else if self.eof() {
Err(self.error(ErrorCode::EOFWhileParsingObject))
} else {
Err(self.error(ErrorCode::ExpectedColon))
match try!(self.next_char()) {
Some(b':') => Ok(()),
Some(_) => Err(self.error(ErrorCode::ExpectedColon)),
None => Err(self.error(ErrorCode::EOFWhileParsingObject)),
}
}
}
@@ -429,54 +518,74 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
type Error = Error;
#[inline]
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Error>
fn visit<V>(&mut self, visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
self.parse_value(visitor)
}
/// Parses a `null` as a None, and any other values as a `Some(...)`.
#[inline]
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
try!(self.parse_whitespace());
if self.eof() {
return Err(self.error(ErrorCode::EOFWhileParsingValue));
}
if self.ch_is(b'n') {
try!(self.parse_ident(b"ull"));
visitor.visit_none()
} else {
visitor.visit_some(self)
match try!(self.peek_or_null()) {
b'n' => {
self.eat_char();
try!(self.parse_ident(b"ull"));
visitor.visit_none()
}
_ => {
visitor.visit_some(self)
}
}
}
/// Parses a newtype struct as the underlying value.
#[inline]
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_newtype_struct<V>(&mut self,
_name: &str,
mut visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
visitor.visit_newtype_struct(self)
}
/// Parses an enum as an object like `{"$KEY":$VALUE}`, where $VALUE is either a straight
/// value, a `[..]`, or a `{..}`.
#[inline]
fn visit_enum<V>(&mut self,
_name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value>
where V: de::EnumVisitor,
{
try!(self.parse_whitespace());
if self.ch_is(b'{') {
try!(self.bump());
try!(self.parse_whitespace());
match try!(self.next_char_or_null()) {
b'{' => {
try!(self.parse_whitespace());
let value = {
try!(visitor.visit(&mut *self))
};
let value = {
try!(visitor.visit(&mut *self))
};
try!(self.parse_whitespace());
try!(self.parse_whitespace());
if self.ch_is(b'}') {
try!(self.bump());
Ok(value)
} else {
match try!(self.next_char_or_null()) {
b'}' => {
Ok(value)
}
_ => {
Err(self.error(ErrorCode::ExpectedSomeValue))
}
}
}
_ => {
Err(self.error(ErrorCode::ExpectedSomeValue))
}
} else {
Err(self.error(ErrorCode::ExpectedSomeValue))
}
}
@@ -505,24 +614,27 @@ impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
{
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
fn visit<T>(&mut self) -> Result<Option<T>>
where T: de::Deserialize,
{
try!(self.de.parse_whitespace());
if self.de.ch_is(b']') {
return Ok(None);
}
if self.first {
self.first = false;
} else {
if self.de.ch_is(b',') {
try!(self.de.bump());
} else if self.de.eof() {
match try!(self.de.peek()) {
Some(b']') => {
return Ok(None);
}
Some(b',') if !self.first => {
self.de.eat_char();
}
Some(_) => {
if self.first {
self.first = false;
} else {
return Err(self.de.error(ErrorCode::ExpectedListCommaOrEnd));
}
}
None => {
return Err(self.de.error(ErrorCode::EOFWhileParsingList));
} else {
return Err(self.de.error(ErrorCode::ExpectedListCommaOrEnd));
}
}
@@ -530,15 +642,17 @@ impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
Ok(Some(value))
}
fn end(&mut self) -> Result<(), Error> {
fn end(&mut self) -> Result<()> {
try!(self.de.parse_whitespace());
if self.de.ch_is(b']') {
self.de.bump()
} else if self.de.eof() {
Err(self.de.error(ErrorCode::EOFWhileParsingList))
} else {
Err(self.de.error(ErrorCode::TrailingCharacters))
match try!(self.de.next_char()) {
Some(b']') => { Ok(()) }
Some(_) => {
Err(self.de.error(ErrorCode::TrailingCharacters))
}
None => {
Err(self.de.error(ErrorCode::EOFWhileParsingList))
}
}
}
}
@@ -562,40 +676,45 @@ impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
{
type Error = Error;
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
fn visit_key<K>(&mut self) -> Result<Option<K>>
where K: de::Deserialize,
{
try!(self.de.parse_whitespace());
if self.de.ch_is(b'}') {
return Ok(None);
}
if self.first {
self.first = false;
} else {
if self.de.ch_is(b',') {
try!(self.de.bump());
match try!(self.de.peek()) {
Some(b'}') => {
return Ok(None);
}
Some(b',') if !self.first => {
self.de.eat_char();
try!(self.de.parse_whitespace());
} else if self.de.eof() {
}
Some(_) => {
if self.first {
self.first = false;
} else {
return Err(self.de.error(ErrorCode::ExpectedObjectCommaOrEnd));
}
}
None => {
return Err(self.de.error(ErrorCode::EOFWhileParsingObject));
} else {
return Err(self.de.error(ErrorCode::ExpectedObjectCommaOrEnd));
}
}
if self.de.eof() {
return Err(self.de.error(ErrorCode::EOFWhileParsingValue));
match try!(self.de.peek()) {
Some(b'"') => {
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
}
Some(_) => {
Err(self.de.error(ErrorCode::KeyMustBeAString))
}
None => {
Err(self.de.error(ErrorCode::EOFWhileParsingValue))
}
}
if !self.de.ch_is(b'"') {
return Err(self.de.error(ErrorCode::KeyMustBeAString));
}
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
}
fn visit_value<V>(&mut self) -> Result<V, Error>
fn visit_value<V>(&mut self) -> Result<V>
where V: de::Deserialize,
{
try!(self.de.parse_object_colon());
@@ -603,20 +722,21 @@ impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
Ok(try!(de::Deserialize::deserialize(self.de)))
}
fn end(&mut self) -> Result<(), Error> {
fn end(&mut self) -> Result<()> {
try!(self.de.parse_whitespace());
if self.de.ch_is(b'}') {
try!(self.de.bump());
Ok(())
} else if self.de.eof() {
Err(self.de.error(ErrorCode::EOFWhileParsingObject))
} else {
Err(self.de.error(ErrorCode::TrailingCharacters))
match try!(self.de.next_char()) {
Some(b'}') => { Ok(()) }
Some(_) => {
Err(self.de.error(ErrorCode::TrailingCharacters))
}
None => {
Err(self.de.error(ErrorCode::EOFWhileParsingObject))
}
}
}
fn missing_field<V>(&mut self, _field: &'static str) -> Result<V, Error>
fn missing_field<V>(&mut self, _field: &'static str) -> Result<V>
where V: de::Deserialize,
{
let mut de = de::value::ValueDeserializer::into_deserializer(());
@@ -629,41 +749,47 @@ impl<Iter> de::VariantVisitor for Deserializer<Iter>
{
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
fn visit_variant<V>(&mut self) -> Result<V>
where V: de::Deserialize
{
de::Deserialize::deserialize(self)
}
fn visit_unit(&mut self) -> Result<(), Error> {
let val = try!(de::Deserialize::deserialize(self));
try!(self.parse_object_colon());
Ok(val)
}
fn visit_unit(&mut self) -> Result<()> {
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
fn visit_newtype<T>(&mut self) -> Result<T>
where T: de::Deserialize,
{
de::Deserialize::deserialize(self)
}
fn visit_tuple<V>(&mut self,
_len: usize,
visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
try!(self.parse_object_colon());
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
fn visit_struct<V>(&mut self,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value>
where V: de::Visitor,
{
try!(self.parse_object_colon());
de::Deserializer::visit(self, visitor)
}
}
/// Decodes a json value from a `std::io::Read`.
pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
pub fn from_iter<I, T>(iter: I) -> Result<T>
where I: Iterator<Item=io::Result<u8>>,
T: de::Deserialize,
{
let mut de = try!(Deserializer::new(iter));
let mut de = Deserializer::new(iter);
let value = try!(de::Deserialize::deserialize(&mut de));
// Make sure the whole stream has been consumed.
@@ -672,7 +798,7 @@ pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
}
/// Decodes a json value from a `std::io::Read`.
pub fn from_reader<R, T>(rdr: R) -> Result<T, Error>
pub fn from_reader<R, T>(rdr: R) -> Result<T>
where R: io::Read,
T: de::Deserialize,
{
@@ -680,14 +806,14 @@ pub fn from_reader<R, T>(rdr: R) -> Result<T, Error>
}
/// Decodes a json value from a `&str`.
pub fn from_slice<T>(v: &[u8]) -> Result<T, Error>
pub fn from_slice<T>(v: &[u8]) -> Result<T>
where T: de::Deserialize
{
from_iter(v.iter().map(|byte| Ok(*byte)))
}
/// Decodes a json value from a `&str`.
pub fn from_str<T>(s: &str) -> Result<T, Error>
pub fn from_str<T>(s: &str) -> Result<T>
where T: de::Deserialize
{
from_slice(s.as_bytes())
@@ -1,8 +1,9 @@
use std::error;
use std::fmt;
use std::io;
use std::result;
use de;
use serde::de;
/// The errors that can arise while parsing a JSON stream.
#[derive(Clone, PartialEq)]
@@ -151,35 +152,38 @@ impl From<de::value::Error> for Error {
fn from(error: de::value::Error) -> Error {
match error {
de::value::Error::SyntaxError => {
de::Error::syntax_error()
Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)
}
de::value::Error::EndOfStreamError => {
de::Error::end_of_stream_error()
de::Error::end_of_stream()
}
de::value::Error::UnknownFieldError(field) => {
Error::SyntaxError(ErrorCode::UnknownField(field), 0, 0)
}
de::value::Error::MissingFieldError(field) => {
de::Error::missing_field_error(field)
de::Error::missing_field(field)
}
}
}
}
impl de::Error for Error {
fn syntax_error() -> Error {
fn syntax(_: &str) -> Error {
Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)
}
fn end_of_stream_error() -> Error {
fn end_of_stream() -> Error {
Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 0, 0)
}
fn unknown_field_error(field: &str) -> Error {
fn unknown_field(field: &str) -> Error {
Error::SyntaxError(ErrorCode::UnknownField(field.to_string()), 0, 0)
}
fn missing_field_error(field: &'static str) -> Error {
fn missing_field(field: &'static str) -> Error {
Error::MissingFieldError(field)
}
}
/// Helper alias for `Result` objects that return a JSON `Error`.
pub type Result<T> = result::Result<T, Error>;
@@ -6,7 +6,7 @@
//! encode structured data in a text format that can be easily read by humans. Its simple syntax
//! and native compatibility with JavaScript have made it a widely used format.
//!
//! Data types that can be encoded are JavaScript types (see the `serde::json:Value` enum for more
//! Data types that can be encoded are JavaScript types (see the `serde_json:Value` enum for more
//! details):
//!
//! * `Boolean`: equivalent to rust's `bool`
@@ -16,7 +16,7 @@
//! * `String`: equivalent to rust's `String`
//! * `Array`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the
//! same array
//! * `Object`: equivalent to rust's `BTreeMap<String, serde::json::Value>`
//! * `Object`: equivalent to rust's `BTreeMap<String, serde_json::Value>`
//! * `Null`
//!
//! An object is a series of string keys mapping to values, in `"key": value` format. Arrays are
@@ -48,8 +48,8 @@
//! `serde::Deserialize` trait. Serde provides provides an annotation to automatically generate
//! the code for these traits: `#[derive(Serialize, Deserialize)]`.
//!
//! The JSON API also provides an enum `serde::json::Value` and a method `to_value` to serialize
//! objects. A `serde::json::Value` value can be serialized as a string or buffer using the
//! The JSON API also provides an enum `serde_json::Value` and a method `to_value` to serialize
//! objects. A `serde_json::Value` value can be serialized as a string or buffer using the
//! functions described above. You can also use the `json::Serializer` object, which implements the
//! `Serializer` trait.
//!
@@ -61,12 +61,12 @@
//! //#![feature(custom_derive, plugin)]
//! //#![plugin(serde_macros)]
//!
//! extern crate serde;
//! extern crate serde_json;
//!
//! use serde::json::{self, Value};
//! use serde_json::Value;
//!
//! fn main() {
//! let data: Value = json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap();
//! let data: Value = serde_json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap();
//! println!("data: {:?}", data);
//! // data: {"bar":"baz","foo":13}
//! println!("object? {}", data.is_object());
@@ -92,8 +92,17 @@
//! }
//! ```
pub use self::de::{Deserializer, from_str};
pub use self::error::{Error, ErrorCode};
extern crate num;
extern crate serde;
pub use self::de::{
Deserializer,
from_iter,
from_reader,
from_slice,
from_str,
};
pub use self::error::{Error, ErrorCode, Result};
pub use self::ser::{
Serializer,
to_writer,
+51 -19
View File
@@ -2,7 +2,7 @@ use std::io;
use std::num::FpCategory;
use std::string::FromUtf8Error;
use ser;
use serde::ser;
/// A structure for implementing serialization to JSON.
pub struct Serializer<W, F=CompactFormatter> {
@@ -158,8 +158,21 @@ impl<W, F> ser::Serializer for Serializer<W, F>
self.writer.write_all(b"null")
}
/// Override `visit_newtype_struct` to serialize newtypes without an object wrapper.
#[inline]
fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> io::Result<()> {
fn visit_newtype_struct<T>(&mut self,
_name: &'static str,
value: T) -> Result<(), Self::Error>
where T: ser::Serialize,
{
value.serialize(self)
}
#[inline]
fn visit_unit_variant(&mut self,
_name: &str,
_variant_index: usize,
variant: &str) -> io::Result<()> {
try!(self.formatter.open(&mut self.writer, b'{'));
try!(self.formatter.comma(&mut self.writer, true));
try!(self.visit_str(variant));
@@ -168,6 +181,22 @@ impl<W, F> ser::Serializer for Serializer<W, F>
self.formatter.close(&mut self.writer, b'}')
}
#[inline]
fn visit_newtype_variant<T>(&mut self,
_name: &str,
_variant_index: usize,
variant: &str,
value: T) -> io::Result<()>
where T: ser::Serialize,
{
try!(self.formatter.open(&mut self.writer, b'{'));
try!(self.formatter.comma(&mut self.writer, true));
try!(self.visit_str(variant));
try!(self.formatter.colon(&mut self.writer));
try!(value.serialize(self));
self.formatter.close(&mut self.writer, b'}')
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> io::Result<()>
where V: ser::SeqVisitor,
@@ -190,7 +219,11 @@ impl<W, F> ser::Serializer for Serializer<W, F>
}
#[inline]
fn visit_enum_seq<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
fn visit_tuple_variant<V>(&mut self,
_name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> io::Result<()>
where V: ser::SeqVisitor,
{
try!(self.formatter.open(&mut self.writer, b'{'));
@@ -206,9 +239,11 @@ impl<W, F> ser::Serializer for Serializer<W, F>
where T: ser::Serialize,
{
try!(self.formatter.comma(&mut self.writer, self.first));
try!(value.serialize(self));
self.first = false;
value.serialize(self)
Ok(())
}
#[inline]
@@ -232,7 +267,11 @@ impl<W, F> ser::Serializer for Serializer<W, F>
}
#[inline]
fn visit_enum_map<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
fn visit_struct_variant<V>(&mut self,
_name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> io::Result<()>
where V: ser::MapVisitor,
{
try!(self.formatter.open(&mut self.writer, b'{'));
@@ -250,11 +289,14 @@ impl<W, F> ser::Serializer for Serializer<W, F>
V: ser::Serialize,
{
try!(self.formatter.comma(&mut self.writer, self.first));
self.first = false;
try!(key.serialize(self));
try!(self.formatter.colon(&mut self.writer));
value.serialize(self)
try!(value.serialize(self));
self.first = false;
Ok(())
}
#[inline]
@@ -423,12 +465,7 @@ fn fmt_f32_or_null<W>(wr: &mut W, value: f32) -> io::Result<()>
match value.classify() {
FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null"),
_ => {
let s = format!("{:?}", value);
try!(wr.write_all(s.as_bytes()));
if !s.contains('.') {
try!(wr.write_all(b".0"))
}
Ok(())
write!(wr, "{:?}", value)
}
}
}
@@ -439,12 +476,7 @@ fn fmt_f64_or_null<W>(wr: &mut W, value: f64) -> io::Result<()>
match value.classify() {
FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null"),
_ => {
let s = format!("{:?}", value);
try!(wr.write_all(s.as_bytes()));
if !s.contains('.') {
try!(wr.write_all(b".0"))
}
Ok(())
write!(wr, "{:?}", value)
}
}
}
@@ -6,9 +6,10 @@ use std::vec;
use num::NumCast;
use de;
use ser;
use super::error::Error;
use serde::de;
use serde::ser;
use error::Error;
#[derive(Clone, PartialEq)]
pub enum Value {
@@ -458,7 +459,10 @@ impl ser::Serializer for Serializer {
}
#[inline]
fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> Result<(), ()> {
fn visit_unit_variant(&mut self,
_name: &str,
_variant_index: usize,
variant: &str) -> Result<(), ()> {
let mut values = BTreeMap::new();
values.insert(variant.to_string(), Value::Array(vec![]));
@@ -467,6 +471,22 @@ impl ser::Serializer for Serializer {
Ok(())
}
#[inline]
fn visit_newtype_variant<T>(&mut self,
_name: &str,
_variant_index: usize,
variant: &str,
value: T) -> Result<(), ()>
where T: ser::Serialize,
{
let mut values = BTreeMap::new();
values.insert(variant.to_string(), to_value(&value));
self.state.push(State::Value(Value::Object(values)));
Ok(())
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<(), ()>
where V: ser::SeqVisitor,
@@ -489,7 +509,11 @@ impl ser::Serializer for Serializer {
}
#[inline]
fn visit_enum_seq<V>(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()>
fn visit_tuple_variant<V>(&mut self,
_name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> Result<(), ()>
where V: ser::SeqVisitor,
{
try!(self.visit_seq(visitor));
@@ -548,7 +572,11 @@ impl ser::Serializer for Serializer {
}
#[inline]
fn visit_enum_map<V>(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()>
fn visit_struct_variant<V>(&mut self,
_name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> Result<(), ()>
where V: ser::MapVisitor,
{
try!(self.visit_map(visitor));
@@ -622,7 +650,7 @@ impl de::Deserializer for Deserializer {
{
let value = match self.value.take() {
Some(value) => value,
None => { return Err(de::Error::end_of_stream_error()); }
None => { return Err(de::Error::end_of_stream()); }
};
match value {
@@ -659,58 +687,121 @@ impl de::Deserializer for Deserializer {
match self.value {
Some(Value::Null) => visitor.visit_none(),
Some(_) => visitor.visit_some(self),
None => Err(de::Error::end_of_stream_error()),
None => Err(de::Error::end_of_stream()),
}
}
#[inline]
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_enum<V>(&mut self,
_name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
let value = match self.value.take() {
Some(Value::Object(value)) => value,
Some(_) => { return Err(de::Error::syntax_error()); }
None => { return Err(de::Error::end_of_stream_error()); }
Some(_) => { return Err(de::Error::syntax("expected an enum")); }
None => { return Err(de::Error::end_of_stream()); }
};
let mut iter = value.into_iter();
let value = match iter.next() {
Some((variant, Value::Array(fields))) => {
self.value = Some(Value::String(variant));
let len = fields.len();
try!(visitor.visit(SeqDeserializer {
de: self,
iter: fields.into_iter(),
len: len,
}))
}
Some((variant, Value::Object(fields))) => {
let len = fields.len();
try!(visitor.visit(MapDeserializer {
de: self,
iter: fields.into_iter(),
value: Some(Value::String(variant)),
len: len,
}))
}
Some(_) => { return Err(de::Error::syntax_error()); }
None => { return Err(de::Error::syntax_error()); }
let (variant, value) = match iter.next() {
Some(v) => v,
None => return Err(de::Error::syntax("expected a variant name")),
};
// enums are encoded in json as maps with a single key:value pair
match iter.next() {
Some(_) => Err(de::Error::syntax_error()),
None => Ok(value)
Some(_) => Err(de::Error::syntax("expected map")),
None => visitor.visit(VariantDeserializer {
de: self,
val: Some(value),
variant: Some(Value::String(variant)),
}),
}
}
#[inline]
fn visit_newtype_struct<V>(&mut self,
_name: &'static str,
mut visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor,
{
visitor.visit_newtype_struct(self)
}
#[inline]
fn format() -> &'static str {
"json"
}
}
struct VariantDeserializer<'a> {
de: &'a mut Deserializer,
val: Option<Value>,
variant: Option<Value>,
}
impl<'a> de::VariantVisitor for VariantDeserializer<'a> {
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
de::Deserialize::deserialize(&mut Deserializer::new(self.variant.take().unwrap()))
}
fn visit_unit(&mut self) -> Result<(), Error> {
de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap()))
}
fn visit_newtype<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize,
{
de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap()))
}
fn visit_tuple<V>(&mut self,
_len: usize,
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
if let Value::Array(fields) = self.val.take().unwrap() {
de::Deserializer::visit(
&mut SeqDeserializer {
de: self.de,
len: fields.len(),
iter: fields.into_iter(),
},
visitor,
)
} else {
Err(de::Error::syntax("expected a tuple"))
}
}
fn visit_struct<V>(&mut self,
_fields: &'static[&'static str],
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
if let Value::Object(fields) = self.val.take().unwrap() {
de::Deserializer::visit(
&mut MapDeserializer {
de: self.de,
len: fields.len(),
iter: fields.into_iter(),
value: None,
},
visitor,
)
} else {
Err(de::Error::syntax("expected a struct"))
}
}
}
struct SeqDeserializer<'a> {
de: &'a mut Deserializer,
iter: vec::IntoIter<Value>,
@@ -752,7 +843,7 @@ impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
if self.len == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream_error())
Err(de::Error::length_mismatch(self.len))
}
}
@@ -761,33 +852,6 @@ impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
}
}
impl<'a> de::VariantVisitor for SeqDeserializer<'a> {
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
de::Deserialize::deserialize(self.de)
}
fn visit_unit(&mut self) -> Result<(), Error>
{
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
}
struct MapDeserializer<'a> {
de: &'a mut Deserializer,
iter: btree_map::IntoIter<String, Value>,
@@ -824,7 +888,7 @@ impl<'a> de::MapVisitor for MapDeserializer<'a> {
if self.len == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream_error())
Err(de::Error::length_mismatch(self.len))
}
}
@@ -865,38 +929,10 @@ impl<'a> de::Deserializer for MapDeserializer<'a> {
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
println!("MapDeserializer!");
visitor.visit_map(self)
}
}
impl<'a> de::VariantVisitor for MapDeserializer<'a> {
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
self.de.value = self.value.take();
de::Deserialize::deserialize(self.de)
}
fn visit_unit(&mut self) -> Result<(), Error> {
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
}
/// Shortcut function to encode a `T` into a JSON `Value`
pub fn to_value<T>(value: &T) -> Value
where T: ser::Serialize
+6 -3
View File
@@ -1,10 +1,12 @@
[package]
name = "serde_macros"
version = "0.4.1"
version = "0.5.1"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
repository = "https://github.com/erickt/rust-serde"
repository = "https://github.com/serde-rs/serde"
documentation = "https://github.com/serde-rs/serde"
keywords = ["serde", "serialization"]
[lib]
name = "serde_macros"
@@ -16,4 +18,5 @@ serde_codegen = { version = "*", path = "../serde_codegen", default-features = f
[dev-dependencies]
num = "*"
rustc-serialize = "*"
serde = { version = "*", path = "../serde" }
serde = { version = "*", path = "../serde", features = ["nightly"] }
serde_json = { version = "*", path = "../serde_json" }
+1
View File
@@ -4,6 +4,7 @@
extern crate num;
extern crate rustc_serialize;
extern crate serde;
extern crate serde_json;
extern crate test;
include!("../../serde_tests/benches/bench.rs.in");
+10 -8
View File
@@ -2,9 +2,9 @@
#![plugin(serde_macros)]
extern crate serde;
extern crate serde_json;
use std::collections::BTreeMap;
use serde::json;
// Creating serializable types with serde is quite simple with `serde_macros`. It implements a
// syntax extension that automatically generates the necessary serde trait implementations.
@@ -18,7 +18,7 @@ fn main() {
let point = Point { x: 5, y: 6 };
// Serializing to JSON is pretty simple by using the `to_string` method:
let serialized_point = json::to_string(&point).unwrap();
let serialized_point = serde_json::to_string(&point).unwrap();
println!("{}", serialized_point);
// prints:
@@ -26,7 +26,7 @@ fn main() {
// {"x":5,"y":6}
// There is also support for pretty printing using `to_string_pretty`:
let serialized_point = json::to_string_pretty(&point).unwrap();
let serialized_point = serde_json::to_string_pretty(&point).unwrap();
println!("{}", serialized_point);
// prints:
@@ -37,7 +37,7 @@ fn main() {
// }
// Values can also be deserialized with the same style using `from_str`:
let deserialized_point: Point = json::from_str(&serialized_point).unwrap();
let deserialized_point: Point = serde_json::from_str(&serialized_point).unwrap();
println!("{:?}", deserialized_point);
// prints:
@@ -46,16 +46,18 @@ fn main() {
// `Point`s aren't the only type that can be serialized to. Because `Point` members have the
// same type, they can be also serialized into a map. Also,
let deserialized_map: BTreeMap<String, i64> = json::from_str(&serialized_point).unwrap();
let deserialized_map: BTreeMap<String, i64> =
serde_json::from_str(&serialized_point).unwrap();
println!("{:?}", deserialized_map);
// prints:
//
// {"x": 5, "y": 6}
// If you need to accept arbitrary data, you can also deserialize into `json::Value`, which
// can represent all JSON values.
let deserialized_value: json::Value = json::from_str(&serialized_point).unwrap();
// If you need to accept arbitrary data, you can also deserialize into `serde_json::Value`,
// which can represent all JSON values.
let deserialized_value: serde_json::Value =
serde_json::from_str(&serialized_point).unwrap();
println!("{:?}", deserialized_value);
// prints:
+1
View File
@@ -2,6 +2,7 @@
#![plugin(serde_macros)]
extern crate serde;
extern crate serde_json;
extern crate test;
include!("../../serde_tests/tests/test.rs.in");
+3 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_tests"
version = "0.4.1"
version = "0.5.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
@@ -11,7 +11,7 @@ keywords = ["serialization"]
build = "build.rs"
[build-dependencies]
syntex = { version = "*", optional = true }
syntex = { version = "*" }
syntex_syntax = { version = "*" }
serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-syntex"] }
@@ -19,6 +19,7 @@ serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-sy
num = "*"
rustc-serialize = "*"
serde = { version = "*", path = "../serde" }
serde_json = { version = "*", path = "../serde_json" }
syntex = "*"
[[test]]
+1
View File
@@ -3,6 +3,7 @@
extern crate num;
extern crate rustc_serialize;
extern crate serde;
extern crate serde_json;
extern crate test;
include!(concat!(env!("OUT_DIR"), "/bench.rs"));
+11 -6
View File
@@ -20,13 +20,13 @@ pub enum Error {
}
impl serde::de::Error for Error {
fn syntax_error() -> Error { Error::SyntaxError }
fn syntax(_: &str) -> Error { Error::SyntaxError }
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
fn end_of_stream() -> Error { Error::EndOfStreamError }
fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn unknown_field(_: &str) -> Error { Error::SyntaxError }
fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError }
fn missing_field(_: &'static str) -> Error { Error::SyntaxError }
}
//////////////////////////////////////////////////////////////////////////////
@@ -288,7 +288,10 @@ mod deserializer {
}
#[inline]
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_enum<V>(&mut self,
_name: &str,
_variants: &[&str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
match self.stack.pop() {
@@ -350,7 +353,9 @@ mod deserializer {
de::Deserialize::deserialize(self.de)
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
fn visit_tuple<V>(&mut self,
_len: usize,
mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_seq(self)
+23 -23
View File
@@ -5,9 +5,9 @@ use test::Bencher;
use rustc_serialize;
use serde::de::{self, Deserialize, Deserializer};
use serde::json::ser::escape_str;
use serde::json;
use serde::ser::{self, Serialize, Serializer};
use serde_json::ser::escape_str;
use serde_json;
use std::str::FromStr;
use rustc_serialize::Encodable;
@@ -50,7 +50,7 @@ impl rustc_serialize::Decodable for HttpProtocol {
impl FromStr for HttpProtocol {
type Err = ();
fn from_str(s: &str) -> Result<HttpProtocol, ()> { unimplemented!() }
fn from_str(_s: &str) -> Result<HttpProtocol, ()> { unimplemented!() }
}
impl FromPrimitive for HttpProtocol {
@@ -104,7 +104,7 @@ enum HttpMethod {
impl FromStr for HttpMethod {
type Err = ();
fn from_str(s: &str) -> Result<HttpMethod, ()> { unimplemented!() }
fn from_str(_s: &str) -> Result<HttpMethod, ()> { unimplemented!() }
}
impl FromPrimitive for HttpMethod {
@@ -174,7 +174,7 @@ enum CacheStatus {
impl FromStr for CacheStatus {
type Err = ();
fn from_str(s: &str) -> Result<CacheStatus, ()> { unimplemented!() }
fn from_str(_s: &str) -> Result<CacheStatus, ()> { unimplemented!() }
}
impl FromPrimitive for CacheStatus {
@@ -244,7 +244,7 @@ enum OriginProtocol {
impl FromStr for OriginProtocol {
type Err = ();
fn from_str(s: &str) -> Result<OriginProtocol, ()> { unimplemented!() }
fn from_str(_s: &str) -> Result<OriginProtocol, ()> { unimplemented!() }
}
impl FromPrimitive for OriginProtocol {
@@ -307,7 +307,7 @@ enum ZonePlan {
impl FromStr for ZonePlan {
type Err = ();
fn from_str(s: &str) -> Result<ZonePlan, ()> { unimplemented!() }
fn from_str(_s: &str) -> Result<ZonePlan, ()> { unimplemented!() }
}
impl FromPrimitive for ZonePlan {
@@ -622,7 +622,7 @@ enum Country {
impl FromStr for Country {
type Err = ();
fn from_str(s: &str) -> Result<Country, ()> { unimplemented!() }
fn from_str(_s: &str) -> Result<Country, ()> { unimplemented!() }
}
impl FromPrimitive for Country {
@@ -1123,18 +1123,18 @@ fn bench_encoder(b: &mut Bencher) {
#[test]
fn test_serializer() {
let log = Log::new();
let json = json::to_vec(&log);
let json = serde_json::to_vec(&log);
assert_eq!(json, JSON_STR.as_bytes());
}
#[bench]
fn bench_serializer(b: &mut Bencher) {
let log = Log::new();
let json = json::to_vec(&log);
let json = serde_json::to_vec(&log);
b.bytes = json.len() as u64;
b.iter(|| {
let _ = json::to_vec(&log);
let _ = serde_json::to_vec(&log);
});
}
@@ -1142,7 +1142,7 @@ fn bench_serializer(b: &mut Bencher) {
fn test_serializer_vec() {
let log = Log::new();
let wr = Vec::with_capacity(1024);
let mut serializer = json::Serializer::new(wr);
let mut serializer = serde_json::Serializer::new(wr);
log.serialize(&mut serializer).unwrap();
let json = serializer.into_inner();
@@ -1152,7 +1152,7 @@ fn test_serializer_vec() {
#[bench]
fn bench_serializer_vec(b: &mut Bencher) {
let log = Log::new();
let json = json::to_vec(&log);
let json = serde_json::to_vec(&log);
b.bytes = json.len() as u64;
let mut wr = Vec::with_capacity(1024);
@@ -1160,7 +1160,7 @@ fn bench_serializer_vec(b: &mut Bencher) {
b.iter(|| {
wr.clear();
let mut serializer = json::Serializer::new(wr.by_ref());
let mut serializer = serde_json::Serializer::new(wr.by_ref());
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
@@ -1169,7 +1169,7 @@ fn bench_serializer_vec(b: &mut Bencher) {
#[bench]
fn bench_serializer_slice(b: &mut Bencher) {
let log = Log::new();
let json = json::to_vec(&log);
let json = serde_json::to_vec(&log);
b.bytes = json.len() as u64;
let mut buf = [0; 1024];
@@ -1178,7 +1178,7 @@ fn bench_serializer_slice(b: &mut Bencher) {
for item in buf.iter_mut(){ *item = 0; }
let mut wr = &mut buf[..];
let mut serializer = json::Serializer::new(wr.by_ref());
let mut serializer = serde_json::Serializer::new(wr.by_ref());
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
@@ -1191,7 +1191,7 @@ fn test_serializer_my_mem_writer0() {
let mut wr = MyMemWriter0::with_capacity(1024);
{
let mut serializer = json::Serializer::new(wr.by_ref());
let mut serializer = serde_json::Serializer::new(wr.by_ref());
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
}
@@ -1202,7 +1202,7 @@ fn test_serializer_my_mem_writer0() {
#[bench]
fn bench_serializer_my_mem_writer0(b: &mut Bencher) {
let log = Log::new();
let json = json::to_vec(&log);
let json = serde_json::to_vec(&log);
b.bytes = json.len() as u64;
let mut wr = MyMemWriter0::with_capacity(1024);
@@ -1210,7 +1210,7 @@ fn bench_serializer_my_mem_writer0(b: &mut Bencher) {
b.iter(|| {
wr.buf.clear();
let mut serializer = json::Serializer::new(wr.by_ref());
let mut serializer = serde_json::Serializer::new(wr.by_ref());
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
@@ -1223,7 +1223,7 @@ fn test_serializer_my_mem_writer1() {
let mut wr = MyMemWriter1::with_capacity(1024);
{
let mut serializer = json::Serializer::new(wr.by_ref());
let mut serializer = serde_json::Serializer::new(wr.by_ref());
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
}
@@ -1234,7 +1234,7 @@ fn test_serializer_my_mem_writer1() {
#[bench]
fn bench_serializer_my_mem_writer1(b: &mut Bencher) {
let log = Log::new();
let json = json::to_vec(&log);
let json = serde_json::to_vec(&log);
b.bytes = json.len() as u64;
let mut wr = MyMemWriter1::with_capacity(1024);
@@ -1242,7 +1242,7 @@ fn bench_serializer_my_mem_writer1(b: &mut Bencher) {
b.iter(|| {
wr.buf.clear();
let mut serializer = json::Serializer::new(wr.by_ref());
let mut serializer = serde_json::Serializer::new(wr.by_ref());
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
@@ -1593,6 +1593,6 @@ fn bench_deserializer(b: &mut Bencher) {
b.bytes = JSON_STR.len() as u64;
b.iter(|| {
let _log: Log = json::from_str(JSON_STR).unwrap();
let _log: Log = serde_json::from_str(JSON_STR).unwrap();
});
}
+7 -7
View File
@@ -17,13 +17,13 @@ pub enum Error {
}
impl serde::de::Error for Error {
fn syntax_error() -> Error { Error::SyntaxError }
fn syntax(_: &str) -> Error { Error::SyntaxError }
fn end_of_stream_error() -> Error { Error::EndOfStream }
fn end_of_stream() -> Error { Error::EndOfStream }
fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn unknown_field(_: &str) -> Error { Error::SyntaxError }
fn missing_field_error(_: &'static str) -> Error {
fn missing_field(_: &'static str) -> Error {
Error::MissingField
}
}
@@ -347,17 +347,17 @@ mod deserializer {
impl de::Deserializer<Error> for IsizeDeserializer {
#[inline]
fn end_of_stream_error(&mut self) -> Error {
fn end_of_stream(&mut self) -> Error {
EndOfStream
}
#[inline]
fn syntax_error(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error {
fn syntax(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error {
SyntaxError
}
#[inline]
fn unexpected_name_error(&mut self, _token: de::Token) -> Error {
fn unexpected_name(&mut self, _token: de::Token) -> Error {
SyntaxError
}
+8 -5
View File
@@ -33,13 +33,13 @@ pub enum Error {
}
impl serde::de::Error for Error {
fn syntax_error() -> Error { Error::SyntaxError }
fn syntax(_: &str) -> Error { Error::SyntaxError }
fn end_of_stream_error() -> Error { Error::EndOfStream }
fn end_of_stream() -> Error { Error::EndOfStream }
fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn unknown_field(_: &str) -> Error { Error::SyntaxError }
fn missing_field_error(_: &'static str) -> Error {
fn missing_field(_: &'static str) -> Error {
Error::MissingField
}
}
@@ -398,7 +398,10 @@ mod deserializer {
}
}
fn visit_named_map<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_struct<V>(&mut self,
name: &str,
_fields: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.stack.pop() {
+4 -4
View File
@@ -15,13 +15,13 @@ pub enum Error {
}
impl serde::de::Error for Error {
fn syntax_error() -> Error { Error::SyntaxError }
fn syntax(_: &str) -> Error { Error::SyntaxError }
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
fn end_of_stream() -> Error { Error::EndOfStreamError }
fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn unknown_field(_: &str) -> Error { Error::SyntaxError }
fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError }
fn missing_field(_: &'static str) -> Error { Error::SyntaxError }
}
//////////////////////////////////////////////////////////////////////////////
+1
View File
@@ -1,3 +1,4 @@
extern crate serde;
extern crate serde_json;
include!(concat!(env!("OUT_DIR"), "/test.rs"));
-4
View File
@@ -1,11 +1,7 @@
/*
mod test_annotations;
mod test_bytes;
mod test_de;
mod test_json;
mod test_json_builder;
*/
mod test_macros;
/*
mod test_ser;
*/
+26 -9
View File
@@ -1,4 +1,5 @@
use serde::json;
use std::default;
use serde_json;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Default {
@@ -30,33 +31,39 @@ enum SerEnum<A> {
},
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct SkipSerializingFields<A: default::Default> {
a: i8,
#[serde(skip_serializing, default)]
b: A,
}
#[test]
fn test_default() {
let deserialized_value: Default = json::from_str(&"{\"a1\":1,\"a2\":2}").unwrap();
let deserialized_value: Default = serde_json::from_str(&"{\"a1\":1,\"a2\":2}").unwrap();
assert_eq!(deserialized_value, Default { a1: 1, a2: 2 });
let deserialized_value: Default = json::from_str(&"{\"a1\":1}").unwrap();
let deserialized_value: Default = serde_json::from_str(&"{\"a1\":1}").unwrap();
assert_eq!(deserialized_value, Default { a1: 1, a2: 0 });
}
#[test]
fn test_rename() {
let value = Rename { a1: 1, a2: 2 };
let serialized_value = json::to_string(&value).unwrap();
let serialized_value = serde_json::to_string(&value).unwrap();
assert_eq!(serialized_value, "{\"a1\":1,\"a3\":2}");
let deserialized_value: Rename = json::from_str(&serialized_value).unwrap();
let deserialized_value: Rename = serde_json::from_str(&serialized_value).unwrap();
assert_eq!(value, deserialized_value);
}
#[test]
fn test_format_rename() {
let value = FormatRename { a1: 1, a2: 2 };
let serialized_value = json::to_string(&value).unwrap();
let serialized_value = serde_json::to_string(&value).unwrap();
assert_eq!(serialized_value, "{\"a1\":1,\"a5\":2}");
let deserialized_value = json::from_str("{\"a1\":1,\"a5\":2}").unwrap();
let deserialized_value = serde_json::from_str("{\"a1\":1,\"a5\":2}").unwrap();
assert_eq!(value, deserialized_value);
}
@@ -64,10 +71,20 @@ fn test_format_rename() {
fn test_enum_format_rename() {
let s1 = String::new();
let value = SerEnum::Map { a: 0i8, b: s1 };
let serialized_value = json::to_string(&value).unwrap();
let serialized_value = serde_json::to_string(&value).unwrap();
let ans = "{\"Map\":{\"a\":0,\"d\":\"\"}}";
assert_eq!(serialized_value, ans);
let deserialized_value = json::from_str(ans).unwrap();
let deserialized_value = serde_json::from_str(ans).unwrap();
assert_eq!(value, deserialized_value);
}
#[test]
fn test_skip_serializing_fields() {
let value = SkipSerializingFields { a: 1, b: 2 };
let serialized_value = serde_json::to_string(&value).unwrap();
assert_eq!(serialized_value, "{\"a\":1}");
let deserialized_value: SkipSerializingFields<_> = serde_json::from_str(&serialized_value).unwrap();
assert_eq!(SkipSerializingFields { a: 1, b: 0 }, deserialized_value);
}
+11 -11
View File
@@ -1,7 +1,7 @@
use serde;
use serde::Serialize;
use serde::bytes::{ByteBuf, Bytes};
use serde::json;
use serde_json;
///////////////////////////////////////////////////////////////////////////////
@@ -9,13 +9,13 @@ use serde::json;
struct Error;
impl serde::de::Error for Error {
fn syntax_error() -> Error { Error }
fn syntax(_: &str) -> Error { Error }
fn end_of_stream_error() -> Error { Error }
fn end_of_stream() -> Error { Error }
fn unknown_field_error(_field: &str) -> Error { Error }
fn unknown_field(_field: &str) -> Error { Error }
fn missing_field_error(_field: &'static str) -> Error { Error }
fn missing_field(_field: &'static str) -> Error { Error }
}
///////////////////////////////////////////////////////////////////////////////
@@ -144,11 +144,11 @@ impl serde::Deserializer for BytesDeserializer {
fn test_bytes_ser_json() {
let buf = vec![];
let bytes = Bytes::from(&buf);
assert_eq!(json::to_string(&bytes).unwrap(), "[]".to_string());
assert_eq!(serde_json::to_string(&bytes).unwrap(), "[]".to_string());
let buf = vec![1, 2, 3];
let bytes = Bytes::from(&buf);
assert_eq!(json::to_string(&bytes).unwrap(), "[1,2,3]".to_string());
assert_eq!(serde_json::to_string(&bytes).unwrap(), "[1,2,3]".to_string());
}
#[test]
@@ -167,10 +167,10 @@ fn test_bytes_ser_bytes() {
#[test]
fn test_byte_buf_ser_json() {
let bytes = ByteBuf::new();
assert_eq!(json::to_string(&bytes).unwrap(), "[]".to_string());
assert_eq!(serde_json::to_string(&bytes).unwrap(), "[]".to_string());
let bytes = ByteBuf::from(vec![1, 2, 3]);
assert_eq!(json::to_string(&bytes).unwrap(), "[1,2,3]".to_string());
assert_eq!(serde_json::to_string(&bytes).unwrap(), "[1,2,3]".to_string());
}
#[test]
@@ -189,11 +189,11 @@ fn test_byte_buf_ser_bytes() {
#[test]
fn test_byte_buf_de_json() {
let bytes = ByteBuf::new();
let v: ByteBuf = json::from_str("[]").unwrap();
let v: ByteBuf = serde_json::from_str("[]").unwrap();
assert_eq!(v, bytes);
let bytes = ByteBuf::from(vec![1, 2, 3]);
let v: ByteBuf = json::from_str("[1, 2, 3]").unwrap();
let v: ByteBuf = serde_json::from_str("[1, 2, 3]").unwrap();
assert_eq!(v, bytes);
}
+134 -30
View File
@@ -22,6 +22,7 @@ enum Token {
Char(char),
Str(&'static str),
String(String),
Bytes(&'static [u8]),
Option(bool),
@@ -38,6 +39,10 @@ enum Token {
MapEnd,
EnumStart(&'static str),
EnumUnit,
EnumNewtype,
EnumSeq,
EnumMap,
EnumEnd,
}
@@ -63,15 +68,15 @@ enum Error {
}
impl de::Error for Error {
fn syntax_error() -> Error { Error::SyntaxError }
fn syntax(_: &str) -> Error { Error::SyntaxError }
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
fn end_of_stream() -> Error { Error::EndOfStreamError }
fn unknown_field_error(field: &str) -> Error {
fn unknown_field(field: &str) -> Error {
Error::UnknownFieldError(field.to_string())
}
fn missing_field_error(field: &'static str) -> Error {
fn missing_field(field: &'static str) -> Error {
Error::MissingFieldError(field)
}
}
@@ -99,6 +104,7 @@ impl Deserializer for TokenDeserializer {
Some(Token::Char(v)) => visitor.visit_char(v),
Some(Token::Str(v)) => visitor.visit_str(v),
Some(Token::String(v)) => visitor.visit_string(v),
Some(Token::Bytes(v)) => visitor.visit_bytes(v),
Some(Token::Option(false)) => visitor.visit_none(),
Some(Token::Option(true)) => visitor.visit_some(self),
Some(Token::Unit) => visitor.visit_unit(),
@@ -143,7 +149,10 @@ impl Deserializer for TokenDeserializer {
}
}
fn visit_enum<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_enum<V>(&mut self,
name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
match self.tokens.next() {
@@ -161,7 +170,7 @@ impl Deserializer for TokenDeserializer {
}
}
fn visit_named_unit<V>(&mut self, name: &str, visitor: V) -> Result<V::Value, Error>
fn visit_unit_struct<V>(&mut self, name: &str, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.tokens.peek() {
@@ -178,7 +187,10 @@ impl Deserializer for TokenDeserializer {
}
}
fn visit_named_seq<V>(&mut self, name: &str, visitor: V) -> Result<V::Value, Error>
fn visit_tuple_struct<V>(&mut self,
name: &str,
_len: usize,
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.tokens.peek() {
@@ -195,7 +207,10 @@ impl Deserializer for TokenDeserializer {
}
}
fn visit_named_map<V>(&mut self, name: &str, visitor: V) -> Result<V::Value, Error>
fn visit_struct<V>(&mut self,
name: &str,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.tokens.peek() {
@@ -315,32 +330,66 @@ impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> {
}
fn visit_unit(&mut self) -> Result<(), Error> {
de::Deserialize::deserialize(self.de)
match self.de.tokens.next() {
Some(Token::EnumUnit) => {
de::Deserialize::deserialize(self.de)
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
fn visit_newtype<T>(&mut self) -> Result<T, Self::Error>
where T: de::Deserialize,
{
de::Deserializer::visit(self.de, visitor)
match self.de.tokens.next() {
Some(Token::EnumNewtype) => {
de::Deserialize::deserialize(self.de)
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
fn visit_tuple<V>(&mut self,
_len: usize,
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self.de, visitor)
match self.de.tokens.next() {
Some(Token::EnumSeq) => {
de::Deserializer::visit(self.de, visitor)
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn visit_struct<V>(&mut self,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.de.tokens.next() {
Some(Token::EnumMap) => {
de::Deserializer::visit(self.de, visitor)
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
}
//////////////////////////////////////////////////////////////////////////
#[derive(Copy, Clone, PartialEq, Debug, Deserialize)]
struct NamedUnit;
struct UnitStruct;
#[derive(PartialEq, Debug, Deserialize)]
struct NamedSeq(i32, i32, i32);
struct TupleStruct(i32, i32, i32);
#[derive(PartialEq, Debug, Deserialize)]
struct NamedMap {
struct Struct {
a: i32,
b: i32,
c: i32,
@@ -349,6 +398,7 @@ struct NamedMap {
#[derive(PartialEq, Debug, Deserialize)]
enum Enum {
Unit,
Simple(i32),
Seq(i32, i32, i32),
Map { a: i32, b: i32, c: i32 }
}
@@ -486,6 +536,24 @@ declare_tests! {
Token::I32(1),
],
}
test_result {
Ok::<i32, i32>(0) => vec![
Token::EnumStart("Result"),
Token::Str("Ok"),
Token::EnumNewtype,
Token::I32(0),
Token::SeqEnd,
],
Err::<i32, i32>(1) => vec![
Token::EnumStart("Result"),
Token::Str("Err"),
Token::EnumNewtype,
Token::I32(1),
Token::SeqEnd,
],
}
test_unit {
() => vec![Token::Unit],
() => vec![
@@ -498,19 +566,19 @@ declare_tests! {
Token::SeqEnd,
],
}
test_named_unit {
NamedUnit => vec![Token::Unit],
NamedUnit => vec![
Token::Name("NamedUnit"),
test_unit_struct {
UnitStruct => vec![Token::Unit],
UnitStruct => vec![
Token::Name("UnitStruct"),
Token::Unit,
],
NamedUnit => vec![
UnitStruct => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
}
test_named_seq {
NamedSeq(1, 2, 3) => vec![
test_tuple_struct {
TupleStruct(1, 2, 3) => vec![
Token::SeqStart(3),
Token::SeqSep,
Token::I32(1),
@@ -522,8 +590,8 @@ declare_tests! {
Token::I32(3),
Token::SeqEnd,
],
NamedSeq(1, 2, 3) => vec![
Token::Name("NamedSeq"),
TupleStruct(1, 2, 3) => vec![
Token::Name("TupleStruct"),
Token::SeqStart(3),
Token::SeqSep,
Token::I32(1),
@@ -818,8 +886,8 @@ declare_tests! {
Token::MapEnd,
],
}
test_named_map {
NamedMap { a: 1, b: 2, c: 3 } => vec![
test_struct {
Struct { a: 1, b: 2, c: 3 } => vec![
Token::MapStart(3),
Token::MapSep,
Token::Str("a"),
@@ -834,8 +902,8 @@ declare_tests! {
Token::I32(3),
Token::MapEnd,
],
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::Name("NamedMap"),
Struct { a: 1, b: 2, c: 3 } => vec![
Token::Name("Struct"),
Token::MapStart(3),
Token::MapSep,
Token::Str("a"),
@@ -855,14 +923,28 @@ declare_tests! {
Enum::Unit => vec![
Token::EnumStart("Enum"),
Token::Str("Unit"),
Token::EnumUnit,
Token::Unit,
Token::EnumEnd,
],
}
test_enum_simple {
Enum::Simple(1) => vec![
Token::EnumStart("Enum"),
Token::Str("Simple"),
Token::EnumNewtype,
Token::I32(1),
Token::EnumEnd,
],
}
test_enum_seq {
Enum::Seq(1, 2, 3) => vec![
Token::EnumStart("Enum"),
Token::Str("Seq"),
Token::EnumSeq,
Token::SeqStart(3),
Token::SeqSep,
Token::I32(1),
@@ -880,6 +962,8 @@ declare_tests! {
Enum::Map { a: 1, b: 2, c: 3 } => vec![
Token::EnumStart("Enum"),
Token::Str("Map"),
Token::EnumMap,
Token::MapStart(3),
Token::MapSep,
Token::Str("a"),
@@ -896,4 +980,24 @@ declare_tests! {
Token::EnumEnd,
],
}
test_enum_unit_usize {
Enum::Unit => vec![
Token::EnumStart("Enum"),
Token::Usize(0),
Token::EnumUnit,
Token::Unit,
Token::EnumEnd,
],
}
test_enum_unit_bytes {
Enum::Unit => vec![
Token::EnumStart("Enum"),
Token::Bytes(b"Unit"),
Token::EnumUnit,
Token::Unit,
Token::EnumEnd,
],
}
}
+294 -25
View File
@@ -1,10 +1,14 @@
use std::fmt::Debug;
use std::collections::BTreeMap;
use std::f64;
use std::fmt::Debug;
use std::i64;
use std::marker::PhantomData;
use std::u64;
use serde::de;
use serde::ser;
use serde::json::{
use serde_json::{
self,
Value,
from_str,
@@ -12,7 +16,7 @@ use serde::json::{
to_value,
};
use serde::json::error::{Error, ErrorCode};
use serde_json::error::{Error, ErrorCode};
macro_rules! treemap {
($($k:expr => $v:expr),*) => ({
@@ -27,7 +31,7 @@ enum Animal {
Dog,
Frog(String, Vec<isize>),
Cat { age: usize, name: String },
AntHive(Vec<String>),
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@@ -48,11 +52,11 @@ fn test_encode_ok<T>(errors: &[(T, &str)])
for &(ref value, out) in errors {
let out = out.to_string();
let s = json::to_string(value).unwrap();
let s = serde_json::to_string(value).unwrap();
assert_eq!(s, out);
let v = to_value(&value);
let s = json::to_string(&v).unwrap();
let s = serde_json::to_string(&v).unwrap();
assert_eq!(s, out);
}
}
@@ -63,11 +67,11 @@ fn test_pretty_encode_ok<T>(errors: &[(T, &str)])
for &(ref value, out) in errors {
let out = out.to_string();
let s = json::to_string_pretty(value).unwrap();
let s = serde_json::to_string_pretty(value).unwrap();
assert_eq!(s, out);
let v = to_value(&value);
let s = json::to_string_pretty(&v).unwrap();
let s = serde_json::to_string_pretty(&v).unwrap();
assert_eq!(s, out);
}
}
@@ -81,12 +85,23 @@ fn test_write_null() {
test_pretty_encode_ok(tests);
}
#[test]
fn test_write_u64() {
let tests = &[
(3u64, "3"),
(u64::MAX, &u64::MAX.to_string()),
];
test_encode_ok(tests);
test_pretty_encode_ok(tests);
}
#[test]
fn test_write_i64() {
let tests = &[
(3i64, "3"),
(-2i64, "-2"),
(-1234i64, "-1234"),
(i64::MIN, &i64::MIN.to_string()),
];
test_encode_ok(tests);
test_pretty_encode_ok(tests);
@@ -94,11 +109,18 @@ fn test_write_i64() {
#[test]
fn test_write_f64() {
let min_string = format!("{:?}", f64::MIN);
let max_string = format!("{:?}", f64::MAX);
let epsilon_string = format!("{:?}", f64::EPSILON);
let tests = &[
(3.0, "3.0"),
(3.0, "3"),
(3.1, "3.1"),
(-1.5, "-1.5"),
(0.5, "0.5"),
(f64::MIN, &min_string),
(f64::MAX, &max_string),
(f64::EPSILON, &epsilon_string),
];
test_encode_ok(tests);
test_pretty_encode_ok(tests);
@@ -533,6 +555,10 @@ fn test_write_enum() {
Animal::Cat { age: 5, name: "Kate".to_string() },
"{\"Cat\":{\"age\":5,\"name\":\"Kate\"}}"
),
(
Animal::AntHive(vec!["Bob".to_string(), "Stuart".to_string()]),
"{\"AntHive\":[\"Bob\",\"Stuart\"]}",
),
]);
test_pretty_encode_ok(&[
@@ -616,7 +642,7 @@ fn test_write_option() {
]);
}
fn test_parse_ok<T>(errors: Vec<(&'static str, T)>)
fn test_parse_ok<T>(errors: Vec<(&str, T)>)
where T: Clone + Debug + PartialEq + ser::Serialize + de::Deserialize,
{
for (s, value) in errors {
@@ -702,7 +728,6 @@ fn test_parse_number_errors() {
("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)),
("777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 20)),
("1e777777777777777777777777777", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 22)),
]);
}
@@ -713,28 +738,44 @@ fn test_parse_i64() {
("-2", -2),
("-1234", -1234),
(" -1234 ", -1234),
(&i64::MIN.to_string(), i64::MIN),
(&i64::MAX.to_string(), i64::MAX),
]);
}
#[test]
fn test_parse_u64() {
test_parse_ok(vec![
("0", 0u64),
("3", 3u64),
("1234", 1234),
(&u64::MAX.to_string(), u64::MAX),
]);
}
#[test]
fn test_parse_f64() {
test_parse_ok(vec![
("0.0", 0.0f64),
("3.0", 3.0f64),
("3.00", 3.0f64),
("3.1", 3.1),
("-1.2", -1.2),
("0.4", 0.4),
("0.4e5", 0.4e5),
("0.4e+5", 0.4e5),
("0.4e15", 0.4e15),
("0.4e-01", 0.4e-01),
(" 0.4e-01 ", 0.4e-01),
("0.4e+15", 0.4e15),
("0.4e-01", 0.4e-1),
(" 0.4e-01 ", 0.4e-1),
("0.4e-001", 0.4e-1),
("0.4e-0", 0.4e0),
("0.00e00", 0.0),
("0.00e+00", 0.0),
("0.00e-00", 0.0),
(&format!("{:?}", (i64::MIN as f64) - 1.0), (i64::MIN as f64) - 1.0),
(&format!("{:?}", (u64::MAX as f64) + 1.0), (u64::MAX as f64) + 1.0),
(&format!("{:?}", f64::EPSILON), f64::EPSILON),
]);
}
@@ -763,8 +804,8 @@ fn test_parse_string() {
#[test]
fn test_parse_list() {
test_parse_err::<Vec<f64>>(vec![
("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 1)),
("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("[", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 1)),
("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 2)),
("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 2)),
("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
("[1,]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 4)),
@@ -815,8 +856,8 @@ fn test_parse_list() {
#[test]
fn test_parse_object() {
test_parse_err::<BTreeMap<String, u32>>(vec![
("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 1)),
("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("{", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 1)),
("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 2)),
("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)),
("{ \"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)),
("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 4)),
@@ -868,7 +909,7 @@ fn test_parse_struct() {
test_parse_err::<Outer>(vec![
("5", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
("\"hello\"", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 7)),
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 15)),
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 14)),
]);
test_parse_ok(vec![
@@ -891,7 +932,7 @@ fn test_parse_struct() {
Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] }
]
},
)
),
]);
let v: Outer = from_str("{}").unwrap();
@@ -902,6 +943,22 @@ fn test_parse_struct() {
inner: vec![],
}
);
let v: Outer = from_str(
"[
[
[ null, 2, [\"abc\", \"xyz\"] ]
]
]").unwrap();
assert_eq!(
v,
Outer {
inner: vec![
Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] }
],
}
);
}
#[test]
@@ -931,10 +988,10 @@ fn test_parse_enum_errors() {
("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)),
("{\"Dog\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 7)),
("{\"Dog\":}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::UnknownField("unknown".to_string()), 1, 11)),
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
("{\"Frog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 10)),
("{\"Cat\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::UnknownField("unknown".to_string()), 1, 10)),
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
("{\"Frog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
("{\"Cat\":[]}", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 9)),
]);
}
@@ -959,6 +1016,10 @@ fn test_parse_enum() {
" { \"Cat\" : { \"age\" : 5 , \"name\" : \"Kate\" } } ",
Animal::Cat { age: 5, name: "Kate".to_string() },
),
(
" { \"AntHive\" : [\"Bob\", \"Stuart\"] } ",
Animal::AntHive(vec!["Bob".to_string(), "Stuart".to_string()]),
),
]);
test_parse_ok(vec![
@@ -1064,7 +1125,7 @@ fn test_missing_fmt_renamed_field() {
#[test]
fn test_find_path() {
let obj: Value = json::from_str(r#"{"x": {"a": 1}, "y": 2}"#).unwrap();
let obj: Value = serde_json::from_str(r#"{"x": {"a": 1}, "y": 2}"#).unwrap();
assert!(obj.find_path(&["x", "a"]).unwrap() == &Value::U64(1));
assert!(obj.find_path(&["y"]).unwrap() == &Value::U64(2));
@@ -1073,9 +1134,217 @@ fn test_find_path() {
#[test]
fn test_lookup() {
let obj: Value = json::from_str(r#"{"x": {"a": 1}, "y": 2}"#).unwrap();
let obj: Value = serde_json::from_str(r#"{"x": {"a": 1}, "y": 2}"#).unwrap();
assert!(obj.lookup("x.a").unwrap() == &Value::U64(1));
assert!(obj.lookup("y").unwrap() == &Value::U64(2));
assert!(obj.lookup("z").is_none());
}
#[test]
fn test_serialize_seq_with_no_len() {
#[derive(Clone, Debug, PartialEq)]
struct MyVec<T>(Vec<T>);
impl<T> ser::Serialize for MyVec<T>
where T: ser::Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_seq(ser::impls::SeqIteratorVisitor::new(self.0.iter(), None))
}
}
struct Visitor<T> {
marker: PhantomData<MyVec<T>>,
}
impl<T> de::Visitor for Visitor<T>
where T: de::Deserialize,
{
type Value = MyVec<T>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<MyVec<T>, E>
where E: de::Error,
{
Ok(MyVec(Vec::new()))
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<MyVec<T>, V::Error>
where V: de::SeqVisitor,
{
let mut values = Vec::new();
while let Some(value) = try!(visitor.visit()) {
values.push(value);
}
try!(visitor.end());
Ok(MyVec(values))
}
}
impl<T> de::Deserialize for MyVec<T>
where T: de::Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<MyVec<T>, D::Error>
where D: de::Deserializer,
{
deserializer.visit_map(Visitor { marker: PhantomData })
}
}
let mut vec = Vec::new();
vec.push(MyVec(Vec::new()));
vec.push(MyVec(Vec::new()));
let vec: MyVec<MyVec<u32>> = MyVec(vec);
test_encode_ok(&[
(
vec.clone(),
"[[],[]]",
),
]);
let s = serde_json::to_string_pretty(&vec).unwrap();
assert_eq!(
s,
concat!(
"[\n",
" [\n",
" ],\n",
" [\n",
" ]\n",
"]"
)
);
}
#[test]
fn test_serialize_map_with_no_len() {
#[derive(Clone, Debug, PartialEq)]
struct Map<K, V>(BTreeMap<K, V>);
impl<K, V> ser::Serialize for Map<K, V>
where K: ser::Serialize + Ord,
V: ser::Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_map(ser::impls::MapIteratorVisitor::new(self.0.iter(), None))
}
}
struct Visitor<K, V> {
marker: PhantomData<Map<K, V>>,
}
impl<K, V> de::Visitor for Visitor<K, V>
where K: de::Deserialize + Eq + Ord,
V: de::Deserialize,
{
type Value = Map<K, V>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<Map<K, V>, E>
where E: de::Error,
{
Ok(Map(BTreeMap::new()))
}
#[inline]
fn visit_map<Visitor>(&mut self, mut visitor: Visitor) -> Result<Map<K, V>, Visitor::Error>
where Visitor: de::MapVisitor,
{
let mut values = BTreeMap::new();
while let Some((key, value)) = try!(visitor.visit()) {
values.insert(key, value);
}
try!(visitor.end());
Ok(Map(values))
}
}
impl<K, V> de::Deserialize for Map<K, V>
where K: de::Deserialize + Eq + Ord,
V: de::Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<Map<K, V>, D::Error>
where D: de::Deserializer,
{
deserializer.visit_map(Visitor { marker: PhantomData })
}
}
let mut map = BTreeMap::new();
map.insert("a", Map(BTreeMap::new()));
map.insert("b", Map(BTreeMap::new()));
let map: Map<_, Map<u32, u32>> = Map(map);
test_encode_ok(&[
(
map.clone(),
"{\"a\":{},\"b\":{}}",
),
]);
let s = serde_json::to_string_pretty(&map).unwrap();
assert_eq!(
s,
concat!(
"{\n",
" \"a\": {\n",
" },\n",
" \"b\": {\n",
" }\n",
"}"
)
);
}
#[test]
fn test_deserialize_from_stream() {
use std::net;
use std::io::Read;
use std::thread;
use serde::Deserialize;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Message {
message: String,
}
let l = net::TcpListener::bind("localhost:20000").unwrap();
thread::spawn(|| {
let l = l;
for stream in l.incoming() {
let mut stream = stream.unwrap();
let read_stream = stream.try_clone().unwrap();
let mut de = serde_json::Deserializer::new(read_stream.bytes());
let request = Message::deserialize(&mut de).unwrap();
let response = Message { message: request.message };
serde_json::to_writer(&mut stream, &response).unwrap();
}
});
let mut stream = net::TcpStream::connect("localhost:20000").unwrap();
let request = Message { message: "hi there".to_string() };
serde_json::to_writer(&mut stream, &request).unwrap();
let mut de = serde_json::Deserializer::new(stream.bytes());
let response = Message::deserialize(&mut de).unwrap();
assert_eq!(request, response);
}
+2 -2
View File
@@ -1,7 +1,7 @@
use std::collections::BTreeMap;
use serde::json::value::Value;
use serde::json::builder::{ArrayBuilder, ObjectBuilder};
use serde_json::value::Value;
use serde_json::builder::{ArrayBuilder, ObjectBuilder};
#[test]
fn test_array_builder() {
+90 -31
View File
@@ -1,5 +1,5 @@
use std::collections::BTreeMap;
use serde::json::{self, Value};
use serde_json::{self, Value};
macro_rules! btreemap {
() => {
@@ -131,24 +131,43 @@ enum Lifetimes<'a> {
NoLifetimeMap { a: i32 },
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct GenericStruct<T> {
x: T,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct GenericNewtypeStruct<T>(T);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct GenericTupleStruct<T, U>(T, U);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub enum GenericEnum<T, U> {
Unit,
Newtype(T),
Seq(T, U),
Map { x: T, y: U },
}
#[test]
fn test_named_unit() {
let named_unit = NamedUnit;
assert_eq!(
json::to_string(&named_unit).unwrap(),
serde_json::to_string(&named_unit).unwrap(),
"null".to_string()
);
assert_eq!(
json::to_value(&named_unit),
serde_json::to_value(&named_unit),
Value::Null
);
let v: NamedUnit = json::from_str("null").unwrap();
let v: NamedUnit = serde_json::from_str("null").unwrap();
assert_eq!(v, named_unit);
let v: NamedUnit = json::from_value(Value::Null).unwrap();
let v: NamedUnit = serde_json::from_value(Value::Null).unwrap();
assert_eq!(v, named_unit);
}
@@ -160,25 +179,25 @@ fn test_ser_named_tuple() {
let named_tuple = SerNamedTuple(&a, &mut b, c);
assert_eq!(
json::to_string(&named_tuple).unwrap(),
serde_json::to_string(&named_tuple).unwrap(),
"[5,6,7]"
);
assert_eq!(
json::to_value(&named_tuple),
serde_json::to_value(&named_tuple),
Value::Array(vec![Value::U64(5), Value::U64(6), Value::U64(7)])
);
}
#[test]
fn test_de_named_tuple() {
let v: DeNamedTuple<i32, i32, i32> = json::from_str("[1,2,3]").unwrap();
let v: DeNamedTuple<i32, i32, i32> = serde_json::from_str("[1,2,3]").unwrap();
assert_eq!(
v,
DeNamedTuple(1, 2, 3)
);
let v: Value = json::from_str("[1,2,3]").unwrap();
let v: Value = serde_json::from_str("[1,2,3]").unwrap();
assert_eq!(
v,
Value::Array(vec![
@@ -201,12 +220,12 @@ fn test_ser_named_map() {
};
assert_eq!(
json::to_string(&named_map).unwrap(),
serde_json::to_string(&named_map).unwrap(),
"{\"a\":5,\"b\":6,\"c\":7}"
);
assert_eq!(
json::to_value(&named_map),
serde_json::to_value(&named_map),
Value::Object(btreemap![
"a".to_string() => Value::U64(5),
"b".to_string() => Value::U64(6),
@@ -223,12 +242,12 @@ fn test_de_named_map() {
c: 7,
};
let v2: DeNamedMap<i32, i32, i32> = json::from_str(
let v2: DeNamedMap<i32, i32, i32> = serde_json::from_str(
"{\"a\":5,\"b\":6,\"c\":7}"
).unwrap();
assert_eq!(v, v2);
let v2 = json::from_value(Value::Object(btreemap![
let v2 = serde_json::from_value(Value::Object(btreemap![
"a".to_string() => Value::U64(5),
"b".to_string() => Value::U64(6),
"c".to_string() => Value::U64(7)
@@ -239,12 +258,12 @@ fn test_de_named_map() {
#[test]
fn test_ser_enum_unit() {
assert_eq!(
json::to_string(&SerEnum::Unit::<u32, u32, u32>).unwrap(),
serde_json::to_string(&SerEnum::Unit::<u32, u32, u32>).unwrap(),
"{\"Unit\":[]}"
);
assert_eq!(
json::to_value(&SerEnum::Unit::<u32, u32, u32>),
serde_json::to_value(&SerEnum::Unit::<u32, u32, u32>),
Value::Object(btreemap!(
"Unit".to_string() => Value::Array(vec![]))
)
@@ -261,7 +280,7 @@ fn test_ser_enum_seq() {
//let f = 6;
assert_eq!(
json::to_string(&SerEnum::Seq(
serde_json::to_string(&SerEnum::Seq(
a,
b,
&c,
@@ -273,7 +292,7 @@ fn test_ser_enum_seq() {
);
assert_eq!(
json::to_value(&SerEnum::Seq(
serde_json::to_value(&SerEnum::Seq(
a,
b,
&c,
@@ -304,7 +323,7 @@ fn test_ser_enum_map() {
//let f = 6;
assert_eq!(
json::to_string(&SerEnum::Map {
serde_json::to_string(&SerEnum::Map {
a: a,
b: b,
c: &c,
@@ -316,7 +335,7 @@ fn test_ser_enum_map() {
);
assert_eq!(
json::to_value(&SerEnum::Map {
serde_json::to_value(&SerEnum::Map {
a: a,
b: b,
c: &c,
@@ -339,13 +358,13 @@ fn test_ser_enum_map() {
#[test]
fn test_de_enum_unit() {
let v: DeEnum<_, _, _> = json::from_str("{\"Unit\":[]}").unwrap();
let v: DeEnum<_, _, _> = serde_json::from_str("{\"Unit\":[]}").unwrap();
assert_eq!(
v,
DeEnum::Unit::<u32, u32, u32>
);
let v: DeEnum<_, _, _> = json::from_value(Value::Object(btreemap!(
let v: DeEnum<_, _, _> = serde_json::from_value(Value::Object(btreemap!(
"Unit".to_string() => Value::Array(vec![]))
)).unwrap();
assert_eq!(
@@ -363,7 +382,7 @@ fn test_de_enum_seq() {
let e = 5;
//let f = 6;
let v: DeEnum<_, _, _> = json::from_str("{\"Seq\":[1,2,3,5]}").unwrap();
let v: DeEnum<_, _, _> = serde_json::from_str("{\"Seq\":[1,2,3,5]}").unwrap();
assert_eq!(
v,
DeEnum::Seq(
@@ -376,7 +395,7 @@ fn test_de_enum_seq() {
)
);
let v: DeEnum<_, _, _> = json::from_value(Value::Object(btreemap!(
let v: DeEnum<_, _, _> = serde_json::from_value(Value::Object(btreemap!(
"Seq".to_string() => Value::Array(vec![
Value::U64(1),
Value::U64(2),
@@ -408,7 +427,7 @@ fn test_de_enum_map() {
let e = 5;
//let f = 6;
let v: DeEnum<_, _, _> = json::from_str(
let v: DeEnum<_, _, _> = serde_json::from_str(
"{\"Map\":{\"a\":1,\"b\":2,\"c\":3,\"e\":5}}"
).unwrap();
assert_eq!(
@@ -423,7 +442,7 @@ fn test_de_enum_map() {
}
);
let v: DeEnum<_, _, _> = json::from_value(Value::Object(btreemap!(
let v: DeEnum<_, _, _> = serde_json::from_value(Value::Object(btreemap!(
"Map".to_string() => Value::Object(btreemap![
"a".to_string() => Value::U64(1),
"b".to_string() => Value::U64(2),
@@ -452,26 +471,66 @@ fn test_lifetimes() {
let value = 5;
let lifetime = Lifetimes::LifetimeSeq(&value);
assert_eq!(
json::to_string(&lifetime).unwrap(),
"{\"LifetimeSeq\":[5]}"
serde_json::to_string(&lifetime).unwrap(),
"{\"LifetimeSeq\":5}"
);
let lifetime = Lifetimes::NoLifetimeSeq(5);
assert_eq!(
json::to_string(&lifetime).unwrap(),
"{\"NoLifetimeSeq\":[5]}"
serde_json::to_string(&lifetime).unwrap(),
"{\"NoLifetimeSeq\":5}"
);
let value = 5;
let lifetime = Lifetimes::LifetimeMap { a: &value };
assert_eq!(
json::to_string(&lifetime).unwrap(),
serde_json::to_string(&lifetime).unwrap(),
"{\"LifetimeMap\":{\"a\":5}}"
);
let lifetime = Lifetimes::NoLifetimeMap { a: 5 };
assert_eq!(
json::to_string(&lifetime).unwrap(),
serde_json::to_string(&lifetime).unwrap(),
"{\"NoLifetimeMap\":{\"a\":5}}"
);
}
macro_rules! declare_tests {
($($name:ident { $($ty:ty : $value:expr => $str:expr,)+ })+) => {
$(
#[test]
fn $name() {
$(
let value: $ty = $value;
let string = serde_json::to_string(&value).unwrap();
assert_eq!(string, $str);
let expected: $ty = serde_json::from_str(&string).unwrap();
assert_eq!(value, expected);
)+
}
)+
}
}
declare_tests! {
test_generic_struct {
GenericStruct<u32> : GenericStruct { x: 5 } => "{\"x\":5}",
}
test_generic_newtype_struct {
GenericNewtypeStruct<u32> : GenericNewtypeStruct(5) => "5",
}
test_generic_tuple_struct {
GenericTupleStruct<u32, u32> : GenericTupleStruct(5, 6) => "[5,6]",
}
test_generic_enum_newtype {
GenericEnum<u32, u32> : GenericEnum::Newtype(5) => "{\"Newtype\":5}",
}
test_generic_enum_seq {
GenericEnum<u32, u32> : GenericEnum::Seq(5, 6) => "{\"Seq\":[5,6]}",
}
test_generic_enum_map {
GenericEnum<u32, u32> : GenericEnum::Map { x: 5, y: 6 } => "{\"Map\":{\"x\":5,\"y\":6}}",
}
}
+78 -29
View File
@@ -24,17 +24,19 @@ pub enum Token<'a> {
Option(bool),
Unit,
NamedUnit(&'a str),
UnitStruct(&'a str),
EnumUnit(&'a str, &'a str),
EnumNewtype(&'a str, &'a str),
SeqStart(Option<usize>),
NamedSeqStart(&'a str, Option<usize>),
TupleStructStart(&'a str, Option<usize>),
EnumSeqStart(&'a str, &'a str, Option<usize>),
SeqSep,
SeqEnd,
MapStart(Option<usize>),
NamedMapStart(&'a str, Option<usize>),
StructStart(&'a str, Option<usize>),
EnumMapStart(&'a str, &'a str, Option<usize>),
MapSep,
MapEnd,
@@ -80,13 +82,31 @@ impl<'a> Serializer for AssertSerializer<'a> {
Ok(())
}
fn visit_named_unit(&mut self, name: &str) -> Result<(), ()> {
assert_eq!(self.iter.next().unwrap(), Token::NamedUnit(name));
fn visit_newtype_variant<T>(&mut self,
name: &str,
_variant_index: usize,
variant: &str,
value: T) -> Result<(), ()>
where T: Serialize,
{
assert_eq!(self.iter.next(), Some(Token::EnumNewtype(name, variant)));
value.serialize(self)
}
fn visit_unit_struct(&mut self, name: &str) -> Result<(), ()> {
assert_eq!(self.iter.next().unwrap(), Token::UnitStruct(name));
Ok(())
}
fn visit_enum_unit(&mut self, name: &str, variant: &str) -> Result<(), ()> {
assert_eq!(self.iter.next().unwrap(), Token::EnumUnit(name, variant));
fn visit_unit_variant(&mut self,
name: &str,
_variant_index: usize,
variant: &str) -> Result<(), ()> {
assert_eq!(
self.iter.next().unwrap(),
Token::EnumUnit(name, variant)
);
Ok(())
}
@@ -188,25 +208,32 @@ impl<'a> Serializer for AssertSerializer<'a> {
self.visit_sequence(visitor)
}
fn visit_named_seq<V>(&mut self, name: &str, visitor: V) -> Result<(), ()>
fn visit_tuple_struct<V>(&mut self, name: &str, visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let len = visitor.len();
assert_eq!(self.iter.next().unwrap(), Token::NamedSeqStart(name, len));
assert_eq!(
self.iter.next().unwrap(),
Token::TupleStructStart(name, len)
);
self.visit_sequence(visitor)
}
fn visit_enum_seq<V>(&mut self,
name: &str,
variant: &str,
visitor: V) -> Result<(), ()>
fn visit_tuple_variant<V>(&mut self,
name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let len = visitor.len();
assert_eq!(self.iter.next().unwrap(), Token::EnumSeqStart(name, variant, len));
assert_eq!(
self.iter.next().unwrap(),
Token::EnumSeqStart(name, variant, len)
);
self.visit_sequence(visitor)
}
@@ -228,22 +255,32 @@ impl<'a> Serializer for AssertSerializer<'a> {
self.visit_mapping(visitor)
}
fn visit_named_map<V>(&mut self, name: &str, visitor: V) -> Result<(), ()>
fn visit_struct<V>(&mut self, name: &str, visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let len = visitor.len();
assert_eq!(self.iter.next().unwrap(), Token::NamedMapStart(name, len));
assert_eq!(
self.iter.next().unwrap(),
Token::StructStart(name, len)
);
self.visit_mapping(visitor)
}
fn visit_enum_map<V>(&mut self, name: &str, variant: &str, visitor: V) -> Result<(), ()>
fn visit_struct_variant<V>(&mut self,
name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let len = visitor.len();
assert_eq!(self.iter.next().unwrap(), Token::EnumMapStart(name, variant, len));
assert_eq!(
self.iter.next().unwrap(),
Token::EnumMapStart(name, variant, len)
);
self.visit_mapping(visitor)
}
@@ -262,13 +299,13 @@ impl<'a> Serializer for AssertSerializer<'a> {
//////////////////////////////////////////////////////////////////////////
#[derive(Serialize)]
struct NamedUnit;
struct UnitStruct;
#[derive(Serialize)]
struct NamedSeq(i32, i32, i32);
struct TupleStruct(i32, i32, i32);
#[derive(Serialize)]
struct NamedMap {
struct Struct {
a: i32,
b: i32,
c: i32,
@@ -277,6 +314,7 @@ struct NamedMap {
#[derive(Serialize)]
enum Enum {
Unit,
One(i32),
Seq(i32, i32),
Map { a: i32, b: i32 },
}
@@ -356,6 +394,16 @@ declare_tests! {
Token::I32(1),
],
}
test_result {
Ok::<i32, i32>(0) => vec![
Token::EnumNewtype("Result", "Ok"),
Token::I32(0),
],
Err::<i32, i32>(1) => vec![
Token::EnumNewtype("Result", "Err"),
Token::I32(1),
],
}
test_slice {
&[0][..0] => vec![
Token::SeqStart(Some(0)),
@@ -480,12 +528,12 @@ declare_tests! {
Token::MapEnd,
],
}
test_named_unit {
NamedUnit => vec![Token::NamedUnit("NamedUnit")],
test_unit_struct {
UnitStruct => vec![Token::UnitStruct("UnitStruct")],
}
test_named_seq {
NamedSeq(1, 2, 3) => vec![
Token::NamedSeqStart("NamedSeq", Some(3)),
test_tuple_struct {
TupleStruct(1, 2, 3) => vec![
Token::TupleStructStart("TupleStruct", Some(3)),
Token::SeqSep,
Token::I32(1),
@@ -497,9 +545,9 @@ declare_tests! {
Token::SeqEnd,
],
}
test_named_map {
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::NamedMapStart("NamedMap", Some(3)),
test_struct {
Struct { a: 1, b: 2, c: 3 } => vec![
Token::StructStart("Struct", Some(3)),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
@@ -516,6 +564,7 @@ declare_tests! {
}
test_enum {
Enum::Unit => vec![Token::EnumUnit("Enum", "Unit")],
Enum::One(42) => vec![Token::EnumNewtype("Enum", "One"), Token::I32(42)],
Enum::Seq(1, 2) => vec![
Token::EnumSeqStart("Enum", "Seq", Some(2)),
Token::SeqSep,