Compare commits

..

1 Commits

Author SHA1 Message Date
Erick Tryzelaar 37c0ad19bb Version bump 2015-06-25 16:10:52 -07:00
62 changed files with 8695 additions and 8900 deletions
+1 -2
View File
@@ -1,3 +1,2 @@
Cargo.lock
target target
*.sw[po] Cargo.lock
+30 -32
View File
@@ -1,36 +1,34 @@
language: rust language: rust
rust: rust:
- stable - stable
- beta - beta
- nightly - nightly
- 1.5.0
addons:
apt:
packages:
- libcurl4-openssl-dev
- libelf-dev
- libdw-dev
- binutils-dev
before_script:
- pip install 'travis-cargo<0.2' --user
- export PATH=$HOME/.local/bin:$PATH
script:
- (cd serde && travis-cargo build)
- (cd serde && travis-cargo test)
- (cd serde && travis-cargo --only nightly test -- --features nightly-testing)
- (cd serde_tests && travis-cargo test)
- (cd serde_tests && travis-cargo --only nightly test -- --features nightly-testing)
- (cd serde_macros && travis-cargo --only nightly test -- --features nightly-testing)
- (cd serde_macros && travis-cargo --only nightly bench -- --features nightly-testing)
- (cd serde && travis-cargo --only stable doc)
- (cd serde_codegen && travis-cargo --only stable doc)
- (cd serde_macros && travis-cargo --only nightly doc)
after_success:
- (cd serde && travis-cargo --only stable doc-upload)
#- (cd serde_codegen && travis-cargo --only stable doc-upload)
#- (cd serde_macros && travis-cargo --only nightly doc-upload)
- (cd serde_tests && travis-cargo coveralls --no-sudo)
env: env:
global: global:
- TRAVIS_CARGO_NIGHTLY_FEATURE="" secure: HO41LMpMXkF2In9+1sxWVu7fgolL+y9+4Q5PI6wZX2L5pDwpPJCjxaQarQXCEnoIxED1PlP03JuF7ULNz0zw1ylYhAOfOSdkxFZRnE2wMZqq6qvXBHwyMiDrAociIzoPKSGv7JVrKPsjsnd+96K6xxueIodQZrmAdyq7N/M82Mc=
- secure: Jcd11Jy0xLyacBUB+oKOaxKBm9iZNInenRDtNBY8GKOtqF5fHUfEjgDf538hwRl5L0FP7DLr8oK0IHmzA7lPjJxlzoKVKV3IM7bRZEYzW5DMonf/lcliuGte7SH0NVFhifM87T8HI2hjGdAb+7+m34siBR7M3AY/XjLInrvUFvY= matrix:
- CRATE=serde_tests TARGET=test
matrix:
include:
- rust: nightly
env: CRATE=serde_macros TARGET=test
- rust: nightly
env: CRATE=serde_macros TARGET=bench
- rust: nightly
env: CRATE=serde_tests TARGET=bench
script:
- (cd $CRATE && cargo $TARGET)
after_success: |
[ $TRAVIS_BRANCH = "master" ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
mkdir -p target/doc &&
(cd serde && cargo doc --no-deps) &&
(cd serde_codegen && cargo doc --no-deps) &&
(cd serde_macros && 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 &&
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 &&
ghp-import -n target/doc &&
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
+95 -407
View File
@@ -1,10 +1,8 @@
Serde Rust Serialization Framework Serde Rust Serialization Framework
================================== ==================================
[![Build Status](https://api.travis-ci.org/serde-rs/serde.svg?branch=master)](https://travis-ci.org/serde-rs/serde) [![Build Status](https://api.travis-ci.org/serde-rs/serde.png?branch=master)](https://travis-ci.org/serde-rs/serde)
[![Coverage Status](https://coveralls.io/repos/serde-rs/serde/badge.svg?branch=master&service=github)](https://coveralls.io/github/serde-rs/serde?branch=master)
[![Latest Version](https://img.shields.io/crates/v/serde.svg)](https://crates.io/crates/serde) [![Latest Version](https://img.shields.io/crates/v/serde.svg)](https://crates.io/crates/serde)
[![Clippy Linting Result](http://clippy.bashy.io/github/serde-rs/serde/master/badge.svg)](http://clippy.bashy.io/github/serde-rs/serde/master/log)
Serde is a powerful framework that enables serialization libraries to Serde is a powerful framework that enables serialization libraries to
generically serialize Rust data structures without the overhead of runtime type generically serialize Rust data structures without the overhead of runtime type
@@ -12,244 +10,76 @@ information. In many situations, the handshake protocol between serializers and
serializees can be completely optimized away, leaving Serde to perform roughly serializees can be completely optimized away, leaving Serde to perform roughly
the same speed as a hand written serializer for a specific type. the same speed as a hand written serializer for a specific type.
Documentation is available at: Documentation is available at http://serde-rs.github.io/serde/serde
* [serde](https://serde-rs.github.io/serde/serde/index.html) Making a Type Serializable
==========================
Using Serde with Nightly Rust and serde\_macros 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
Here is a simple example that demonstrates how to use Serde by serializing and [Serialize](http://serde-rs.github.io/serde/serde/ser/trait.Serialize.html)
deserializing to JSON. Serde comes with some powerful code generation libraries and
that work with Stable and Nightly Rust that eliminate much of the complexity of [Deserialize](http://serde-rs.github.io/serde/serde/de/trait.Deserialize.html)
hand rolling serialization and deserialization for a given type. First lets see for the annotated type:
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 ```rust
#![feature(custom_derive, plugin)] #![feature(custom_derive, plugin)]
#![plugin(serde_macros)] #![plugin(serde_macros)]
extern crate serde_json; extern crate serde;
#[derive(Serialize, Deserialize, Debug)] ...
#[derive(Serialize, Deserialize)]
struct Point { struct Point {
x: i32, x: i32,
y: i32, y: i32,
} }
fn main() {
let point = Point { x: 1, y: 2 };
let serialized = serde_json::to_string(&point).unwrap();
println!("{}", serialized);
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
println!("{:?}", deserialized);
}
``` ```
When run, it produces: 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:
``` ```rust
% cargo run use serde::json;
{"x":1,"y":2}
Point { x: 1, y: 2 }
```
Using Serde with Stable Rust, syntex, and serde\_codegen
========================================================
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/serde-rs/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,ignore
extern crate serde;
extern crate serde_json;
include!(concat!(env!("OUT_DIR"), "/main.rs"));
```
`src/main.rs.in`:
```rust,ignore
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
let serialized = serde_json::to_string(&point).unwrap();
println!("{}", serialized);
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
println!("{:?}", deserialized);
}
```
`build.rs`
```rust,ignore
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();
}
```
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,ignore
#[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,ignore
#![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.
Then to run with stable:
```
% cargo build
... ...
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();
``` ```
Or with nightly: [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):
``` ```rust
% cargo build --features nightly --no-default-features let point = Point { x: 1, y: 2 };
... let point_value = json::to_value(&point).unwrap();
println!("{}", point_value.find("x")); // prints: Some(1)
let deserialize_point: Point = json::from_value(point_value).unwrap();
``` ```
Serialization without Macros Serialization without Macros
@@ -257,9 +87,9 @@ Serialization without Macros
Under the covers, Serde extensively uses the Visitor pattern to thread state Under the covers, Serde extensively uses the Visitor pattern to thread state
between the between the
[Serializer](http://serde-rs.github.io/serde/serde/serde/ser/trait.Serializer.html) [Serializer](http://serde-rs.github.io/serde/serde/ser/trait.Serializer.html)
and and
[Serialize](http://serde-rs.github.io/serde/serde/serde/ser/trait.Serialize.html) [Serialize](http://serde-rs.github.io/serde/serde/ser/trait.Serialize.html)
without the two having specific information about each other's concrete type. without the two having specific information about each other's concrete type.
This has many of the same benefits as frameworks that use runtime type This has many of the same benefits as frameworks that use runtime type
information without the overhead. In fact, when compiling with optimizations, information without the overhead. In fact, when compiling with optimizations,
@@ -268,27 +98,27 @@ nearly as fast as a hand written serializer format for a specific type.
To see it in action, lets look at how a simple type like `i32` is serialized. To see it in action, lets look at how a simple type like `i32` is serialized.
The The
[Serializer](http://serde-rs.github.io/serde/serde/serde/ser/trait.Serializer.html) [Serializer](http://serde-rs.github.io/serde/serde/ser/trait.Serializer.html)
is threaded through the type: is threaded through the type:
```rust,ignore ```rust
impl serde::Serialize for i32 { impl serde::Serialize for i32 {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: serde::Serializer, where S: serde::Serializer,
{ {
serializer.serialize_i32(*self) serializer.visit_i32(*self)
} }
} }
``` ```
As you can see it's pretty simple. More complex types like `BTreeMap` need to As you can see it's pretty simple. More complex types like `BTreeMap` need to
pass a pass a
[MapVisitor](http://serde-rs.github.io/serde/serde/serde/ser/trait.MapVisitor.html) [MapVisitor](http://serde-rs.github.io/serde/serde/ser/trait.MapVisitor.html)
to the to the
[Serializer](http://serde-rs.github.io/serde/serde/serde/ser/trait.Serializer.html) [Serializer](http://serde-rs.github.io/serde/serde/ser/trait.Serializer.html)
in order to walk through the type: in order to walk through the type:
```rust,ignore ```rust
impl<K, V> Serialize for BTreeMap<K, V> impl<K, V> Serialize for BTreeMap<K, V>
where K: Serialize + Ord, where K: Serialize + Ord,
V: Serialize, V: Serialize,
@@ -297,7 +127,7 @@ impl<K, V> Serialize for BTreeMap<K, V>
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
serializer.serialize_map(MapIteratorVisitor::new(self.iter(), Some(self.len()))) serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
} }
} }
@@ -329,7 +159,7 @@ impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
{ {
match self.iter.next() { match self.iter.next() {
Some((key, value)) => { Some((key, value)) => {
let value = try!(serializer.serialize_map_elt(key, value)); let value = try!(serializer.visit_map_elt(key, value));
Ok(Some(value)) Ok(Some(value))
} }
None => Ok(None) None => Ok(None)
@@ -344,13 +174,10 @@ impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
``` ```
Serializing structs follow this same pattern. In fact, structs are represented Serializing structs follow this same pattern. In fact, structs are represented
as a named map. Its visitor uses a simple state machine to iterate through all as a named map. It's visitor uses a simple state machine to iterate through all
the fields: the fields:
```rust ```rust
extern crate serde;
extern crate serde_json;
struct Point { struct Point {
x: i32, x: i32,
y: i32, y: i32,
@@ -360,7 +187,7 @@ impl serde::Serialize for Point {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: serde::Serializer where S: serde::Serializer
{ {
serializer.serialize_struct("Point", PointMapVisitor { serializer.visit_named_map("Point", PointMapVisitor {
value: self, value: self,
state: 0, state: 0,
}) })
@@ -379,11 +206,11 @@ impl<'a> serde::ser::MapVisitor for PointMapVisitor<'a> {
match self.state { match self.state {
0 => { 0 => {
self.state += 1; self.state += 1;
Ok(Some(try!(serializer.serialize_struct_elt("x", &self.value.x)))) Ok(Some(try!(serializer.visit_map_elt("x", &self.value.x))))
} }
1 => { 1 => {
self.state += 1; self.state += 1;
Ok(Some(try!(serializer.serialize_struct_elt("y", &self.value.y)))) Ok(Some(try!(serializer.visit_map_elt("y", &self.value.y))))
} }
_ => { _ => {
Ok(None) Ok(None)
@@ -391,13 +218,6 @@ impl<'a> serde::ser::MapVisitor for PointMapVisitor<'a> {
} }
} }
} }
fn main() {
let point = Point { x: 1, y: 2 };
let serialized = serde_json::to_string(&point).unwrap();
println!("{}", serialized);
}
``` ```
Deserialization without Macros Deserialization without Macros
@@ -405,19 +225,19 @@ Deserialization without Macros
Deserialization is a little more complicated since there's a bit more error Deserialization is a little more complicated since there's a bit more error
handling that needs to occur. Let's start with the simple `i32` handling that needs to occur. Let's start with the simple `i32`
[Deserialize](http://serde-rs.github.io/serde/serde/serde/de/trait.Deserialize.html) [Deserialize](http://serde-rs.github.io/serde/serde/de/trait.Deserialize.html)
implementation. It passes a implementation. It passes a
[Visitor](http://serde-rs.github.io/serde/serde/serde/de/trait.Visitor.html) to the [Visitor](http://serde-rs.github.io/serde/serde/de/trait.Visitor.html) to the
[Deserializer](http://serde-rs.github.io/serde/serde/serde/de/trait.Deserializer.html). [Deserializer](http://serde-rs.github.io/serde/serde/de/trait.Deserializer.html).
The [Visitor](http://serde-rs.github.io/serde/serde/serde/de/trait.Visitor.html) The [Visitor](http://serde-rs.github.io/serde/serde/de/trait.Visitor.html)
can create the `i32` from a variety of different types: can create the `i32` from a variety of different types:
```rust,ignore ```rust
impl Deserialize for i32 { impl Deserialize for i32 {
fn deserialize<D>(deserializer: &mut D) -> Result<i32, D::Error> fn deserialize<D>(deserializer: &mut D) -> Result<i32, D::Error>
where D: serde::Deserializer, where D: serde::Deserializer,
{ {
deserializer.deserialize(I32Visitor) deserializer.visit(I32Visitor)
} }
} }
@@ -426,7 +246,7 @@ struct I32Visitor;
impl serde::de::Visitor for I32Visitor { impl serde::de::Visitor for I32Visitor {
type Value = i32; type Value = i32;
fn visit_i16<E>(&mut self, value: i16) -> Result<i32, E> fn visit_i16<E>(&mut self, value: i16) -> Result<i16, E>
where E: Error, where E: Error,
{ {
self.visit_i32(value as i32) self.visit_i32(value as i32)
@@ -444,18 +264,18 @@ impl serde::de::Visitor for I32Visitor {
Since it's possible for this type to get passed an unexpected type, we need a Since it's possible for this type to get passed an unexpected type, we need a
way to error out. This is done by way of the way to error out. This is done by way of the
[Error](http://serde-rs.github.io/serde/serde/serde/de/trait.Error.html) trait, [Error](http://serde-rs.github.io/serde/serde/de/trait.Error.html) trait,
which allows a which allows a
[Deserialize](http://serde-rs.github.io/serde/serde/serde/de/trait.Deserialize.html) [Deserialize](http://serde-rs.github.io/serde/serde/de/trait.Deserialize.html)
to generate an error for a few common error conditions. Here's how it could be used: to generate an error for a few common error conditions. Here's how it could be used:
```rust,ignore ```rust
... ...
fn visit_string<E>(&mut self, _: String) -> Result<i32, E> fn visit_string<E>(&mut self, _: String) -> Result<i32, E>
where E: Error, where E: Error,
{ {
Err(serde::de::Error::custom("expect a string")) Err(serde::de::Error::syntax_error())
} }
... ...
@@ -463,11 +283,11 @@ to generate an error for a few common error conditions. Here's how it could be u
``` ```
Maps follow a similar pattern as before, and use a Maps follow a similar pattern as before, and use a
[MapVisitor](http://serde-rs.github.io/serde/serde/serde/de/trait.MapVisitor.html) [MapVisitor](http://serde-rs.github.io/serde/serde/de/trait.MapVisitor.html)
to walk through the values generated by the to walk through the values generated by the
[Deserializer](http://serde-rs.github.io/serde/serde/serde/de/trait.Deserializer.html). [Deserializer](http://serde-rs.github.io/serde/serde/de/trait.Deserializer.html).
```rust,ignore ```rust
impl<K, V> serde::Deserialize for BTreeMap<K, V> impl<K, V> serde::Deserialize for BTreeMap<K, V>
where K: serde::Deserialize + Eq + Ord, where K: serde::Deserialize + Eq + Ord,
V: serde::Deserialize, V: serde::Deserialize,
@@ -475,7 +295,7 @@ impl<K, V> serde::Deserialize for BTreeMap<K, V>
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeMap<K, V>, D::Error> fn deserialize<D>(deserializer: &mut D) -> Result<BTreeMap<K, V>, D::Error>
where D: serde::Deserializer, where D: serde::Deserializer,
{ {
deserializer.deserialize(BTreeMapVisitor::new()) deserializer.visit(BTreeMapVisitor::new())
} }
} }
@@ -517,6 +337,7 @@ impl<K, V> serde::de::Visitor for BTreeMapVisitor<K, V>
Ok(values) Ok(values)
} }
} }
``` ```
Deserializing structs goes a step further in order to support not allocating a Deserializing structs goes a step further in order to support not allocating a
@@ -525,15 +346,6 @@ deserializes an enum variant from a string. So for our `Point` example from
before, we need to generate: before, we need to generate:
```rust ```rust
extern crate serde;
extern crate serde_json;
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
enum PointField { enum PointField {
X, X,
Y, Y,
@@ -543,32 +355,35 @@ impl serde::Deserialize for PointField {
fn deserialize<D>(deserializer: &mut D) -> Result<PointField, D::Error> fn deserialize<D>(deserializer: &mut D) -> Result<PointField, D::Error>
where D: serde::de::Deserializer where D: serde::de::Deserializer
{ {
struct PointFieldVisitor; struct FieldVisitor;
impl serde::de::Visitor for PointFieldVisitor { impl serde::de::Visitor for FieldVisitor {
type Value = PointField; type Value = Field;
fn visit_str<E>(&mut self, value: &str) -> Result<PointField, E> fn visit_str<E>(&mut self, value: &str) -> Result<PointField, E>
where E: serde::de::Error where E: serde::de::Error
{ {
match value { match value {
"x" => Ok(PointField::X), "x" => Ok(Field::X),
"y" => Ok(PointField::Y), "y" => Ok(Field::Y),
_ => Err(serde::de::Error::custom("expected x or y")), _ => Err(serde::de::Error::syntax_error()),
} }
} }
} }
deserializer.deserialize(PointFieldVisitor) deserializer.visit(FieldVisitor)
} }
} }
```
This is then used in our actual deserializer:
```rust
impl serde::Deserialize for Point { impl serde::Deserialize for Point {
fn deserialize<D>(deserializer: &mut D) -> Result<Point, D::Error> fn deserialize<D>(deserializer: &mut D) -> Result<Point, D::Error>
where D: serde::de::Deserializer where D: serde::de::Deserializer
{ {
static FIELDS: &'static [&'static str] = &["x", "y"]; deserializer.visit_named_map("Point", PointVisitor)
deserializer.deserialize_struct("Point", FIELDS, PointVisitor)
} }
} }
@@ -585,8 +400,8 @@ impl serde::de::Visitor for PointVisitor {
loop { loop {
match try!(visitor.visit_key()) { match try!(visitor.visit_key()) {
Some(PointField::X) => { x = Some(try!(visitor.visit_value())); } Some(Field::X) => { x = Some(try!(visitor.visit_value())); }
Some(PointField::Y) => { y = Some(try!(visitor.visit_value())); } Some(Field::Y) => { y = Some(try!(visitor.visit_value())); }
None => { break; } None => { break; }
} }
} }
@@ -606,131 +421,4 @@ impl serde::de::Visitor for PointVisitor {
Ok(Point{ x: x, y: y }) Ok(Point{ x: x, y: y })
} }
} }
fn main() {
let serialized = "{\"x\":1,\"y\":2}";
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
println!("{:?}", deserialized);
}
``` ```
Design Considerations and tradeoffs for Serializers and Deserializers
=====================================================================
Serde serialization and deserialization implementations are written in such a
way that they err on being able to represent more values, and also provide
better error messages when they are passed an incorrect type to deserialize
from. For example, by default, it is a syntax error to deserialize a `String`
into an `Option<String>`. This is implemented such that it is possible to
distinguish between the values `None` and `Some(())`, if the serialization
format supports option types.
However, many formats do not have option types, and represents optional values
as either a `null`, or some other value. Serde `Serializer`s and
`Deserializer`s can opt-in support for this. For serialization, this is pretty
easy. Simply implement these methods:
```rust,ignore
...
fn visit_none(&mut self) -> Result<(), Self::Error> {
self.visit_unit()
}
fn visit_some<T>(&mut self, value: T) -> Result<(), Self::Error> {
value.serialize(self)
}
...
```
For deserialization, this can be implemented by way of the
`Deserializer::visit_option` hook, which presumes that there is some ability to peek at what is the
next value in the serialized token stream. This following example is from
[serde_tests::TokenDeserializer](https://github.com/serde-rs/serde/blob/master/serde_tests/tests/token.rs#L435-L454),
where it checks to see if the next value is an `Option`, a `()`, or some other
value:
```rust,ignore
...
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.tokens.peek() {
Some(&Token::Option(false)) => {
self.tokens.next();
visitor.visit_none()
}
Some(&Token::Option(true)) => {
self.tokens.next();
visitor.visit_some(self)
}
Some(&Token::Unit) => {
self.tokens.next();
visitor.visit_none()
}
Some(_) => visitor.visit_some(self),
None => Err(Error::EndOfStreamError),
}
}
...
```
Annotations
===========
`serde_codegen` and `serde_macros` support annotations that help to customize
how types are serialized. Here are the supported annotations:
Container Annotations:
| Annotation | Function |
| ---------- | -------- |
| `#[serde(rename="name")]` | Serialize and deserialize this container with the given name |
| `#[serde(rename(serialize="name1"))]` | Serialize this container with the given name |
| `#[serde(rename(deserialize="name1"))]` | Deserialize this container with the given name |
| `#[serde(deny_unknown_fields)]` | Always error during serialization when encountering unknown fields. When absent, unknown fields are ignored for self-describing formats like JSON. |
Variant Annotations:
| Annotation | Function |
| ---------- | -------- |
| `#[serde(rename="name")]` | Serialize and deserialize this variant with the given name |
| `#[serde(rename(serialize="name1"))]` | Serialize this variant with the given name |
| `#[serde(rename(deserialize="name1"))]` | Deserialize this variant with the given name |
Field Annotations:
| Annotation | Function |
| ---------- | -------- |
| `#[serde(rename="name")]` | Serialize and deserialize this field with the given name |
| `#[serde(rename(serialize="name1"))]` | Serialize this field with the given name |
| `#[serde(rename(deserialize="name1"))]` | Deserialize this field with the given name |
| `#[serde(default)]` | If the value is not specified, use the `Default::default()` |
| `#[serde(default="$path")]` | Call the path to a function `fn() -> T` to build the value |
| `#[serde(skip_serializing)]` | Do not serialize this value |
| `#[serde(skip_deserializing)]` | Always use `Default::default()` or `#[serde(default="$path")]` instead of deserializing this value |
| `#[serde(skip_serializing_if="$path")]` | Do not serialize this value if this function `fn(&T) -> bool` returns `true` |
| `#[serde(serialize_with="$path")]` | Call a function `fn<S>(&T, &mut S) -> Result<(), S::Error> where S: Serializer` to serialize this value of type `T` |
| `#[serde(deserialize_with="$path")]` | Call a function `fn<D>(&mut D) -> Result<T, D::Error> where D: Deserializer` to deserialize this value of type `T` |
Upgrading from Serde 0.6
========================
* `#[serde(skip_serializing_if_none)]` was replaced with `#[serde(skip_serializing_if="Option::is_none")]`.
* `#[serde(skip_serializing_if_empty)]` was replaced with `#[serde(skip_serializing_if="Vec::is_empty")]`.
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/dtolnay/serde-yaml) |
-2
View File
@@ -1,2 +0,0 @@
target
Cargo.lock
-18
View File
@@ -1,18 +0,0 @@
[package]
name = "serde-syntex-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 = "^0.7.5", optional = true }
syntex = "^0.32.0"
[dependencies]
serde = "^0.7.5"
serde_json = "^0.7.0"
serde_macros = { version = "^0.7.5", optional = true }
-20
View File
@@ -1,20 +0,0 @@
This example demonstrates how to use Serde with Syntex. On stable or nightly
with Syntex, it can be built with:
```
% multirust run stable cargo run
Running `target/debug/serde-syntex-example`
{"x":1,"y":2}
Point { x: 1, y: 2 }
% multirust run nightly cargo run
Running `target/debug/serde-syntex-example`
{"x":1,"y":2}
Point { x: 1, y: 2 }
```
On nightly, it can use a plugin with:
```
% multirust run nightly cargo run --features nightly --no-default-features
```
-29
View File
@@ -1,29 +0,0 @@
#[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();
}
-11
View File
@@ -1,11 +0,0 @@
#![cfg_attr(nightly, feature(custom_derive, plugin))]
#![cfg_attr(nightly, 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"));
@@ -1,16 +0,0 @@
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
let serialized = serde_json::to_string(&point).unwrap();
println!("{}", serialized);
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
println!("{:?}", deserialized);
}
+4 -8
View File
@@ -1,17 +1,13 @@
[package] [package]
name = "serde" name = "serde"
version = "0.7.5" version = "0.4.2"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
repository = "https://github.com/serde-rs/serde" repository = "https://github.com/serde-rs/serde"
documentation = "https://serde-rs.github.io/serde/serde/" documentation = "http://serde-rs.github.io/serde/serde"
readme = "../README.md" readme = "../README.md"
keywords = ["serde", "serialization"] keywords = ["serialization"]
[features]
nightly = []
nightly-testing = ["clippy", "nightly"]
[dependencies] [dependencies]
clippy = { version = "^0.*", optional = true } num = "*"
+94
View File
@@ -0,0 +1,94 @@
use std::cmp;
use std::io;
use std::slice;
trait IntoBufRead {
type IntoBuf: io::BufRead + BufReadExt;
fn into_buf_read(self) -> Self::IntoBuf;
}
trait BufReadExt {
fn get_buf(&self) -> &[u8];
fn read_u8(&mut self) -> io::Result<Option<u8>>;
}
struct SliceReader<'a> {
buf: &'a [u8],
}
impl<'a> io::Read for SliceReader<'a> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let amt = cmp::min(buf.len(), self.buf.len());
let (a, b) = self.buf.split_at(amt);
slice::bytes::copy_memory(buf, a);
*self.buf = b;
Ok(amt)
}
}
impl<'a> io::BufRead for SliceReader<'a> {
fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) }
fn consume(&mut self, amt: usize) { *self.buf = &self.buf[amt..]; }
}
impl<'a> BufReadExt for SliceReader<'a> {
fn get_buf(&self) -> &[u8] { self.buf }
fn read_u8(&mut self) -> io::Result<Option<u8>> {
let byte = self.buf.get(0);
*self.buf = &self.buf[1..];
byte
}
}
struct BufReader<R> {
inner: R,
buf: io::Cursor<Vec<u8>>,
}
impl<R> BufReader<R> where R: io::Read {
fn new(inner: R) -> Self {
BufferedReader::with_capacity(io::DEFAULT_BUF_SIZE, inner)
}
fn new(cap: usize, inner: R) -> Self {
BufferedReader {
inner: inner,
buf: io::Cursor::new(Vec::with_capacity(cap)),
}
}
fn into_inner(self) -> R {
self.inner
}
}
impl<R> Read for BufReader<R> where R: io::Read {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
// If we don't have any buffered data and we're doing a massive read
// (larger than our internal buffer), bypass our internal buffer
// entirely.
if self.buf.get_ref().len() == self.buf.position() as usize &&
buf.len() >= self.buf.get_ref().capacity() {
return self.inner.read(buf);
}
try!(self.fill_buf());
self.buf.read(buf)
}
}
impl<R> BufReadExt for BufReader<R> {
fn get_buf(&self) -> &[u8] {
self.buf.get_ref()
}
fn read_u8(&mut self) -> io::Result<Option<u8>> {
if self.buf.get_ref().len() == self.buf.position() as usize {
}
let byte = self.buf.get(0);
*self.buf = &self.buf[1..];
byte
}
}
+5 -8
View File
@@ -54,27 +54,25 @@ impl<'a> ser::Serialize for Bytes<'a> {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer where S: ser::Serializer
{ {
serializer.serialize_bytes(self.bytes) serializer.visit_bytes(self.bytes)
} }
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// `ByteBuf` wraps a `Vec<u8>` and serializes as a byte array. /// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
#[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] #[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf { pub struct ByteBuf {
bytes: Vec<u8>, bytes: Vec<u8>,
} }
impl ByteBuf { impl ByteBuf {
/// Construct a new, empty `ByteBuf`.
pub fn new() -> Self { pub fn new() -> Self {
ByteBuf { ByteBuf {
bytes: Vec::new(), bytes: Vec::new(),
} }
} }
/// Construct a new, empty `ByteBuf` with the specified capacity.
pub fn with_capacity(cap: usize) -> Self { pub fn with_capacity(cap: usize) -> Self {
ByteBuf { ByteBuf {
bytes: Vec::with_capacity(cap) bytes: Vec::with_capacity(cap)
@@ -140,11 +138,10 @@ impl ser::Serialize for ByteBuf {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer where S: ser::Serializer
{ {
serializer.serialize_bytes(&self) serializer.visit_bytes(&self)
} }
} }
/// This type implements the `serde::de::Visitor` trait for a `ByteBuf`.
pub struct ByteBufVisitor; pub struct ByteBufVisitor;
impl de::Visitor for ByteBufVisitor { impl de::Visitor for ByteBufVisitor {
@@ -199,7 +196,7 @@ impl de::Deserialize for ByteBuf {
fn deserialize<D>(deserializer: &mut D) -> Result<ByteBuf, D::Error> fn deserialize<D>(deserializer: &mut D) -> Result<ByteBuf, D::Error>
where D: de::Deserializer where D: de::Deserializer
{ {
deserializer.deserialize_bytes(ByteBufVisitor) deserializer.visit_bytes(ByteBufVisitor)
} }
} }
-409
View File
@@ -1,409 +0,0 @@
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Extracted from https://github.com/rust-num/num.
// Rust 1.5 is unhappy that this private module is undocumented.
#![allow(missing_docs)]
use std::{usize, u8, u16, u32, u64};
use std::{isize, i8, i16, i32, i64};
use std::{f32, f64};
use std::mem::size_of;
/// Numbers which have upper and lower bounds
pub trait Bounded {
// FIXME (#5527): These should be associated constants
/// returns the smallest finite number this type can represent
fn min_value() -> Self;
/// returns the largest finite number this type can represent
fn max_value() -> Self;
}
macro_rules! bounded_impl {
($t:ty, $min:expr, $max:expr) => {
impl Bounded for $t {
#[inline]
fn min_value() -> $t { $min }
#[inline]
fn max_value() -> $t { $max }
}
}
}
bounded_impl!(usize, usize::MIN, usize::MAX);
bounded_impl!(u8, u8::MIN, u8::MAX);
bounded_impl!(u16, u16::MIN, u16::MAX);
bounded_impl!(u32, u32::MIN, u32::MAX);
bounded_impl!(u64, u64::MIN, u64::MAX);
bounded_impl!(isize, isize::MIN, isize::MAX);
bounded_impl!(i8, i8::MIN, i8::MAX);
bounded_impl!(i16, i16::MIN, i16::MAX);
bounded_impl!(i32, i32::MIN, i32::MAX);
bounded_impl!(i64, i64::MIN, i64::MAX);
bounded_impl!(f32, f32::MIN, f32::MAX);
bounded_impl!(f64, f64::MIN, f64::MAX);
/// A generic trait for converting a value to a number.
pub trait ToPrimitive {
/// Converts the value of `self` to an `isize`.
#[inline]
fn to_isize(&self) -> Option<isize> {
self.to_i64().and_then(|x| x.to_isize())
}
/// Converts the value of `self` to an `i8`.
#[inline]
fn to_i8(&self) -> Option<i8> {
self.to_i64().and_then(|x| x.to_i8())
}
/// Converts the value of `self` to an `i16`.
#[inline]
fn to_i16(&self) -> Option<i16> {
self.to_i64().and_then(|x| x.to_i16())
}
/// Converts the value of `self` to an `i32`.
#[inline]
fn to_i32(&self) -> Option<i32> {
self.to_i64().and_then(|x| x.to_i32())
}
/// Converts the value of `self` to an `i64`.
fn to_i64(&self) -> Option<i64>;
/// Converts the value of `self` to a `usize`.
#[inline]
fn to_usize(&self) -> Option<usize> {
self.to_u64().and_then(|x| x.to_usize())
}
/// Converts the value of `self` to an `u8`.
#[inline]
fn to_u8(&self) -> Option<u8> {
self.to_u64().and_then(|x| x.to_u8())
}
/// Converts the value of `self` to an `u16`.
#[inline]
fn to_u16(&self) -> Option<u16> {
self.to_u64().and_then(|x| x.to_u16())
}
/// Converts the value of `self` to an `u32`.
#[inline]
fn to_u32(&self) -> Option<u32> {
self.to_u64().and_then(|x| x.to_u32())
}
/// Converts the value of `self` to an `u64`.
#[inline]
fn to_u64(&self) -> Option<u64>;
/// Converts the value of `self` to an `f32`.
#[inline]
fn to_f32(&self) -> Option<f32> {
self.to_f64().and_then(|x| x.to_f32())
}
/// Converts the value of `self` to an `f64`.
#[inline]
fn to_f64(&self) -> Option<f64> {
self.to_i64().and_then(|x| x.to_f64())
}
}
macro_rules! impl_to_primitive_int_to_int {
($SrcT:ty, $DstT:ty, $slf:expr) => (
{
if size_of::<$SrcT>() <= size_of::<$DstT>() {
Some($slf as $DstT)
} else {
let n = $slf as i64;
let min_value: $DstT = Bounded::min_value();
let max_value: $DstT = Bounded::max_value();
if min_value as i64 <= n && n <= max_value as i64 {
Some($slf as $DstT)
} else {
None
}
}
}
)
}
macro_rules! impl_to_primitive_int_to_uint {
($SrcT:ty, $DstT:ty, $slf:expr) => (
{
let zero: $SrcT = 0;
let max_value: $DstT = Bounded::max_value();
if zero <= $slf && $slf as u64 <= max_value as u64 {
Some($slf as $DstT)
} else {
None
}
}
)
}
macro_rules! impl_to_primitive_int {
($T:ty) => (
impl ToPrimitive for $T {
#[inline]
fn to_isize(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
#[inline]
fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
#[inline]
fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16, *self) }
#[inline]
fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32, *self) }
#[inline]
fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64, *self) }
#[inline]
fn to_usize(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
#[inline]
fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
#[inline]
fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16, *self) }
#[inline]
fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32, *self) }
#[inline]
fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64, *self) }
#[inline]
fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
#[inline]
fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
}
)
}
impl_to_primitive_int! { isize }
impl_to_primitive_int! { i8 }
impl_to_primitive_int! { i16 }
impl_to_primitive_int! { i32 }
impl_to_primitive_int! { i64 }
macro_rules! impl_to_primitive_uint_to_int {
($DstT:ty, $slf:expr) => (
{
let max_value: $DstT = Bounded::max_value();
if $slf as u64 <= max_value as u64 {
Some($slf as $DstT)
} else {
None
}
}
)
}
macro_rules! impl_to_primitive_uint_to_uint {
($SrcT:ty, $DstT:ty, $slf:expr) => (
{
if size_of::<$SrcT>() <= size_of::<$DstT>() {
Some($slf as $DstT)
} else {
let zero: $SrcT = 0;
let max_value: $DstT = Bounded::max_value();
if zero <= $slf && $slf as u64 <= max_value as u64 {
Some($slf as $DstT)
} else {
None
}
}
}
)
}
macro_rules! impl_to_primitive_uint {
($T:ty) => (
impl ToPrimitive for $T {
#[inline]
fn to_isize(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
#[inline]
fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
#[inline]
fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16, *self) }
#[inline]
fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32, *self) }
#[inline]
fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64, *self) }
#[inline]
fn to_usize(&self) -> Option<usize> {
impl_to_primitive_uint_to_uint!($T, usize, *self)
}
#[inline]
fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
#[inline]
fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16, *self) }
#[inline]
fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32, *self) }
#[inline]
fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64, *self) }
#[inline]
fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
#[inline]
fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
}
)
}
impl_to_primitive_uint! { usize }
impl_to_primitive_uint! { u8 }
impl_to_primitive_uint! { u16 }
impl_to_primitive_uint! { u32 }
impl_to_primitive_uint! { u64 }
macro_rules! impl_to_primitive_float_to_float {
($SrcT:ident, $DstT:ident, $slf:expr) => (
if size_of::<$SrcT>() <= size_of::<$DstT>() {
Some($slf as $DstT)
} else {
let n = $slf as f64;
let max_value: $SrcT = ::std::$SrcT::MAX;
if -max_value as f64 <= n && n <= max_value as f64 {
Some($slf as $DstT)
} else {
None
}
}
)
}
macro_rules! impl_to_primitive_float {
($T:ident) => (
impl ToPrimitive for $T {
#[inline]
fn to_isize(&self) -> Option<isize> { Some(*self as isize) }
#[inline]
fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
#[inline]
fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
#[inline]
fn to_i32(&self) -> Option<i32> { Some(*self as i32) }
#[inline]
fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
#[inline]
fn to_usize(&self) -> Option<usize> { Some(*self as usize) }
#[inline]
fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
#[inline]
fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
#[inline]
fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
#[inline]
fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
#[inline]
fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32, *self) }
#[inline]
fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64, *self) }
}
)
}
impl_to_primitive_float! { f32 }
impl_to_primitive_float! { f64 }
pub trait FromPrimitive: Sized {
#[inline]
fn from_isize(n: isize) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
#[inline]
fn from_i8(n: i8) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
fn from_i64(n: i64) -> Option<Self>;
#[inline]
fn from_usize(n: usize) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
#[inline]
fn from_u8(n: u8) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
#[inline]
fn from_u32(n: u32) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
fn from_u64(n: u64) -> Option<Self>;
#[inline]
fn from_f32(n: f32) -> Option<Self> {
FromPrimitive::from_f64(n as f64)
}
#[inline]
fn from_f64(n: f64) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
}
macro_rules! impl_from_primitive {
($T:ty, $to_ty:ident) => (
impl FromPrimitive for $T {
#[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
#[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
#[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
#[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() }
#[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() }
#[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() }
}
)
}
impl_from_primitive! { isize, to_isize }
impl_from_primitive! { i8, to_i8 }
impl_from_primitive! { i16, to_i16 }
impl_from_primitive! { i32, to_i32 }
impl_from_primitive! { i64, to_i64 }
impl_from_primitive! { usize, to_usize }
impl_from_primitive! { u8, to_u8 }
impl_from_primitive! { u16, to_u16 }
impl_from_primitive! { u32, to_u32 }
impl_from_primitive! { u64, to_u64 }
impl_from_primitive! { f32, to_f32 }
impl_from_primitive! { f64, to_f64 }
+332 -599
View File
File diff suppressed because it is too large Load Diff
+102 -504
View File
@@ -1,164 +1,23 @@
//! Generic deserialization framework. //! Generic deserialization framework.
use std::error;
pub mod impls; pub mod impls;
pub mod value; pub mod value;
mod from_primitive;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// `Error` is a trait that allows a `Deserialize` to generically create a pub trait Error {
/// `Deserializer` error. fn syntax_error() -> Self;
pub trait Error: Sized + error::Error {
/// Raised when there is general error when deserializing a type.
fn custom<T: Into<String>>(msg: T) -> Self;
/// Raised when a `Deserialize` type unexpectedly hit the end of the stream. fn end_of_stream_error() -> Self;
fn end_of_stream() -> Self;
/// Raised when a `Deserialize` was passed an incorrect type. fn unknown_field_error(field: &str) -> Self;
fn invalid_type(ty: Type) -> Self {
Error::custom(format!("Invalid type. Expected `{:?}`", ty))
}
/// Raised when a `Deserialize` was passed an incorrect value. fn missing_field_error(field: &'static str) -> Self;
fn invalid_value(msg: &str) -> Self {
Error::custom(format!("Invalid value: {}", msg))
}
/// Raised when a fixed sized sequence or map was passed in the wrong amount of arguments.
fn invalid_length(len: usize) -> Self {
Error::custom(format!("Invalid length: {}", len))
}
/// Raised when a `Deserialize` enum type received an unexpected variant.
fn unknown_variant(field: &str) -> Self {
Error::custom(format!("Unknown variant `{}`", field))
}
/// Raised when a `Deserialize` struct type received an unexpected struct field.
fn unknown_field(field: &str) -> Self {
Error::custom(format!("Unknown field `{}`", field))
}
/// raised when a `deserialize` struct type did not receive a field.
fn missing_field(field: &'static str) -> Self {
Error::custom(format!("Missing field `{}`", field))
}
/// Raised when a `Deserialize` struct type received more than one of the
/// same struct field.
fn duplicate_field(field: &'static str) -> Self {
Error::custom(format!("Duplicate field `{}`", field))
}
}
/// `Type` represents all the primitive types that can be deserialized. This is used by
/// `Error::invalid_type`.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Type {
/// Represents a `bool` type.
Bool,
/// Represents a `usize` type.
Usize,
/// Represents a `u8` type.
U8,
/// Represents a `u16` type.
U16,
/// Represents a `u32` type.
U32,
/// Represents a `u64` type.
U64,
/// Represents a `isize` type.
Isize,
/// Represents a `i8` type.
I8,
/// Represents a `i16` type.
I16,
/// Represents a `i32` type.
I32,
/// Represents a `i64` type.
I64,
/// Represents a `f32` type.
F32,
/// Represents a `f64` type.
F64,
/// Represents a `char` type.
Char,
/// Represents a `&str` type.
Str,
/// Represents a `String` type.
String,
/// Represents a `()` type.
Unit,
/// Represents an `Option<T>` type.
Option,
/// Represents a sequence type.
Seq,
/// Represents a map type.
Map,
/// Represents a unit struct type.
UnitStruct,
/// Represents a newtype type.
NewtypeStruct,
/// Represents a tuple struct type.
TupleStruct,
/// Represents a struct type.
Struct,
/// Represents a struct field name.
FieldName,
/// Represents a tuple type.
Tuple,
/// Represents an `enum` type.
Enum,
/// Represents an enum variant name.
VariantName,
/// Represents a struct variant.
StructVariant,
/// Represents a tuple variant.
TupleVariant,
/// Represents a unit variant.
UnitVariant,
/// Represents a `&[u8]` type.
Bytes,
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// `Deserialize` represents a type that can be deserialized. pub trait Deserialize {
pub trait Deserialize: Sized {
/// Deserialize this value given this `Deserializer`. /// Deserialize this value given this `Deserializer`.
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer; where D: Deserializer;
@@ -166,400 +25,188 @@ pub trait Deserialize: Sized {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// `Deserializer` is a trait that can deserialize values by threading a `Visitor` trait through a /// `Deserializer` is an abstract trait that can deserialize values into a `Visitor`.
/// value. It supports two entry point styles which enables different kinds of deserialization.
///
/// 1) The `deserialize` method. File formats like JSON embed the type of its construct in its file
/// format. This allows the `Deserializer` to deserialize into a generic type like
/// `json::Value`, which can represent all JSON types.
///
/// 2) The `deserialize_*` methods. File formats like bincode do not embed in its format how to
/// decode its values. It relies instead on the `Deserialize` type to hint to the `Deserializer`
/// with the `deserialize_*` methods how it should parse the next value. One downside though to
/// only supporting the `deserialize_*` types is that it does not allow for deserializing into a
/// generic `json::Value`-esque type.
pub trait Deserializer { pub trait Deserializer {
/// The error type that can be returned if some error occurs during deserialization.
type Error: Error; type Error: Error;
/// This method walks a visitor through a value as it is being deserialized. /// The `visit` method walks a visitor through a value as it is being deserialized.
fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error> fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor; where V: Visitor;
/// This method hints that the `Deserialize` type is expecting a `bool` value. /// 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)`.
#[inline] #[inline]
fn deserialize_bool<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error> fn visit_option<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor, where V: Visitor,
{ {
self.deserialize(visitor) self.visit(visitor)
} }
/// This method hints that the `Deserialize` type is expecting an `usize` value. /// 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.
#[inline] #[inline]
fn deserialize_usize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error> fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor, where V: Visitor,
{ {
self.deserialize_u64(visitor) self.visit(visitor)
} }
/// This method hints that the `Deserialize` type is expecting an `u8` value. /// 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.
#[inline] #[inline]
fn deserialize_u8<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error> fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor, where V: Visitor,
{ {
self.deserialize_u64(visitor) self.visit(visitor)
} }
/// This method hints that the `Deserialize` type is expecting an `u16` value. /// 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.
#[inline] #[inline]
fn deserialize_u16<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error> fn visit_named_unit<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor, where V: Visitor,
{ {
self.deserialize_u64(visitor) self.visit(visitor)
} }
/// This method hints that the `Deserialize` type is expecting an `u32` value. /// 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.
#[inline] #[inline]
fn deserialize_u32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error> fn visit_named_seq<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor, where V: Visitor,
{ {
self.deserialize_u64(visitor) self.visit_seq(visitor)
} }
/// This method hints that the `Deserialize` type is expecting an `u64` value. /// 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.
#[inline] #[inline]
fn deserialize_u64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error> fn visit_named_map<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor, where V: Visitor,
{ {
self.deserialize(visitor) self.visit_map(visitor)
} }
/// This method hints that the `Deserialize` type is expecting an `isize` value. /// 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.
#[inline] #[inline]
fn deserialize_isize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error> fn visit_enum<V>(&mut self, _enum: &str, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_i64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i8` value.
#[inline]
fn deserialize_i8<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_i64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i16` value.
#[inline]
fn deserialize_i16<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_i64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i32` value.
#[inline]
fn deserialize_i32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_i64(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `i64` value.
#[inline]
fn deserialize_i64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `f32` value.
#[inline]
fn deserialize_f32<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_f64(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `f64` value.
#[inline]
fn deserialize_f64<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `char` value.
#[inline]
fn deserialize_char<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `&str` value.
#[inline]
fn deserialize_str<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize(visitor)
}
/// This method hints that the `Deserialize` type is expecting a `String` value.
#[inline]
fn deserialize_string<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_str(visitor)
}
/// This method hints that the `Deserialize` type is expecting an `unit` value.
#[inline]
fn deserialize_unit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize(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 deserialize_option<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize(visitor)
}
/// 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 deserialize_seq<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize(visitor)
}
/// This method hints that the `Deserialize` type is expecting a fixed size array. This allows
/// deserializers to parse arrays that aren't tagged as arrays.
///
/// By default, this deserializes arrays from a sequence.
#[inline]
fn deserialize_fixed_size_array<V>(&mut self,
_len: usize,
visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize(visitor)
}
/// 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 deserialize_bytes<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_seq(visitor)
}
/// 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 deserialize_map<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize(visitor)
}
/// 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 deserialize_unit_struct<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_unit(visitor)
}
/// 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 deserialize_newtype_struct<V>(&mut self,
name: &'static str,
visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_tuple_struct(name, 1, visitor)
}
/// 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 deserialize_tuple_struct<V>(&mut self,
_name: &'static str,
len: usize,
visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_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 deserialize_struct<V>(&mut self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_map(visitor)
}
/// This method hints that the `Deserialize` type is expecting some sort of struct field
/// name. This allows deserializers to choose between &str, usize, or &[u8] to properly
/// deserialize a struct field.
#[inline]
fn deserialize_struct_field<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize(visitor)
}
/// 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 deserialize_tuple<V>(&mut self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.deserialize_seq(visitor)
}
/// 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 deserialize_enum<V>(&mut self,
_enum: &'static str,
_variants: &'static [&'static str],
_visitor: V) -> Result<V::Value, Self::Error>
where V: EnumVisitor, where V: EnumVisitor,
{ {
Err(Error::invalid_type(Type::Enum)) Err(Error::syntax_error())
} }
/// This method hints that the `Deserialize` type needs to deserialize a value whose type /// The `visit_bytes` method allows a `Deserialize` type to inform the `Deserializer` that it's
/// doesn't matter because it is ignored. /// expecting a `Vec<u8>`. This allows deserializers that provide a custom byte vector
/// serialization to properly deserialize the type.
#[inline] #[inline]
fn deserialize_ignored_any<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error> fn visit_bytes<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor where V: Visitor,
{ {
self.deserialize(visitor) self.visit(visitor)
}
/// Specify a format string for the deserializer.
///
/// The deserializer format is used to determine which format
/// specific field attributes should be used with the
/// deserializer.
fn format() -> &'static str {
""
} }
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// This trait represents a visitor that walks through a deserializer.
pub trait Visitor { pub trait Visitor {
/// The value produced by this visitor.
type Value: Deserialize; type Value: Deserialize;
/// `visit_bool` deserializes a `bool` into a `Value`.
fn visit_bool<E>(&mut self, _v: bool) -> Result<Self::Value, E> fn visit_bool<E>(&mut self, _v: bool) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::invalid_type(Type::Bool)) Err(Error::syntax_error())
} }
/// `visit_isize` deserializes a `isize` into a `Value`.
fn visit_isize<E>(&mut self, v: isize) -> Result<Self::Value, E> fn visit_isize<E>(&mut self, v: isize) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
self.visit_i64(v as i64) self.visit_i64(v as i64)
} }
/// `visit_i8` deserializes a `i8` into a `Value`.
fn visit_i8<E>(&mut self, v: i8) -> Result<Self::Value, E> fn visit_i8<E>(&mut self, v: i8) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
self.visit_i64(v as i64) self.visit_i64(v as i64)
} }
/// `visit_i16` deserializes a `i16` into a `Value`.
fn visit_i16<E>(&mut self, v: i16) -> Result<Self::Value, E> fn visit_i16<E>(&mut self, v: i16) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
self.visit_i64(v as i64) self.visit_i64(v as i64)
} }
/// `visit_i32` deserializes a `i32` into a `Value`.
fn visit_i32<E>(&mut self, v: i32) -> Result<Self::Value, E> fn visit_i32<E>(&mut self, v: i32) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
self.visit_i64(v as i64) self.visit_i64(v as i64)
} }
/// `visit_i64` deserializes a `i64` into a `Value`.
fn visit_i64<E>(&mut self, _v: i64) -> Result<Self::Value, E> fn visit_i64<E>(&mut self, _v: i64) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::invalid_type(Type::I64)) Err(Error::syntax_error())
} }
/// `visit_usize` deserializes a `usize` into a `Value`.
fn visit_usize<E>(&mut self, v: usize) -> Result<Self::Value, E> fn visit_usize<E>(&mut self, v: usize) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
self.visit_u64(v as u64) self.visit_u64(v as u64)
} }
/// `visit_u8` deserializes a `u8` into a `Value`.
fn visit_u8<E>(&mut self, v: u8) -> Result<Self::Value, E> fn visit_u8<E>(&mut self, v: u8) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
self.visit_u64(v as u64) self.visit_u64(v as u64)
} }
/// `visit_u16` deserializes a `u16` into a `Value`.
fn visit_u16<E>(&mut self, v: u16) -> Result<Self::Value, E> fn visit_u16<E>(&mut self, v: u16) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
self.visit_u64(v as u64) self.visit_u64(v as u64)
} }
/// `visit_u32` deserializes a `u32` into a `Value`.
fn visit_u32<E>(&mut self, v: u32) -> Result<Self::Value, E> fn visit_u32<E>(&mut self, v: u32) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
self.visit_u64(v as u64) self.visit_u64(v as u64)
} }
/// `visit_u64` deserializes a `u64` into a `Value`.
fn visit_u64<E>(&mut self, _v: u64) -> Result<Self::Value, E> fn visit_u64<E>(&mut self, _v: u64) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::invalid_type(Type::U64)) Err(Error::syntax_error())
} }
/// `visit_f32` deserializes a `f32` into a `Value`.
fn visit_f32<E>(&mut self, v: f32) -> Result<Self::Value, E> fn visit_f32<E>(&mut self, v: f32) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
self.visit_f64(v as f64) self.visit_f64(v as f64)
} }
/// `visit_f64` deserializes a `f64` into a `Value`.
fn visit_f64<E>(&mut self, _v: f64) -> Result<Self::Value, E> fn visit_f64<E>(&mut self, _v: f64) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::invalid_type(Type::F64)) Err(Error::syntax_error())
} }
/// `visit_char` deserializes a `char` into a `Value`.
#[inline] #[inline]
fn visit_char<E>(&mut self, v: char) -> Result<Self::Value, E> fn visit_char<E>(&mut self, v: char) -> Result<Self::Value, E>
where E: Error, where E: Error,
@@ -569,16 +216,12 @@ pub trait Visitor {
self.visit_string(v.to_string()) self.visit_string(v.to_string())
} }
/// `visit_str` deserializes a `&str` into a `Value`.
fn visit_str<E>(&mut self, _v: &str) -> Result<Self::Value, E> fn visit_str<E>(&mut self, _v: &str) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::invalid_type(Type::Str)) Err(Error::syntax_error())
} }
/// `visit_string` deserializes a `String` into a `Value`. This allows a deserializer to avoid
/// a copy if it is deserializing a string from a `String` type. By default it passes a `&str`
/// to the `visit_str` method.
#[inline] #[inline]
fn visit_string<E>(&mut self, v: String) -> Result<Self::Value, E> fn visit_string<E>(&mut self, v: String) -> Result<Self::Value, E>
where E: Error, where E: Error,
@@ -586,64 +229,49 @@ pub trait Visitor {
self.visit_str(&v) self.visit_str(&v)
} }
/// `visit_unit` deserializes a `()` into a `Value`.
fn visit_unit<E>(&mut self) -> Result<Self::Value, E> fn visit_unit<E>(&mut self) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::invalid_type(Type::Unit)) Err(Error::syntax_error())
} }
/// `visit_unit_struct` deserializes a unit struct into a `Value`.
#[inline] #[inline]
fn visit_unit_struct<E>(&mut self, _name: &'static str) -> Result<Self::Value, E> fn visit_named_unit<E>(&mut self, _name: &str) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
self.visit_unit() self.visit_unit()
} }
/// `visit_none` deserializes a none value into a `Value`.
fn visit_none<E>(&mut self) -> Result<Self::Value, E> fn visit_none<E>(&mut self) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::invalid_type(Type::Option)) Err(Error::syntax_error())
} }
/// `visit_some` deserializes a value into a `Value`.
fn visit_some<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error> fn visit_some<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
where D: Deserializer, where D: Deserializer,
{ {
Err(Error::invalid_type(Type::Option)) Err(Error::syntax_error())
} }
/// `visit_newtype_struct` deserializes a value into a `Value`.
fn visit_newtype_struct<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
where D: Deserializer,
{
Err(Error::invalid_type(Type::NewtypeStruct))
}
/// `visit_bool` deserializes a `SeqVisitor` into a `Value`.
fn visit_seq<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error> fn visit_seq<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor, where V: SeqVisitor,
{ {
Err(Error::invalid_type(Type::Seq)) Err(Error::syntax_error())
} }
/// `visit_map` deserializes a `MapVisitor` into a `Value`.
fn visit_map<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error> fn visit_map<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor, where V: MapVisitor,
{ {
Err(Error::invalid_type(Type::Map)) Err(Error::syntax_error())
} }
/// `visit_bytes` deserializes a `&[u8]` into a `Value`.
fn visit_bytes<E>(&mut self, _v: &[u8]) -> Result<Self::Value, E> fn visit_bytes<E>(&mut self, _v: &[u8]) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
Err(Error::invalid_type(Type::Bytes)) Err(Error::syntax_error())
} }
/// `visit_byte_buf` deserializes a `Vec<u8>` into a `Value`.
fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<Self::Value, E> fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<Self::Value, E>
where E: Error, where E: Error,
{ {
@@ -653,23 +281,14 @@ pub trait Visitor {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// `SeqVisitor` visits each item in a sequence.
///
/// This is a trait that a `Deserializer` passes to a `Visitor` implementation, which deserializes
/// each item in a sequence.
pub trait SeqVisitor { pub trait SeqVisitor {
/// The error type that can be returned if some error occurs during deserialization.
type Error: Error; type Error: Error;
/// This returns a `Ok(Some(value))` for the next value in the sequence, or `Ok(None)` if there
/// are no more remaining items.
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error> fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: Deserialize; where T: Deserialize;
/// This signals to the `SeqVisitor` that the `Visitor` does not expect any more items.
fn end(&mut self) -> Result<(), Self::Error>; fn end(&mut self) -> Result<(), Self::Error>;
/// Return the lower and upper bound of items remaining in the sequence.
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
(0, None) (0, None)
@@ -699,15 +318,9 @@ impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// `MapVisitor` visits each item in a sequence.
///
/// This is a trait that a `Deserializer` passes to a `Visitor` implementation.
pub trait MapVisitor { pub trait MapVisitor {
/// The error type that can be returned if some error occurs during deserialization.
type Error: Error; type Error: Error;
/// This returns a `Ok(Some((key, value)))` for the next (key-value) pair in the map, or
/// `Ok(None)` if there are no more remaining items.
#[inline] #[inline]
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error> fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error>
where K: Deserialize, where K: Deserialize,
@@ -722,29 +335,23 @@ pub trait MapVisitor {
} }
} }
/// This returns a `Ok(Some(key))` for the next key in the map, or `Ok(None)` if there are no
/// more remaining items.
fn visit_key<K>(&mut self) -> Result<Option<K>, Self::Error> fn visit_key<K>(&mut self) -> Result<Option<K>, Self::Error>
where K: Deserialize; where K: Deserialize;
/// This returns a `Ok(value)` for the next value in the map.
fn visit_value<V>(&mut self) -> Result<V, Self::Error> fn visit_value<V>(&mut self) -> Result<V, Self::Error>
where V: Deserialize; where V: Deserialize;
/// This signals to the `MapVisitor` that the `Visitor` does not expect any more items.
fn end(&mut self) -> Result<(), Self::Error>; fn end(&mut self) -> Result<(), Self::Error>;
/// Return the lower and upper bound of items remaining in the sequence.
#[inline] #[inline]
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
(0, None) (0, None)
} }
/// Report that the struct has a field that wasn't deserialized
fn missing_field<V>(&mut self, field: &'static str) -> Result<V, Self::Error> fn missing_field<V>(&mut self, field: &'static str) -> Result<V, Self::Error>
where V: Deserialize, where V: Deserialize,
{ {
Err(Error::missing_field(field)) Err(Error::missing_field_error(field))
} }
} }
@@ -789,10 +396,8 @@ impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
/// `EnumVisitor` is a visitor that is created by the `Deserialize` and passed to the /// `EnumVisitor` is a visitor that is created by the `Deserialize` and passed to the
/// `Deserializer` in order to deserialize enums. /// `Deserializer` in order to deserialize enums.
pub trait EnumVisitor { pub trait EnumVisitor {
/// The value produced by this visitor.
type Value; type Value;
/// Visit the specific variant with the `VariantVisitor`.
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error> fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
where V: VariantVisitor; where V: VariantVisitor;
} }
@@ -802,7 +407,6 @@ pub trait EnumVisitor {
/// `VariantVisitor` is a visitor that is created by the `Deserializer` and passed to the /// `VariantVisitor` is a visitor that is created by the `Deserializer` and passed to the
/// `Deserialize` in order to deserialize a specific enum variant. /// `Deserialize` in order to deserialize a specific enum variant.
pub trait VariantVisitor { pub trait VariantVisitor {
/// The error type that can be returned if some error occurs during deserialization.
type Error: Error; type Error: Error;
/// `visit_variant` is called to identify which variant to deserialize. /// `visit_variant` is called to identify which variant to deserialize.
@@ -811,35 +415,21 @@ pub trait VariantVisitor {
/// `visit_unit` is called when deserializing a variant with no values. /// `visit_unit` is called when deserializing a variant with no values.
fn visit_unit(&mut self) -> Result<(), Self::Error> { fn visit_unit(&mut self) -> Result<(), Self::Error> {
Err(Error::invalid_type(Type::UnitVariant)) Err(Error::syntax_error())
} }
/// `visit_newtype` is called when deserializing a variant with a single value. By default this /// `visit_seq` is called when deserializing a tuple-like variant.
/// uses the `visit_tuple` method to deserialize the value. fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
#[inline]
fn visit_newtype<T>(&mut self) -> Result<T, Self::Error>
where T: Deserialize,
{
let (value,) = try!(self.visit_tuple(1, impls::TupleVisitor1::new()));
Ok(value)
}
/// `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 where V: Visitor
{ {
Err(Error::invalid_type(Type::TupleVariant)) Err(Error::syntax_error())
} }
/// `visit_struct` is called when deserializing a struct-like variant. /// `visit_map` is called when deserializing a struct-like variant.
fn visit_struct<V>(&mut self, fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
_fields: &'static [&'static str],
_visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor where V: Visitor
{ {
Err(Error::invalid_type(Type::StructVariant)) Err(Error::syntax_error())
} }
} }
@@ -856,25 +446,33 @@ impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor {
(**self).visit_unit() (**self).visit_unit()
} }
fn visit_newtype<D>(&mut self) -> Result<D, T::Error> fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where D: Deserialize,
{
(**self).visit_newtype()
}
fn visit_tuple<V>(&mut self,
len: usize,
visitor: V) -> Result<V::Value, T::Error>
where V: Visitor, where V: Visitor,
{ {
(**self).visit_tuple(len, visitor) (**self).visit_seq(visitor)
} }
fn visit_struct<V>(&mut self, fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
fields: &'static [&'static str],
visitor: V) -> Result<V::Value, T::Error>
where V: Visitor, where V: Visitor,
{ {
(**self).visit_struct(fields, visitor) (**self).visit_map(visitor)
} }
} }
///////////////////////////////////////////////////////////////////////////////
pub trait EnumSeqVisitor {
type Value;
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor;
}
///////////////////////////////////////////////////////////////////////////////
pub trait EnumMapVisitor {
type Value;
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor;
}
+128 -310
View File
@@ -1,5 +1,3 @@
//! This module supports deserializing from primitives with the `ValueDeserializer` trait.
use std::collections::{ use std::collections::{
BTreeMap, BTreeMap,
BTreeSet, BTreeSet,
@@ -11,120 +9,58 @@ use std::collections::{
hash_set, hash_set,
}; };
use std::hash::Hash; use std::hash::Hash;
use std::error;
use std::fmt;
use std::vec; use std::vec;
use std::marker::PhantomData;
use de; use de;
use bytes; use bytes;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// This represents all the possible errors that can occur using the `ValueDeserializer`.
#[derive(Clone, Debug, PartialEq)]
pub enum Error { pub enum Error {
/// The value had some custom error. SyntaxError,
Custom(String), EndOfStreamError,
UnknownFieldError(String),
/// The value had an incorrect type. MissingFieldError(&'static str),
InvalidType(de::Type),
/// The value had an invalid length.
InvalidLength(usize),
/// The value is invalid and cannot be deserialized.
InvalidValue(String),
/// EOF while deserializing a value.
EndOfStream,
/// Unknown variant in enum.
UnknownVariant(String),
/// Unknown field in struct.
UnknownField(String),
/// Struct is missing a field.
MissingField(&'static str),
} }
impl de::Error for Error { impl de::Error for Error {
fn custom<T: Into<String>>(msg: T) -> Self { Error::Custom(msg.into()) } fn syntax_error() -> Self { Error::SyntaxError }
fn end_of_stream() -> Self { Error::EndOfStream } fn end_of_stream_error() -> Self { Error::EndOfStreamError }
fn invalid_type(ty: de::Type) -> Self { Error::InvalidType(ty) } fn unknown_field_error(field: &str) -> Self { Error::UnknownFieldError(field.to_string()) }
fn invalid_value(msg: &str) -> Self { Error::InvalidValue(msg.to_owned()) } fn missing_field_error(field: &'static str) -> Self { Error::MissingFieldError(field) }
fn invalid_length(len: usize) -> Self { Error::InvalidLength(len) }
fn unknown_variant(variant: &str) -> Self { Error::UnknownVariant(String::from(variant)) }
fn unknown_field(field: &str) -> Self { Error::UnknownField(String::from(field)) }
fn missing_field(field: &'static str) -> Self { Error::MissingField(field) }
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
Error::Custom(ref s) => write!(formatter, "{}", s),
Error::EndOfStream => formatter.write_str("End of stream"),
Error::InvalidType(ty) => write!(formatter, "Invalid type, expected `{:?}`", ty),
Error::InvalidValue(ref value) => write!(formatter, "Invalid value: {}", value),
Error::InvalidLength(len) => write!(formatter, "Invalid length: {}", len),
Error::UnknownVariant(ref variant) => {
write!(formatter, "Unknown variant: {}", variant)
}
Error::UnknownField(ref field) => write!(formatter, "Unknown field: {}", field),
Error::MissingField(ref field) => write!(formatter, "Missing field: {}", field),
}
}
}
impl error::Error for Error {
fn description(&self) -> &str {
"Serde Deserialization Error"
}
fn cause(&self) -> Option<&error::Error> {
None
}
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// This trait converts primitive types into a deserializer. pub trait ValueDeserializer {
pub trait ValueDeserializer<E: de::Error = Error> { type Deserializer: de::Deserializer<Error=Error>;
/// The actual deserializer type.
type Deserializer: de::Deserializer<Error=E>;
/// Convert this value into a deserializer.
fn into_deserializer(self) -> Self::Deserializer; fn into_deserializer(self) -> Self::Deserializer;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
impl<E> ValueDeserializer<E> for () impl ValueDeserializer for () {
where E: de::Error, type Deserializer = UnitDeserializer;
{
type Deserializer = UnitDeserializer<E>;
fn into_deserializer(self) -> UnitDeserializer<E> { fn into_deserializer(self) -> UnitDeserializer {
UnitDeserializer(PhantomData) UnitDeserializer
} }
} }
/// A helper deserializer that deserializes a `()`. /// A helper deserializer that deserializes a `()`.
pub struct UnitDeserializer<E>(PhantomData<E>); pub struct UnitDeserializer;
impl<E> de::Deserializer for UnitDeserializer<E> impl de::Deserializer for UnitDeserializer {
where E: de::Error type Error = Error;
{
type Error = E;
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error> fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
visitor.visit_unit() visitor.visit_unit()
} }
fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error> fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
visitor.visit_none() visitor.visit_none()
@@ -135,30 +71,25 @@ impl<E> de::Deserializer for UnitDeserializer<E>
macro_rules! primitive_deserializer { macro_rules! primitive_deserializer {
($ty:ty, $name:ident, $method:ident) => { ($ty:ty, $name:ident, $method:ident) => {
/// A helper deserializer that deserializes a number. pub struct $name(Option<$ty>);
pub struct $name<E>(Option<$ty>, PhantomData<E>);
impl<E> ValueDeserializer<E> for $ty impl ValueDeserializer for $ty {
where E: de::Error, type Deserializer = $name;
{
type Deserializer = $name<E>;
fn into_deserializer(self) -> $name<E> { fn into_deserializer(self) -> $name {
$name(Some(self), PhantomData) $name(Some(self))
} }
} }
impl<E> de::Deserializer for $name<E> impl de::Deserializer for $name {
where E: de::Error, type Error = Error;
{
type Error = E;
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error> fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.0.take() { match self.0.take() {
Some(v) => visitor.$method(v), Some(v) => visitor.$method(v),
None => Err(de::Error::end_of_stream()), None => Err(de::Error::end_of_stream_error()),
} }
} }
} }
@@ -183,54 +114,45 @@ primitive_deserializer!(char, CharDeserializer, visit_char);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a `&str`. /// A helper deserializer that deserializes a `&str`.
pub struct StrDeserializer<'a, E>(Option<&'a str>, PhantomData<E>); pub struct StrDeserializer<'a>(Option<&'a str>);
impl<'a, E> ValueDeserializer<E> for &'a str impl<'a> ValueDeserializer for &'a str {
where E: de::Error, type Deserializer = StrDeserializer<'a>;
{
type Deserializer = StrDeserializer<'a, E>;
fn into_deserializer(self) -> StrDeserializer<'a, E> { fn into_deserializer(self) -> StrDeserializer<'a> {
StrDeserializer(Some(self), PhantomData) StrDeserializer(Some(self))
} }
} }
impl<'a, E> de::Deserializer for StrDeserializer<'a, E> impl<'a> de::Deserializer for StrDeserializer<'a> {
where E: de::Error, type Error = Error;
{
type Error = E;
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error> fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.0.take() { match self.0.take() {
Some(v) => visitor.visit_str(v), Some(v) => visitor.visit_str(v),
None => Err(de::Error::end_of_stream()), None => Err(de::Error::end_of_stream_error()),
} }
} }
fn deserialize_enum<V>(&mut self, fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
_name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Self::Error>
where V: de::EnumVisitor, where V: de::EnumVisitor,
{ {
visitor.visit(self) visitor.visit(self)
} }
} }
impl<'a, E> de::VariantVisitor for StrDeserializer<'a, E> impl<'a> de::VariantVisitor for StrDeserializer<'a> {
where E: de::Error, type Error = Error;
{
type Error = E;
fn visit_variant<T>(&mut self) -> Result<T, Self::Error> fn visit_variant<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize, where T: de::Deserialize,
{ {
de::Deserialize::deserialize(self) de::Deserialize::deserialize(self)
} }
fn visit_unit(&mut self) -> Result<(), Self::Error> { fn visit_unit(&mut self) -> Result<(), Error> {
Ok(()) Ok(())
} }
} }
@@ -238,102 +160,85 @@ impl<'a, E> de::VariantVisitor for StrDeserializer<'a, E>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a `String`. /// A helper deserializer that deserializes a `String`.
pub struct StringDeserializer<E>(Option<String>, PhantomData<E>); pub struct StringDeserializer(Option<String>);
impl<E> ValueDeserializer<E> for String impl ValueDeserializer for String {
where E: de::Error, type Deserializer = StringDeserializer;
{
type Deserializer = StringDeserializer<E>;
fn into_deserializer(self) -> StringDeserializer<E> { fn into_deserializer(self) -> StringDeserializer {
StringDeserializer(Some(self), PhantomData) StringDeserializer(Some(self))
} }
} }
impl<E> de::Deserializer for StringDeserializer<E> impl de::Deserializer for StringDeserializer {
where E: de::Error, type Error = Error;
{
type Error = E;
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error> fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.0.take() { match self.0.take() {
Some(string) => visitor.visit_string(string), Some(string) => visitor.visit_string(string),
None => Err(de::Error::end_of_stream()), None => Err(de::Error::end_of_stream_error()),
} }
} }
fn deserialize_enum<V>(&mut self, fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
_name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Self::Error>
where V: de::EnumVisitor, where V: de::EnumVisitor,
{ {
visitor.visit(self) visitor.visit(self)
} }
} }
impl<'a, E> de::VariantVisitor for StringDeserializer<E> impl<'a> de::VariantVisitor for StringDeserializer {
where E: de::Error, type Error = Error;
{
type Error = E;
fn visit_variant<T>(&mut self) -> Result<T, Self::Error> fn visit_variant<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize, where T: de::Deserialize,
{ {
de::Deserialize::deserialize(self) de::Deserialize::deserialize(self)
} }
fn visit_unit(&mut self) -> Result<(), Self::Error> { fn visit_unit(&mut self) -> Result<(), Error> {
Ok(()) Ok(())
} }
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a sequence. pub struct SeqDeserializer<I> {
pub struct SeqDeserializer<I, E> {
iter: I, iter: I,
len: usize, len: usize,
marker: PhantomData<E>,
} }
impl<I, E> SeqDeserializer<I, E> impl<I> SeqDeserializer<I> {
where E: de::Error,
{
/// Construct a new `SeqDeserializer<I>`.
pub fn new(iter: I, len: usize) -> Self { pub fn new(iter: I, len: usize) -> Self {
SeqDeserializer { SeqDeserializer {
iter: iter, iter: iter,
len: len, len: len,
marker: PhantomData,
} }
} }
} }
impl<I, T, E> de::Deserializer for SeqDeserializer<I, E> impl<I, T> de::Deserializer for SeqDeserializer<I>
where I: Iterator<Item=T>, where I: Iterator<Item=T>,
T: ValueDeserializer<E>, T: ValueDeserializer,
E: de::Error,
{ {
type Error = E; type Error = Error;
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error> fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
visitor.visit_seq(self) visitor.visit_seq(self)
} }
} }
impl<I, T, E> de::SeqVisitor for SeqDeserializer<I, E> impl<I, T> de::SeqVisitor for SeqDeserializer<I>
where I: Iterator<Item=T>, where I: Iterator<Item=T>,
T: ValueDeserializer<E>, T: ValueDeserializer,
E: de::Error,
{ {
type Error = E; type Error = Error;
fn visit<V>(&mut self) -> Result<Option<V>, Self::Error> fn visit<V>(&mut self) -> Result<Option<V>, Error>
where V: de::Deserialize where V: de::Deserialize
{ {
match self.iter.next() { match self.iter.next() {
@@ -346,11 +251,11 @@ impl<I, T, E> de::SeqVisitor for SeqDeserializer<I, E>
} }
} }
fn end(&mut self) -> Result<(), Self::Error> { fn end(&mut self) -> Result<(), Error> {
if self.len == 0 { if self.len == 0 {
Ok(()) Ok(())
} else { } else {
Err(de::Error::invalid_length(self.len)) Err(de::Error::end_of_stream_error())
} }
} }
@@ -361,37 +266,34 @@ impl<I, T, E> de::SeqVisitor for SeqDeserializer<I, E>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
impl<T, E> ValueDeserializer<E> for Vec<T> impl<T> ValueDeserializer for Vec<T>
where T: ValueDeserializer<E>, where T: ValueDeserializer,
E: de::Error,
{ {
type Deserializer = SeqDeserializer<vec::IntoIter<T>, E>; type Deserializer = SeqDeserializer<vec::IntoIter<T>>;
fn into_deserializer(self) -> Self::Deserializer { fn into_deserializer(self) -> SeqDeserializer<vec::IntoIter<T>> {
let len = self.len(); let len = self.len();
SeqDeserializer::new(self.into_iter(), len) SeqDeserializer::new(self.into_iter(), len)
} }
} }
impl<T, E> ValueDeserializer<E> for BTreeSet<T> impl<T> ValueDeserializer for BTreeSet<T>
where T: ValueDeserializer<E> + Eq + Ord, where T: ValueDeserializer + Eq + Ord,
E: de::Error,
{ {
type Deserializer = SeqDeserializer<btree_set::IntoIter<T>, E>; type Deserializer = SeqDeserializer<btree_set::IntoIter<T>>;
fn into_deserializer(self) -> Self::Deserializer { fn into_deserializer(self) -> SeqDeserializer<btree_set::IntoIter<T>> {
let len = self.len(); let len = self.len();
SeqDeserializer::new(self.into_iter(), len) SeqDeserializer::new(self.into_iter(), len)
} }
} }
impl<T, E> ValueDeserializer<E> for HashSet<T> impl<T> ValueDeserializer for HashSet<T>
where T: ValueDeserializer<E> + Eq + Hash, where T: ValueDeserializer + Eq + Hash,
E: de::Error,
{ {
type Deserializer = SeqDeserializer<hash_set::IntoIter<T>, E>; type Deserializer = SeqDeserializer<hash_set::IntoIter<T>>;
fn into_deserializer(self) -> Self::Deserializer { fn into_deserializer(self) -> SeqDeserializer<hash_set::IntoIter<T>> {
let len = self.len(); let len = self.len();
SeqDeserializer::new(self.into_iter(), len) SeqDeserializer::new(self.into_iter(), len)
} }
@@ -399,92 +301,52 @@ impl<T, E> ValueDeserializer<E> for HashSet<T>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a sequence using a `SeqVisitor`. pub struct MapDeserializer<I, K, V>
pub struct SeqVisitorDeserializer<V_, E> {
visitor: V_,
marker: PhantomData<E>,
}
impl<V_, E> SeqVisitorDeserializer<V_, E>
where V_: de::SeqVisitor<Error = E>,
E: de::Error,
{
/// Construct a new `SeqVisitorDeserializer<V_, E>`.
pub fn new(visitor: V_) -> Self {
SeqVisitorDeserializer{
visitor: visitor,
marker: PhantomData
}
}
}
impl<V_, E> de::Deserializer for SeqVisitorDeserializer<V_, E>
where V_: de::SeqVisitor<Error = E>,
E: de::Error,
{
type Error = E;
fn deserialize<V: de::Visitor>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error> {
visitor.visit_seq(&mut self.visitor)
}
}
///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a map.
pub struct MapDeserializer<I, K, V, E>
where I: Iterator<Item=(K, V)>, where I: Iterator<Item=(K, V)>,
K: ValueDeserializer<E>, K: ValueDeserializer,
V: ValueDeserializer<E>, V: ValueDeserializer,
E: de::Error,
{ {
iter: I, iter: I,
value: Option<V>, value: Option<V>,
len: usize, len: usize,
marker: PhantomData<E>,
} }
impl<I, K, V, E> MapDeserializer<I, K, V, E> impl<I, K, V> MapDeserializer<I, K, V>
where I: Iterator<Item=(K, V)>, where I: Iterator<Item=(K, V)>,
K: ValueDeserializer<E>, K: ValueDeserializer,
V: ValueDeserializer<E>, V: ValueDeserializer,
E: de::Error,
{ {
/// Construct a new `MapDeserializer<I, K, V>`.
pub fn new(iter: I, len: usize) -> Self { pub fn new(iter: I, len: usize) -> Self {
MapDeserializer { MapDeserializer {
iter: iter, iter: iter,
value: None, value: None,
len: len, len: len,
marker: PhantomData,
} }
} }
} }
impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E> impl<I, K, V> de::Deserializer for MapDeserializer<I, K, V>
where I: Iterator<Item=(K, V)>, where I: Iterator<Item=(K, V)>,
K: ValueDeserializer<E>, K: ValueDeserializer,
V: ValueDeserializer<E>, V: ValueDeserializer,
E: de::Error,
{ {
type Error = E; type Error = Error;
fn deserialize<V_>(&mut self, mut visitor: V_) -> Result<V_::Value, Self::Error> fn visit<V_>(&mut self, mut visitor: V_) -> Result<V_::Value, Error>
where V_: de::Visitor, where V_: de::Visitor,
{ {
visitor.visit_map(self) visitor.visit_map(self)
} }
} }
impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E> impl<I, K, V> de::MapVisitor for MapDeserializer<I, K, V>
where I: Iterator<Item=(K, V)>, where I: Iterator<Item=(K, V)>,
K: ValueDeserializer<E>, K: ValueDeserializer,
V: ValueDeserializer<E>, V: ValueDeserializer,
E: de::Error,
{ {
type Error = E; type Error = Error;
fn visit_key<T>(&mut self) -> Result<Option<T>, Self::Error> fn visit_key<T>(&mut self) -> Result<Option<T>, Error>
where T: de::Deserialize, where T: de::Deserialize,
{ {
match self.iter.next() { match self.iter.next() {
@@ -498,7 +360,7 @@ impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
} }
} }
fn visit_value<T>(&mut self) -> Result<T, Self::Error> fn visit_value<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize, where T: de::Deserialize,
{ {
match self.value.take() { match self.value.take() {
@@ -506,17 +368,15 @@ impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
let mut de = value.into_deserializer(); let mut de = value.into_deserializer();
de::Deserialize::deserialize(&mut de) de::Deserialize::deserialize(&mut de)
} }
None => { None => Err(de::Error::syntax_error())
Err(de::Error::end_of_stream())
}
} }
} }
fn end(&mut self) -> Result<(), Self::Error> { fn end(&mut self) -> Result<(), Error> {
if self.len == 0 { if self.len == 0 {
Ok(()) Ok(())
} else { } else {
Err(de::Error::invalid_length(self.len)) Err(de::Error::end_of_stream_error())
} }
} }
@@ -527,27 +387,25 @@ impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
impl<K, V, E> ValueDeserializer<E> for BTreeMap<K, V> impl<K, V> ValueDeserializer for BTreeMap<K, V>
where K: ValueDeserializer<E> + Eq + Ord, where K: ValueDeserializer + Eq + Ord,
V: ValueDeserializer<E>, V: ValueDeserializer,
E: de::Error,
{ {
type Deserializer = MapDeserializer<btree_map::IntoIter<K, V>, K, V, E>; type Deserializer = MapDeserializer<btree_map::IntoIter<K, V>, K, V>;
fn into_deserializer(self) -> Self::Deserializer { fn into_deserializer(self) -> MapDeserializer<btree_map::IntoIter<K, V>, K, V> {
let len = self.len(); let len = self.len();
MapDeserializer::new(self.into_iter(), len) MapDeserializer::new(self.into_iter(), len)
} }
} }
impl<K, V, E> ValueDeserializer<E> for HashMap<K, V> impl<K, V> ValueDeserializer for HashMap<K, V>
where K: ValueDeserializer<E> + Eq + Hash, where K: ValueDeserializer + Eq + Hash,
V: ValueDeserializer<E>, V: ValueDeserializer,
E: de::Error,
{ {
type Deserializer = MapDeserializer<hash_map::IntoIter<K, V>, K, V, E>; type Deserializer = MapDeserializer<hash_map::IntoIter<K, V>, K, V>;
fn into_deserializer(self) -> Self::Deserializer { fn into_deserializer(self) -> MapDeserializer<hash_map::IntoIter<K, V>, K, V> {
let len = self.len(); let len = self.len();
MapDeserializer::new(self.into_iter(), len) MapDeserializer::new(self.into_iter(), len)
} }
@@ -555,62 +413,26 @@ impl<K, V, E> ValueDeserializer<E> for HashMap<K, V>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a map using a `MapVisitor`. impl<'a> ValueDeserializer for bytes::Bytes<'a>
pub struct MapVisitorDeserializer<V_, E> {
visitor: V_,
marker: PhantomData<E>,
}
impl<V_, E> MapVisitorDeserializer<V_, E>
where V_: de::MapVisitor<Error = E>,
E: de::Error,
{ {
/// Construct a new `MapVisitorDeserializer<V_, E>`. type Deserializer = BytesDeserializer<'a>;
pub fn new(visitor: V_) -> Self {
MapVisitorDeserializer{ fn into_deserializer(self) -> BytesDeserializer<'a> {
visitor: visitor, BytesDeserializer(Some(self.into()))
marker: PhantomData
}
} }
} }
impl<V_, E> de::Deserializer for MapVisitorDeserializer<V_, E> pub struct BytesDeserializer<'a> (Option<&'a [u8]>);
where V_: de::MapVisitor<Error = E>,
E: de::Error,
{
type Error = E;
fn deserialize<V: de::Visitor>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error> { impl<'a> de::Deserializer for BytesDeserializer<'a> {
visitor.visit_map(&mut self.visitor) type Error = Error;
}
}
/////////////////////////////////////////////////////////////////////////////// fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
impl<'a, E> ValueDeserializer<E> for bytes::Bytes<'a>
where E: de::Error,
{
type Deserializer = BytesDeserializer<'a, E>;
fn into_deserializer(self) -> BytesDeserializer<'a, E> {
BytesDeserializer(Some(self.into()), PhantomData)
}
}
/// A helper deserializer that deserializes a `&[u8]`.
pub struct BytesDeserializer<'a, E> (Option<&'a [u8]>, PhantomData<E>);
impl<'a, E> de::Deserializer for BytesDeserializer<'a, E>
where E: de::Error
{
type Error = E;
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.0.take() { match self.0.take() {
Some(bytes) => visitor.visit_bytes(bytes), Some(bytes) => visitor.visit_bytes(bytes),
None => Err(de::Error::end_of_stream()), None => Err(de::Error::end_of_stream_error()),
} }
} }
} }
@@ -618,30 +440,26 @@ impl<'a, E> de::Deserializer for BytesDeserializer<'a, E>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
impl<E> ValueDeserializer<E> for bytes::ByteBuf impl ValueDeserializer for bytes::ByteBuf
where E: de::Error,
{ {
type Deserializer = ByteBufDeserializer<E>; type Deserializer = ByteBufDeserializer;
fn into_deserializer(self) -> Self::Deserializer { fn into_deserializer(self) -> Self::Deserializer {
ByteBufDeserializer(Some(self.into()), PhantomData) ByteBufDeserializer(Some(self.into()))
} }
} }
/// A helper deserializer that deserializes a `Vec<u8>`. pub struct ByteBufDeserializer(Option<Vec<u8>>);
pub struct ByteBufDeserializer<E>(Option<Vec<u8>>, PhantomData<E>);
impl<E> de::Deserializer for ByteBufDeserializer<E> impl de::Deserializer for ByteBufDeserializer {
where E: de::Error, type Error = Error;
{
type Error = E;
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error> fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.0.take() { match self.0.take() {
Some(bytes) => visitor.visit_byte_buf(bytes), Some(bytes) => visitor.visit_byte_buf(bytes),
None => Err(de::Error::end_of_stream()), None => Err(de::Error::end_of_stream_error()),
} }
} }
} }
-4
View File
@@ -1,9 +1,6 @@
//! Module that contains helper iterators.
use std::io; use std::io;
use std::iter::Peekable; use std::iter::Peekable;
/// Iterator over a byte stream that tracks the current position's line and column.
pub struct LineColIterator<Iter: Iterator<Item=io::Result<u8>>> { pub struct LineColIterator<Iter: Iterator<Item=io::Result<u8>>> {
iter: Iter, iter: Iter,
line: usize, line: usize,
@@ -11,7 +8,6 @@ pub struct LineColIterator<Iter: Iterator<Item=io::Result<u8>>> {
} }
impl<Iter: Iterator<Item=io::Result<u8>>> LineColIterator<Iter> { impl<Iter: Iterator<Item=io::Result<u8>>> LineColIterator<Iter> {
/// Construct a new `LineColIterator<Iter>`.
pub fn new(iter: Iter) -> LineColIterator<Iter> { pub fn new(iter: Iter) -> LineColIterator<Iter> {
LineColIterator { LineColIterator {
iter: iter, iter: iter,
+84
View File
@@ -0,0 +1,84 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::collections::BTreeMap;
use ser::{self, Serialize};
use json::value::{self, Value};
pub struct ArrayBuilder {
array: Vec<Value>,
}
impl ArrayBuilder {
pub fn new() -> ArrayBuilder {
ArrayBuilder { array: Vec::new() }
}
pub fn unwrap(self) -> Value {
Value::Array(self.array)
}
pub fn push<T: ser::Serialize>(mut self, v: T) -> ArrayBuilder {
self.array.push(value::to_value(&v));
self
}
pub fn push_array<F>(mut self, f: F) -> ArrayBuilder where
F: FnOnce(ArrayBuilder) -> ArrayBuilder
{
let builder = ArrayBuilder::new();
self.array.push(f(builder).unwrap());
self
}
pub fn push_object<F>(mut self, f: F) -> ArrayBuilder where
F: FnOnce(ObjectBuilder) -> ObjectBuilder
{
let builder = ObjectBuilder::new();
self.array.push(f(builder).unwrap());
self
}
}
pub struct ObjectBuilder {
object: BTreeMap<String, Value>,
}
impl ObjectBuilder {
pub fn new() -> ObjectBuilder {
ObjectBuilder { object: BTreeMap::new() }
}
pub fn unwrap(self) -> Value {
Value::Object(self.object)
}
pub fn insert<V: ser::Serialize>(mut self, k: String, v: V) -> ObjectBuilder {
self.object.insert(k, value::to_value(&v));
self
}
pub fn insert_array<F>(mut self, key: String, f: F) -> ObjectBuilder where
F: FnOnce(ArrayBuilder) -> ArrayBuilder
{
let builder = ArrayBuilder::new();
self.object.insert(key, f(builder).unwrap());
self
}
pub fn insert_object<F>(mut self, key: String, f: F) -> ObjectBuilder where
F: FnOnce(ObjectBuilder) -> ObjectBuilder
{
let builder = ObjectBuilder::new();
self.object.insert(key, f(builder).unwrap());
self
}
}
+694
View File
@@ -0,0 +1,694 @@
use std::char;
use std::i32;
use std::io;
use std::str;
use de;
use iter::LineColIterator;
use super::error::{Error, ErrorCode};
pub struct Deserializer<Iter: Iterator<Item=io::Result<u8>>> {
rdr: LineColIterator<Iter>,
ch: Option<u8>,
str_buf: Vec<u8>,
}
macro_rules! try_or_invalid {
($self_:expr, $e:expr) => {
match $e {
Some(v) => v,
None => { return Err($self_.error(ErrorCode::InvalidNumber)); }
}
}
}
impl<Iter> Deserializer<Iter>
where Iter: Iterator<Item=io::Result<u8>>,
{
/// Creates the JSON parser from an `std::iter::Iterator`.
#[inline]
pub fn new(rdr: Iter) -> Result<Deserializer<Iter>, Error> {
let mut deserializer = 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> {
try!(self.parse_whitespace());
if 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 next_char(&mut self) -> Result<Option<u8>, Error> {
try!(self.bump());
Ok(self.ch)
}
fn ch_is(&self, c: u8) -> bool {
self.ch == Some(c)
}
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_value<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
try!(self.parse_whitespace());
if self.eof() {
return Err(self.error(ErrorCode::EOFWhileParsingValue));
}
let value = match self.ch_or_null() {
b'n' => {
try!(self.parse_ident(b"ull"));
visitor.visit_unit()
}
b't' => {
try!(self.parse_ident(b"rue"));
visitor.visit_bool(true)
}
b'f' => {
try!(self.parse_ident(b"alse"));
visitor.visit_bool(false)
}
b'0' ... b'9' | b'-' => self.parse_number(visitor),
b'"' => {
try!(self.parse_string());
let s = str::from_utf8(&self.str_buf).unwrap();
visitor.visit_str(s)
}
b'[' => {
try!(self.bump());
visitor.visit_seq(SeqVisitor::new(self))
}
b'{' => {
try!(self.bump());
visitor.visit_map(MapVisitor::new(self))
}
_ => {
Err(self.error(ErrorCode::ExpectedSomeValue))
}
};
match value {
Ok(value) => Ok(value),
Err(Error::SyntaxError(code, _, _)) => Err(self.error(code)),
Err(err) => Err(err),
}
}
fn parse_ident(&mut self, ident: &[u8]) -> Result<(), Error> {
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>
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() {
b'0' => {
try!(self.bump());
// There can be only one leading '0'.
match self.ch_or_null() {
b'0' ... b'9' => {
return Err(self.error(ErrorCode::InvalidNumber));
}
_ => ()
}
},
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)));
try!(self.bump());
}
_ => break,
}
}
}
_ => { return Err(self.error(ErrorCode::InvalidNumber)); }
}
Ok(accum)
}
fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> {
try!(self.bump());
// Make sure a digit follows the decimal place.
match self.ch_or_null() {
b'0' ... b'9' => (),
_ => { return Err(self.error(ErrorCode::InvalidNumber)); }
}
let mut res = res;
let mut dec = 1.0;
while !self.eof() {
match self.ch_or_null() {
c @ b'0' ... b'9' => {
dec /= 10.0;
res += (((c as u64) - (b'0' as u64)) as f64) * dec;
try!(self.bump());
}
_ => break,
}
}
Ok(res)
}
fn parse_exponent(&mut self, mut res: f64) -> Result<f64, Error> {
try!(self.bump());
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;
}
// Make sure a digit follows the exponent place.
match self.ch_or_null() {
b'0' ... b'9' => (),
_ => { return Err(self.error(ErrorCode::InvalidNumber)); }
}
while !self.eof() {
match self.ch_or_null() {
c @ b'0' ... b'9' => {
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
}
}
let exp = if exp <= i32::MAX as u64 {
10_f64.powi(exp as i32)
} else {
return Err(self.error(ErrorCode::InvalidNumber));
};
if neg_exp {
res /= exp;
} else {
res *= exp;
}
Ok(res)
}
fn decode_hex_escape(&mut self) -> Result<u16, Error> {
let mut i = 0;
let mut n = 0u16;
while i < 4 && !self.eof() {
try!(self.bump());
n = match self.ch_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,
b'c' | b'C' => n * 16_u16 + 12_u16,
b'd' | b'D' => n * 16_u16 + 13_u16,
b'e' | b'E' => n * 16_u16 + 14_u16,
b'f' | b'F' => n * 16_u16 + 15_u16,
_ => { return Err(self.error(ErrorCode::InvalidEscape)); }
};
i += 1;
}
// Error out if we didn't parse 4 digits.
if i != 4 {
return Err(self.error(ErrorCode::InvalidEscape));
}
Ok(n)
}
fn parse_string(&mut self) -> Result<(), Error> {
self.str_buf.clear();
loop {
let ch = match try!(self.next_char()) {
Some(ch) => ch,
None => { return Err(self.error(ErrorCode::EOFWhileParsingString)); }
};
match ch {
b'"' => {
try!(self.bump());
return Ok(());
}
b'\\' => {
let ch = match try!(self.next_char()) {
Some(ch) => ch,
None => { return Err(self.error(ErrorCode::EOFWhileParsingString)); }
};
match ch {
b'"' => self.str_buf.push(b'"'),
b'\\' => self.str_buf.push(b'\\'),
b'/' => self.str_buf.push(b'/'),
b'b' => self.str_buf.push(b'\x08'),
b'f' => self.str_buf.push(b'\x0c'),
b'n' => self.str_buf.push(b'\n'),
b'r' => self.str_buf.push(b'\r'),
b't' => self.str_buf.push(b'\t'),
b'u' => {
let c = match try!(self.decode_hex_escape()) {
0xDC00 ... 0xDFFF => {
return Err(self.error(ErrorCode::LoneLeadingSurrogateInHexEscape));
}
// Non-BMP characters are encoded as a sequence of
// two hex escapes, representing UTF-16 surrogates.
n1 @ 0xD800 ... 0xDBFF => {
match (try!(self.next_char()), try!(self.next_char())) {
(Some(b'\\'), Some(b'u')) => (),
_ => {
return Err(self.error(ErrorCode::UnexpectedEndOfHexEscape));
}
}
let n2 = try!(self.decode_hex_escape());
if n2 < 0xDC00 || n2 > 0xDFFF {
return Err(self.error(ErrorCode::LoneLeadingSurrogateInHexEscape));
}
let n = (((n1 - 0xD800) as u32) << 10 |
(n2 - 0xDC00) as u32) + 0x1_0000;
match char::from_u32(n as u32) {
Some(c) => c,
None => {
return Err(self.error(ErrorCode::InvalidUnicodeCodePoint));
}
}
}
n => {
match char::from_u32(n as u32) {
Some(c) => c,
None => {
return Err(self.error(ErrorCode::InvalidUnicodeCodePoint));
}
}
}
};
// FIXME: this allocation is required in order to be compatible with stable
// rust, which doesn't support encoding a `char` into a stack buffer.
let buf = c.to_string();
self.str_buf.extend(buf.bytes());
}
_ => {
return Err(self.error(ErrorCode::InvalidEscape));
}
}
}
ch => {
self.str_buf.push(ch);
}
}
}
}
fn parse_object_colon(&mut self) -> Result<(), Error> {
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))
}
}
}
impl<Iter> de::Deserializer for Deserializer<Iter>
where Iter: Iterator<Item=io::Result<u8>>,
{
type Error = Error;
#[inline]
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
self.parse_value(visitor)
}
#[inline]
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
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)
}
}
#[inline]
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
try!(self.parse_whitespace());
if self.ch_is(b'{') {
try!(self.bump());
try!(self.parse_whitespace());
let value = {
try!(visitor.visit(&mut *self))
};
try!(self.parse_whitespace());
if self.ch_is(b'}') {
try!(self.bump());
Ok(value)
} else {
Err(self.error(ErrorCode::ExpectedSomeValue))
}
} else {
Err(self.error(ErrorCode::ExpectedSomeValue))
}
}
#[inline]
fn format() -> &'static str {
"json"
}
}
struct SeqVisitor<'a, Iter: 'a + Iterator<Item=io::Result<u8>>> {
de: &'a mut Deserializer<Iter>,
first: bool,
}
impl<'a, Iter: Iterator<Item=io::Result<u8>>> SeqVisitor<'a, Iter> {
fn new(de: &'a mut Deserializer<Iter>) -> Self {
SeqVisitor {
de: de,
first: true,
}
}
}
impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
where Iter: Iterator<Item=io::Result<u8>>,
{
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
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() {
return Err(self.de.error(ErrorCode::EOFWhileParsingList));
} else {
return Err(self.de.error(ErrorCode::ExpectedListCommaOrEnd));
}
}
let value = try!(de::Deserialize::deserialize(self.de));
Ok(Some(value))
}
fn end(&mut self) -> Result<(), Error> {
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))
}
}
}
struct MapVisitor<'a, Iter: 'a + Iterator<Item=io::Result<u8>>> {
de: &'a mut Deserializer<Iter>,
first: bool,
}
impl<'a, Iter: Iterator<Item=io::Result<u8>>> MapVisitor<'a, Iter> {
fn new(de: &'a mut Deserializer<Iter>) -> Self {
MapVisitor {
de: de,
first: true,
}
}
}
impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
where Iter: Iterator<Item=io::Result<u8>>
{
type Error = Error;
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
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());
try!(self.de.parse_whitespace());
} else if self.de.eof() {
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));
}
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>
where V: de::Deserialize,
{
try!(self.de.parse_object_colon());
Ok(try!(de::Deserialize::deserialize(self.de)))
}
fn end(&mut self) -> Result<(), Error> {
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))
}
}
fn missing_field<V>(&mut self, _field: &'static str) -> Result<V, Error>
where V: de::Deserialize,
{
let mut de = de::value::ValueDeserializer::into_deserializer(());
Ok(try!(de::Deserialize::deserialize(&mut de)))
}
}
impl<Iter> de::VariantVisitor for Deserializer<Iter>
where Iter: Iterator<Item=io::Result<u8>>,
{
type Error = Error;
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize
{
de::Deserialize::deserialize(self)
}
fn visit_unit(&mut self) -> Result<(), Error> {
try!(self.parse_object_colon());
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
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>
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>
where I: Iterator<Item=io::Result<u8>>,
T: de::Deserialize,
{
let mut de = try!(Deserializer::new(iter));
let value = try!(de::Deserialize::deserialize(&mut de));
// Make sure the whole stream has been consumed.
try!(de.end());
Ok(value)
}
/// Decodes a json value from a `std::io::Read`.
pub fn from_reader<R, T>(rdr: R) -> Result<T, Error>
where R: io::Read,
T: de::Deserialize,
{
from_iter(rdr.bytes())
}
/// Decodes a json value from a `&str`.
pub fn from_slice<T>(v: &[u8]) -> Result<T, Error>
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>
where T: de::Deserialize
{
from_slice(s.as_bytes())
}
+185
View File
@@ -0,0 +1,185 @@
use std::error;
use std::fmt;
use std::io;
use de;
/// The errors that can arise while parsing a JSON stream.
#[derive(Clone, PartialEq)]
pub enum ErrorCode {
EOFWhileParsingList,
EOFWhileParsingObject,
EOFWhileParsingString,
EOFWhileParsingValue,
ExpectedColon,
ExpectedConversion,
ExpectedEnumEnd,
ExpectedEnumEndToken,
ExpectedEnumMapStart,
ExpectedEnumToken,
ExpectedEnumVariantString,
ExpectedListCommaOrEnd,
ExpectedName,
ExpectedObjectCommaOrEnd,
ExpectedSomeIdent,
ExpectedSomeValue,
InvalidEscape,
InvalidNumber,
InvalidUnicodeCodePoint,
KeyMustBeAString,
LoneLeadingSurrogateInHexEscape,
UnknownField(String),
MissingField(&'static str),
NotFourDigit,
NotUtf8,
TrailingCharacters,
UnexpectedEndOfHexEscape,
UnknownVariant,
UnrecognizedHex,
}
impl fmt::Debug for ErrorCode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use std::fmt::Debug;
match *self {
//ErrorCode::ConversionError(ref token) => write!(f, "failed to convert {}", token),
ErrorCode::EOFWhileParsingList => "EOF While parsing list".fmt(f),
ErrorCode::EOFWhileParsingObject => "EOF While parsing object".fmt(f),
ErrorCode::EOFWhileParsingString => "EOF While parsing string".fmt(f),
ErrorCode::EOFWhileParsingValue => "EOF While parsing value".fmt(f),
ErrorCode::ExpectedColon => "expected `:`".fmt(f),
ErrorCode::ExpectedConversion => "expected conversion".fmt(f),
ErrorCode::ExpectedEnumEnd => "expected enum end".fmt(f),
ErrorCode::ExpectedEnumEndToken => "expected enum map end".fmt(f),
ErrorCode::ExpectedEnumMapStart => "expected enum map start".fmt(f),
ErrorCode::ExpectedEnumToken => "expected enum token".fmt(f),
ErrorCode::ExpectedEnumVariantString => "expected variant".fmt(f),
ErrorCode::ExpectedListCommaOrEnd => "expected `,` or `]`".fmt(f),
ErrorCode::ExpectedName => "expected name".fmt(f),
ErrorCode::ExpectedObjectCommaOrEnd => "expected `,` or `}`".fmt(f),
ErrorCode::ExpectedSomeIdent => "expected ident".fmt(f),
ErrorCode::ExpectedSomeValue => "expected value".fmt(f),
//ErrorCode::ExpectedTokens(ref token, tokens) => write!(f, "expected {}, found {}", tokens, token),
ErrorCode::InvalidEscape => "invalid escape".fmt(f),
ErrorCode::InvalidNumber => "invalid number".fmt(f),
ErrorCode::InvalidUnicodeCodePoint => "invalid unicode code point".fmt(f),
ErrorCode::KeyMustBeAString => "key must be a string".fmt(f),
ErrorCode::LoneLeadingSurrogateInHexEscape => "lone leading surrogate in hex escape".fmt(f),
ErrorCode::UnknownField(ref field) => write!(f, "unknown field \"{}\"", field),
ErrorCode::MissingField(ref field) => write!(f, "missing field \"{}\"", field),
ErrorCode::NotFourDigit => "invalid \\u escape (not four digits)".fmt(f),
ErrorCode::NotUtf8 => "contents not utf-8".fmt(f),
ErrorCode::TrailingCharacters => "trailing characters".fmt(f),
ErrorCode::UnexpectedEndOfHexEscape => "unexpected end of hex escape".fmt(f),
//ErrorCode::UnexpectedName(ref name) => write!(f, "unexpected name {}", name),
ErrorCode::UnknownVariant => "unknown variant".fmt(f),
ErrorCode::UnrecognizedHex => "invalid \\u escape (unrecognized hex)".fmt(f),
}
}
}
#[derive(Debug)]
pub enum Error {
/// msg, line, col
SyntaxError(ErrorCode, usize, usize),
IoError(io::Error),
/*
ExpectedError(String, String),
*/
MissingFieldError(&'static str),
/*
UnknownVariantError(String),
*/
}
impl error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::SyntaxError(..) => "syntax error",
Error::IoError(ref error) => error::Error::description(error),
/*
Error::ExpectedError(ref expected, _) => &expected,
*/
Error::MissingFieldError(_) => "missing field",
/*
Error::UnknownVariantError(_) => "unknown variant",
*/
}
}
fn cause(&self) -> Option<&error::Error> {
match *self {
Error::IoError(ref error) => Some(error),
_ => None,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::SyntaxError(ref code, line, col) => {
write!(fmt, "{:?} at line {} column {}", code, line, col)
}
Error::IoError(ref error) => fmt::Display::fmt(error, fmt),
/*
Error::ExpectedError(ref expected, ref found) => {
Some(format!("expected {}, found {}", expected, found))
}
*/
Error::MissingFieldError(ref field) => {
write!(fmt, "missing field {}", field)
}
/*
Error::UnknownVariantError(ref variant) => {
Some(format!("unknown variant {}", variant))
}
*/
}
}
}
impl From<io::Error> for Error {
fn from(error: io::Error) -> Error {
Error::IoError(error)
}
}
impl From<de::value::Error> for Error {
fn from(error: de::value::Error) -> Error {
match error {
de::value::Error::SyntaxError => {
de::Error::syntax_error()
}
de::value::Error::EndOfStreamError => {
de::Error::end_of_stream_error()
}
de::value::Error::UnknownFieldError(field) => {
Error::SyntaxError(ErrorCode::UnknownField(field), 0, 0)
}
de::value::Error::MissingFieldError(field) => {
de::Error::missing_field_error(field)
}
}
}
}
impl de::Error for Error {
fn syntax_error() -> Error {
Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)
}
fn end_of_stream_error() -> Error {
Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 0, 0)
}
fn unknown_field_error(field: &str) -> Error {
Error::SyntaxError(ErrorCode::UnknownField(field.to_string()), 0, 0)
}
fn missing_field_error(field: &'static str) -> Error {
Error::MissingFieldError(field)
}
}
+113
View File
@@ -0,0 +1,113 @@
//! JSON and serialization
//!
//! # What is JSON?
//!
//! JSON (JavaScript Object Notation) is a way to write data in JavaScript. Like XML, it allows to
//! 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
//! details):
//!
//! * `Boolean`: equivalent to rust's `bool`
//! * `I64`: equivalent to rust's `i64`
//! * `U64`: equivalent to rust's `u64`
//! * `F64`: equivalent to rust's `i64`
//! * `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>`
//! * `Null`
//!
//! An object is a series of string keys mapping to values, in `"key": value` format. Arrays are
//! enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }). A simple JSON
//! document encoding a person, his/her age, address and phone numbers could look like
//!
//! ```ignore
//! {
//! "FirstName": "John",
//! "LastName": "Doe",
//! "Age": 43,
//! "Address": {
//! "Street": "Downing Street 10",
//! "City": "London",
//! "Country": "Great Britain"
//! },
//! "PhoneNumbers": [
//! "+44 1234567",
//! "+44 2345678"
//! ]
//! }
//! ```
//!
//! # Type-based Serialization and Deserialization
//!
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
//! from JSON via the serialization API. To be able to serialize a piece of data, it must implement
//! the `serde::Serialize` trait. To be able to deserialize a piece of data, it must implement the
//! `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
//! functions described above. You can also use the `json::Serializer` object, which implements the
//! `Serializer` trait.
//!
//! # Examples of use
//!
//! ## Parsing a `str` to `Value` and reading the result
//!
//! ```rust
//! //#![feature(custom_derive, plugin)]
//! //#![plugin(serde_macros)]
//!
//! extern crate serde;
//!
//! use serde::json::{self, Value};
//!
//! fn main() {
//! let data: Value = json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap();
//! println!("data: {:?}", data);
//! // data: {"bar":"baz","foo":13}
//! println!("object? {}", data.is_object());
//! // object? true
//!
//! let obj = data.as_object().unwrap();
//! let foo = obj.get("foo").unwrap();
//!
//! println!("array? {:?}", foo.as_array());
//! // array? None
//! println!("u64? {:?}", foo.as_u64());
//! // u64? Some(13u64)
//!
//! for (key, value) in obj.iter() {
//! println!("{}: {}", key, match *value {
//! Value::U64(v) => format!("{} (u64)", v),
//! Value::String(ref v) => format!("{} (string)", v),
//! _ => format!("other")
//! });
//! }
//! // bar: baz (string)
//! // foo: 13 (u64)
//! }
//! ```
pub use self::de::{Deserializer, from_str};
pub use self::error::{Error, ErrorCode};
pub use self::ser::{
Serializer,
to_writer,
to_writer_pretty,
to_vec,
to_vec_pretty,
to_string,
to_string_pretty,
escape_str,
};
pub use self::value::{Value, to_value, from_value};
pub mod builder;
pub mod de;
pub mod error;
pub mod ser;
pub mod value;
+524
View File
@@ -0,0 +1,524 @@
use std::io;
use std::num::FpCategory;
use std::string::FromUtf8Error;
use ser;
/// A structure for implementing serialization to JSON.
pub struct Serializer<W, F=CompactFormatter> {
writer: W,
formatter: F,
/// `first` is used to signify if we should print a comma when we are walking through a
/// sequence.
first: bool,
}
impl<W> Serializer<W>
where W: io::Write,
{
/// Creates a new JSON serializer.
#[inline]
pub fn new(writer: W) -> Self {
Serializer::with_formatter(writer, CompactFormatter)
}
}
impl<'a, W> Serializer<W, PrettyFormatter<'a>>
where W: io::Write,
{
/// Creates a new JSON pretty print serializer.
#[inline]
pub fn pretty(writer: W) -> Self {
Serializer::with_formatter(writer, PrettyFormatter::new())
}
}
impl<W, F> Serializer<W, F>
where W: io::Write,
F: Formatter,
{
/// Creates a new JSON visitor whose output will be written to the writer
/// specified.
#[inline]
pub fn with_formatter(writer: W, formatter: F) -> Self {
Serializer {
writer: writer,
formatter: formatter,
first: false,
}
}
/// Unwrap the `Writer` from the `Serializer`.
#[inline]
pub fn into_inner(self) -> W {
self.writer
}
}
impl<W, F> ser::Serializer for Serializer<W, F>
where W: io::Write,
F: Formatter,
{
type Error = io::Error;
#[inline]
fn visit_bool(&mut self, value: bool) -> io::Result<()> {
if value {
self.writer.write_all(b"true")
} else {
self.writer.write_all(b"false")
}
}
#[inline]
fn visit_isize(&mut self, value: isize) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i8(&mut self, value: i8) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i16(&mut self, value: i16) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i32(&mut self, value: i32) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i64(&mut self, value: i64) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_usize(&mut self, value: usize) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u8(&mut self, value: u8) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u16(&mut self, value: u16) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u32(&mut self, value: u32) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u64(&mut self, value: u64) -> io::Result<()> {
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_f32(&mut self, value: f32) -> io::Result<()> {
fmt_f32_or_null(&mut self.writer, value)
}
#[inline]
fn visit_f64(&mut self, value: f64) -> io::Result<()> {
fmt_f64_or_null(&mut self.writer, value)
}
#[inline]
fn visit_char(&mut self, value: char) -> io::Result<()> {
escape_char(&mut self.writer, value)
}
#[inline]
fn visit_str(&mut self, value: &str) -> io::Result<()> {
escape_str(&mut self.writer, value)
}
#[inline]
fn visit_none(&mut self) -> io::Result<()> {
self.visit_unit()
}
#[inline]
fn visit_some<V>(&mut self, value: V) -> io::Result<()>
where V: ser::Serialize
{
value.serialize(self)
}
#[inline]
fn visit_unit(&mut self) -> io::Result<()> {
self.writer.write_all(b"null")
}
#[inline]
fn visit_enum_unit(&mut self, _name: &str, 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));
try!(self.formatter.colon(&mut self.writer));
try!(self.writer.write_all(b"[]"));
self.formatter.close(&mut self.writer, b'}')
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> io::Result<()>
where V: ser::SeqVisitor,
{
match visitor.len() {
Some(len) if len == 0 => {
self.writer.write_all(b"[]")
}
_ => {
try!(self.formatter.open(&mut self.writer, b'['));
self.first = true;
while let Some(()) = try!(visitor.visit(self)) { }
self.formatter.close(&mut self.writer, b']')
}
}
}
#[inline]
fn visit_enum_seq<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
where V: ser::SeqVisitor,
{
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!(self.visit_seq(visitor));
self.formatter.close(&mut self.writer, b'}')
}
#[inline]
fn visit_seq_elt<T>(&mut self, value: T) -> io::Result<()>
where T: ser::Serialize,
{
try!(self.formatter.comma(&mut self.writer, self.first));
self.first = false;
value.serialize(self)
}
#[inline]
fn visit_map<V>(&mut self, mut visitor: V) -> io::Result<()>
where V: ser::MapVisitor,
{
match visitor.len() {
Some(len) if len == 0 => {
self.writer.write_all(b"{}")
}
_ => {
try!(self.formatter.open(&mut self.writer, b'{'));
self.first = true;
while let Some(()) = try!(visitor.visit(self)) { }
self.formatter.close(&mut self.writer, b'}')
}
}
}
#[inline]
fn visit_enum_map<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
where V: ser::MapVisitor,
{
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!(self.visit_map(visitor));
self.formatter.close(&mut self.writer, b'}')
}
#[inline]
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> io::Result<()>
where K: ser::Serialize,
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)
}
#[inline]
fn format() -> &'static str {
"json"
}
}
pub trait Formatter {
fn open<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write;
fn comma<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where W: io::Write;
fn colon<W>(&mut self, writer: &mut W) -> io::Result<()>
where W: io::Write;
fn close<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write;
}
pub struct CompactFormatter;
impl Formatter for CompactFormatter {
fn open<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write,
{
writer.write_all(&[ch])
}
fn comma<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where W: io::Write,
{
if first {
Ok(())
} else {
writer.write_all(b",")
}
}
fn colon<W>(&mut self, writer: &mut W) -> io::Result<()>
where W: io::Write,
{
writer.write_all(b":")
}
fn close<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write,
{
writer.write_all(&[ch])
}
}
pub struct PrettyFormatter<'a> {
current_indent: usize,
indent: &'a [u8],
}
impl<'a> PrettyFormatter<'a> {
fn new() -> Self {
PrettyFormatter::with_indent(b" ")
}
fn with_indent(indent: &'a [u8]) -> Self {
PrettyFormatter {
current_indent: 0,
indent: indent,
}
}
}
impl<'a> Formatter for PrettyFormatter<'a> {
fn open<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write,
{
self.current_indent += 1;
writer.write_all(&[ch])
}
fn comma<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
where W: io::Write,
{
if first {
try!(writer.write_all(b"\n"));
} else {
try!(writer.write_all(b",\n"));
}
indent(writer, self.current_indent, self.indent)
}
fn colon<W>(&mut self, writer: &mut W) -> io::Result<()>
where W: io::Write,
{
writer.write_all(b": ")
}
fn close<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write,
{
self.current_indent -= 1;
try!(writer.write(b"\n"));
try!(indent(writer, self.current_indent, self.indent));
writer.write_all(&[ch])
}
}
#[inline]
pub fn escape_bytes<W>(wr: &mut W, bytes: &[u8]) -> io::Result<()>
where W: io::Write
{
try!(wr.write_all(b"\""));
let mut start = 0;
for (i, byte) in bytes.iter().enumerate() {
let escaped = match *byte {
b'"' => b"\\\"",
b'\\' => b"\\\\",
b'\x08' => b"\\b",
b'\x0c' => b"\\f",
b'\n' => b"\\n",
b'\r' => b"\\r",
b'\t' => b"\\t",
_ => { continue; }
};
if start < i {
try!(wr.write_all(&bytes[start..i]));
}
try!(wr.write_all(escaped));
start = i + 1;
}
if start != bytes.len() {
try!(wr.write_all(&bytes[start..]));
}
try!(wr.write_all(b"\""));
Ok(())
}
#[inline]
pub fn escape_str<W>(wr: &mut W, value: &str) -> io::Result<()>
where W: io::Write
{
escape_bytes(wr, value.as_bytes())
}
#[inline]
fn escape_char<W>(wr: &mut W, value: char) -> io::Result<()>
where W: io::Write
{
// FIXME: this allocation is required in order to be compatible with stable
// rust, which doesn't support encoding a `char` into a stack buffer.
escape_bytes(wr, value.to_string().as_bytes())
}
fn fmt_f32_or_null<W>(wr: &mut W, value: f32) -> io::Result<()>
where W: io::Write
{
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(())
}
}
}
fn fmt_f64_or_null<W>(wr: &mut W, value: f64) -> io::Result<()>
where W: io::Write
{
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(())
}
}
}
/// Encode the specified struct into a json `[u8]` writer.
#[inline]
pub fn to_writer<W, T>(writer: &mut W, value: &T) -> io::Result<()>
where W: io::Write,
T: ser::Serialize,
{
let mut ser = Serializer::new(writer);
try!(value.serialize(&mut ser));
Ok(())
}
/// Encode the specified struct into a json `[u8]` writer.
#[inline]
pub fn to_writer_pretty<W, T>(writer: &mut W, value: &T) -> io::Result<()>
where W: io::Write,
T: ser::Serialize,
{
let mut ser = Serializer::pretty(writer);
try!(value.serialize(&mut ser));
Ok(())
}
/// Encode the specified struct into a json `[u8]` buffer.
#[inline]
pub fn to_vec<T>(value: &T) -> Vec<u8>
where T: ser::Serialize,
{
// We are writing to a Vec, which doesn't fail. So we can ignore
// the error.
let mut writer = Vec::with_capacity(128);
to_writer(&mut writer, value).unwrap();
writer
}
/// Encode the specified struct into a json `[u8]` buffer.
#[inline]
pub fn to_vec_pretty<T>(value: &T) -> Vec<u8>
where T: ser::Serialize,
{
// We are writing to a Vec, which doesn't fail. So we can ignore
// the error.
let mut writer = Vec::with_capacity(128);
to_writer_pretty(&mut writer, value).unwrap();
writer
}
/// Encode the specified struct into a json `String` buffer.
#[inline]
pub fn to_string<T>(value: &T) -> Result<String, FromUtf8Error>
where T: ser::Serialize
{
let vec = to_vec(value);
String::from_utf8(vec)
}
/// Encode the specified struct into a json `String` buffer.
#[inline]
pub fn to_string_pretty<T>(value: &T) -> Result<String, FromUtf8Error>
where T: ser::Serialize
{
let vec = to_vec_pretty(value);
String::from_utf8(vec)
}
fn indent<W>(wr: &mut W, n: usize, s: &[u8]) -> io::Result<()>
where W: io::Write,
{
for _ in 0 .. n {
try!(wr.write_all(s));
}
Ok(())
}
+915
View File
@@ -0,0 +1,915 @@
use std::collections::{BTreeMap, btree_map};
use std::fmt;
use std::io;
use std::str;
use std::vec;
use num::NumCast;
use de;
use ser;
use super::error::Error;
#[derive(Clone, PartialEq)]
pub enum Value {
Null,
Bool(bool),
I64(i64),
U64(u64),
F64(f64),
String(String),
Array(Vec<Value>),
Object(BTreeMap<String, Value>),
}
impl Value {
/// If the `Value` is an Object, returns the value associated with the provided key.
/// Otherwise, returns None.
pub fn find<'a>(&'a self, key: &str) -> Option<&'a Value>{
match self {
&Value::Object(ref map) => map.get(key),
_ => None
}
}
/// Attempts to get a nested Value Object for each key in `keys`.
/// If any key is found not to exist, find_path will return None.
/// Otherwise, it will return the `Value` associated with the final key.
pub fn find_path<'a>(&'a self, keys: &[&str]) -> Option<&'a Value>{
let mut target = self;
for key in keys {
match target.find(key) {
Some(t) => { target = t; },
None => return None
}
}
Some(target)
}
/// Looks up a value by path.
///
/// This is a convenience method that splits the path by `'.'`
/// and then feeds the sequence of keys into the `find_path`
/// method.
///
/// ``` ignore
/// let obj: Value = json::from_str(r#"{"x": {"a": 1}}"#).unwrap();
///
/// assert!(obj.lookup("x.a").unwrap() == &Value::U64(1));
/// ```
pub fn lookup<'a>(&'a self, path: &str) -> Option<&'a Value> {
let mut target = self;
for key in path.split('.') {
match target.find(key) {
Some(t) => { target = t; },
None => return None
}
}
Some(target)
}
/// If the `Value` is an Object, performs a depth-first search until
/// a value associated with the provided key is found. If no value is found
/// or the `Value` is not an Object, returns None.
pub fn search<'a>(&'a self, key: &str) -> Option<&'a Value> {
match self {
&Value::Object(ref map) => {
match map.get(key) {
Some(json_value) => Some(json_value),
None => {
for (_, v) in map.iter() {
match v.search(key) {
x if x.is_some() => return x,
_ => ()
}
}
None
}
}
},
_ => None
}
}
/// Returns true if the `Value` is an Object. Returns false otherwise.
pub fn is_object<'a>(&'a self) -> bool {
self.as_object().is_some()
}
/// If the `Value` is an Object, returns the associated BTreeMap.
/// Returns None otherwise.
pub fn as_object<'a>(&'a self) -> Option<&'a BTreeMap<String, Value>> {
match self {
&Value::Object(ref map) => Some(map),
_ => None
}
}
/// If the `Value` is an Object, returns the associated mutable BTreeMap.
/// Returns None otherwise.
pub fn as_object_mut<'a>(&'a mut self) -> Option<&'a mut BTreeMap<String, Value>> {
match self {
&mut Value::Object(ref mut map) => Some(map),
_ => None
}
}
/// Returns true if the `Value` is an Array. Returns false otherwise.
pub fn is_array<'a>(&'a self) -> bool {
self.as_array().is_some()
}
/// If the `Value` is an Array, returns the associated vector.
/// Returns None otherwise.
pub fn as_array<'a>(&'a self) -> Option<&'a Vec<Value>> {
match self {
&Value::Array(ref array) => Some(&*array),
_ => None
}
}
/// If the `Value` is an Array, returns the associated mutable vector.
/// Returns None otherwise.
pub fn as_array_mut<'a>(&'a mut self) -> Option<&'a mut Vec<Value>> {
match self {
&mut Value::Array(ref mut list) => Some(list),
_ => None
}
}
/// Returns true if the `Value` is a String. Returns false otherwise.
pub fn is_string<'a>(&'a self) -> bool {
self.as_string().is_some()
}
/// If the `Value` is a String, returns the associated str.
/// Returns None otherwise.
pub fn as_string<'a>(&'a self) -> Option<&'a str> {
match *self {
Value::String(ref s) => Some(&s),
_ => None
}
}
/// Returns true if the `Value` is a Number. Returns false otherwise.
pub fn is_number(&self) -> bool {
match *self {
Value::I64(_) | Value::U64(_) | Value::F64(_) => true,
_ => false,
}
}
/// Returns true if the `Value` is a i64. Returns false otherwise.
pub fn is_i64(&self) -> bool {
match *self {
Value::I64(_) => true,
_ => false,
}
}
/// Returns true if the `Value` is a u64. Returns false otherwise.
pub fn is_u64(&self) -> bool {
match *self {
Value::U64(_) => true,
_ => false,
}
}
/// Returns true if the `Value` is a f64. Returns false otherwise.
pub fn is_f64(&self) -> bool {
match *self {
Value::F64(_) => true,
_ => false,
}
}
/// If the `Value` is a number, return or cast it to a i64.
/// Returns None otherwise.
pub fn as_i64(&self) -> Option<i64> {
match *self {
Value::I64(n) => Some(n),
Value::U64(n) => NumCast::from(n),
_ => None
}
}
/// If the `Value` is a number, return or cast it to a u64.
/// Returns None otherwise.
pub fn as_u64(&self) -> Option<u64> {
match *self {
Value::I64(n) => NumCast::from(n),
Value::U64(n) => Some(n),
_ => None
}
}
/// If the `Value` is a number, return or cast it to a f64.
/// Returns None otherwise.
pub fn as_f64(&self) -> Option<f64> {
match *self {
Value::I64(n) => NumCast::from(n),
Value::U64(n) => NumCast::from(n),
Value::F64(n) => Some(n),
_ => None
}
}
/// Returns true if the `Value` is a Boolean. Returns false otherwise.
pub fn is_boolean(&self) -> bool {
self.as_boolean().is_some()
}
/// If the `Value` is a Boolean, returns the associated bool.
/// Returns None otherwise.
pub fn as_boolean(&self) -> Option<bool> {
match self {
&Value::Bool(b) => Some(b),
_ => None
}
}
/// Returns true if the `Value` is a Null. Returns false otherwise.
pub fn is_null(&self) -> bool {
self.as_null().is_some()
}
/// If the `Value` is a Null, returns ().
/// Returns None otherwise.
pub fn as_null(&self) -> Option<()> {
match self {
&Value::Null => Some(()),
_ => None
}
}
}
impl ser::Serialize for Value {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
match *self {
Value::Null => serializer.visit_unit(),
Value::Bool(v) => serializer.visit_bool(v),
Value::I64(v) => serializer.visit_i64(v),
Value::U64(v) => serializer.visit_u64(v),
Value::F64(v) => serializer.visit_f64(v),
Value::String(ref v) => serializer.visit_str(&v),
Value::Array(ref v) => v.serialize(serializer),
Value::Object(ref v) => v.serialize(serializer),
}
}
}
impl de::Deserialize for Value {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<Value, D::Error>
where D: de::Deserializer,
{
struct ValueVisitor;
impl de::Visitor for ValueVisitor {
type Value = Value;
#[inline]
fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
Ok(Value::Bool(value))
}
#[inline]
fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
if value < 0 {
Ok(Value::I64(value))
} else {
Ok(Value::U64(value as u64))
}
}
#[inline]
fn visit_u64<E>(&mut self, value: u64) -> Result<Value, E> {
Ok(Value::U64(value))
}
#[inline]
fn visit_f64<E>(&mut self, value: f64) -> Result<Value, E> {
Ok(Value::F64(value))
}
#[inline]
fn visit_str<E>(&mut self, value: &str) -> Result<Value, E>
where E: de::Error,
{
self.visit_string(value.to_string())
}
#[inline]
fn visit_string<E>(&mut self, value: String) -> Result<Value, E> {
Ok(Value::String(value))
}
#[inline]
fn visit_none<E>(&mut self) -> Result<Value, E> {
Ok(Value::Null)
}
#[inline]
fn visit_some<D>(&mut self, deserializer: &mut D) -> Result<Value, D::Error>
where D: de::Deserializer,
{
de::Deserialize::deserialize(deserializer)
}
#[inline]
fn visit_unit<E>(&mut self) -> Result<Value, E> {
Ok(Value::Null)
}
#[inline]
fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
where V: de::SeqVisitor,
{
let values = try!(de::impls::VecVisitor::new().visit_seq(visitor));
Ok(Value::Array(values))
}
#[inline]
fn visit_map<V>(&mut self, visitor: V) -> Result<Value, V::Error>
where V: de::MapVisitor,
{
let values = try!(de::impls::BTreeMapVisitor::new().visit_map(visitor));
Ok(Value::Object(values))
}
}
deserializer.visit(ValueVisitor)
}
}
struct WriterFormatter<'a, 'b: 'a> {
inner: &'a mut fmt::Formatter<'b>,
}
impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match self.inner.write_str(str::from_utf8(buf).unwrap()) {
Ok(_) => Ok(buf.len()),
Err(_) => Err(io::Error::last_os_error()),
}
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl fmt::Debug for Value {
/// Serializes a json value into a string
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut wr = WriterFormatter { inner: f };
super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error)
}
}
#[derive(Debug)]
enum State {
Value(Value),
Array(Vec<Value>),
Object(BTreeMap<String, Value>),
}
pub struct Serializer {
state: Vec<State>,
}
impl Serializer {
pub fn new() -> Serializer {
Serializer {
state: Vec::with_capacity(4),
}
}
pub fn unwrap(mut self) -> Value {
match self.state.pop().unwrap() {
State::Value(value) => value,
state => panic!("expected value, found {:?}", state),
}
}
}
impl ser::Serializer for Serializer {
type Error = ();
#[inline]
fn visit_bool(&mut self, value: bool) -> Result<(), ()> {
self.state.push(State::Value(Value::Bool(value)));
Ok(())
}
#[inline]
fn visit_i64(&mut self, value: i64) -> Result<(), ()> {
if value < 0 {
self.state.push(State::Value(Value::I64(value)));
} else {
self.state.push(State::Value(Value::U64(value as u64)));
}
Ok(())
}
#[inline]
fn visit_u64(&mut self, value: u64) -> Result<(), ()> {
self.state.push(State::Value(Value::U64(value)));
Ok(())
}
#[inline]
fn visit_f64(&mut self, value: f64) -> Result<(), ()> {
self.state.push(State::Value(Value::F64(value as f64)));
Ok(())
}
#[inline]
fn visit_char(&mut self, value: char) -> Result<(), ()> {
self.state.push(State::Value(Value::String(value.to_string())));
Ok(())
}
#[inline]
fn visit_str(&mut self, value: &str) -> Result<(), ()> {
self.state.push(State::Value(Value::String(value.to_string())));
Ok(())
}
#[inline]
fn visit_none(&mut self) -> Result<(), ()> {
self.visit_unit()
}
#[inline]
fn visit_some<V>(&mut self, value: V) -> Result<(), ()>
where V: ser::Serialize,
{
value.serialize(self)
}
#[inline]
fn visit_unit(&mut self) -> Result<(), ()> {
self.state.push(State::Value(Value::Null));
Ok(())
}
#[inline]
fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> Result<(), ()> {
let mut values = BTreeMap::new();
values.insert(variant.to_string(), Value::Array(vec![]));
self.state.push(State::Value(Value::Object(values)));
Ok(())
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<(), ()>
where V: ser::SeqVisitor,
{
let len = visitor.len().unwrap_or(0);
let values = Vec::with_capacity(len);
self.state.push(State::Array(values));
while let Some(()) = try!(visitor.visit(self)) { }
let values = match self.state.pop().unwrap() {
State::Array(values) => values,
state => panic!("Expected array, found {:?}", state),
};
self.state.push(State::Value(Value::Array(values)));
Ok(())
}
#[inline]
fn visit_enum_seq<V>(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()>
where V: ser::SeqVisitor,
{
try!(self.visit_seq(visitor));
let value = match self.state.pop().unwrap() {
State::Value(value) => value,
state => panic!("expected value, found {:?}", state),
};
let mut object = BTreeMap::new();
object.insert(variant.to_string(), value);
self.state.push(State::Value(Value::Object(object)));
Ok(())
}
#[inline]
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), ()>
where T: ser::Serialize,
{
try!(value.serialize(self));
let value = match self.state.pop().unwrap() {
State::Value(value) => value,
state => panic!("expected value, found {:?}", state),
};
match *self.state.last_mut().unwrap() {
State::Array(ref mut values) => { values.push(value); }
ref state => panic!("expected array, found {:?}", state),
}
Ok(())
}
#[inline]
fn visit_map<V>(&mut self, mut visitor: V) -> Result<(), ()>
where V: ser::MapVisitor,
{
let values = BTreeMap::new();
self.state.push(State::Object(values));
while let Some(()) = try!(visitor.visit(self)) { }
let values = match self.state.pop().unwrap() {
State::Object(values) => values,
state => panic!("expected object, found {:?}", state),
};
self.state.push(State::Value(Value::Object(values)));
Ok(())
}
#[inline]
fn visit_enum_map<V>(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()>
where V: ser::MapVisitor,
{
try!(self.visit_map(visitor));
let value = match self.state.pop().unwrap() {
State::Value(value) => value,
state => panic!("expected value, found {:?}", state),
};
let mut object = BTreeMap::new();
object.insert(variant.to_string(), value);
self.state.push(State::Value(Value::Object(object)));
Ok(())
}
#[inline]
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), ()>
where K: ser::Serialize,
V: ser::Serialize,
{
try!(key.serialize(self));
let key = match self.state.pop().unwrap() {
State::Value(Value::String(value)) => value,
state => panic!("expected key, found {:?}", state),
};
try!(value.serialize(self));
let value = match self.state.pop().unwrap() {
State::Value(value) => value,
state => panic!("expected value, found {:?}", state),
};
match *self.state.last_mut().unwrap() {
State::Object(ref mut values) => { values.insert(key, value); }
ref state => panic!("expected object, found {:?}", state),
}
Ok(())
}
#[inline]
fn format() -> &'static str {
"json"
}
}
pub struct Deserializer {
value: Option<Value>,
}
impl Deserializer {
/// Creates a new deserializer instance for deserializing the specified JSON value.
pub fn new(value: Value) -> Deserializer {
Deserializer {
value: Some(value),
}
}
}
impl de::Deserializer for Deserializer {
type Error = Error;
#[inline]
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
let value = match self.value.take() {
Some(value) => value,
None => { return Err(de::Error::end_of_stream_error()); }
};
match value {
Value::Null => visitor.visit_unit(),
Value::Bool(v) => visitor.visit_bool(v),
Value::I64(v) => visitor.visit_i64(v),
Value::U64(v) => visitor.visit_u64(v),
Value::F64(v) => visitor.visit_f64(v),
Value::String(v) => visitor.visit_string(v),
Value::Array(v) => {
let len = v.len();
visitor.visit_seq(SeqDeserializer {
de: self,
iter: v.into_iter(),
len: len,
})
}
Value::Object(v) => {
let len = v.len();
visitor.visit_map(MapDeserializer {
de: self,
iter: v.into_iter(),
value: None,
len: len,
})
}
}
}
#[inline]
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.value {
Some(Value::Null) => visitor.visit_none(),
Some(_) => visitor.visit_some(self),
None => Err(de::Error::end_of_stream_error()),
}
}
#[inline]
fn visit_enum<V>(&mut self, _name: &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()); }
};
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()); }
};
match iter.next() {
Some(_) => Err(de::Error::syntax_error()),
None => Ok(value)
}
}
#[inline]
fn format() -> &'static str {
"json"
}
}
struct SeqDeserializer<'a> {
de: &'a mut Deserializer,
iter: vec::IntoIter<Value>,
len: usize,
}
impl<'a> de::Deserializer for SeqDeserializer<'a> {
type Error = Error;
#[inline]
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
if self.len == 0 {
visitor.visit_unit()
} else {
visitor.visit_seq(self)
}
}
}
impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: de::Deserialize
{
match self.iter.next() {
Some(value) => {
self.len -= 1;
self.de.value = Some(value);
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
}
None => Ok(None),
}
}
fn end(&mut self) -> Result<(), Error> {
if self.len == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream_error())
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
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>,
value: Option<Value>,
len: usize,
}
impl<'a> de::MapVisitor for MapDeserializer<'a> {
type Error = Error;
fn visit_key<T>(&mut self) -> Result<Option<T>, Error>
where T: de::Deserialize
{
match self.iter.next() {
Some((key, value)) => {
self.len -= 1;
self.value = Some(value);
self.de.value = Some(Value::String(key));
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
}
None => Ok(None),
}
}
fn visit_value<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize
{
let value = self.value.take().unwrap();
self.de.value = Some(value);
Ok(try!(de::Deserialize::deserialize(self.de)))
}
fn end(&mut self) -> Result<(), Error> {
if self.len == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream_error())
}
}
fn missing_field<V>(&mut self, _field: &'static str) -> Result<V, Error>
where V: de::Deserialize,
{
// See if the type can deserialize from a unit.
struct UnitDeserializer;
impl de::Deserializer for UnitDeserializer {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_unit()
}
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_none()
}
}
Ok(try!(de::Deserialize::deserialize(&mut UnitDeserializer)))
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
impl<'a> de::Deserializer for MapDeserializer<'a> {
type Error = Error;
#[inline]
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
{
let mut ser = Serializer::new();
value.serialize(&mut ser).ok().unwrap();
ser.unwrap()
}
/// Shortcut function to decode a JSON `Value` into a `T`
pub fn from_value<T>(value: Value) -> Result<T, Error>
where T: de::Deserialize
{
let mut de = Deserializer::new(value);
de::Deserialize::deserialize(&mut de)
}
+3 -16
View File
@@ -5,23 +5,9 @@
//! handshake protocol between serializers and serializees can be completely optimized away, //! 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 //! leaving serde to perform roughly the same speed as a hand written serializer for a specific
//! type. //! type.
//! #![doc(html_root_url="http://erickt.github.io/rust-serde")]
//! For a detailed tutorial on the different ways to use serde please check out the
//! [github repository](https://github.com/serde-rs/serde)
#![doc(html_root_url="https://serde-rs.github.io/serde/serde")] extern crate num;
#![cfg_attr(feature = "nightly", feature(collections, enumset, nonzero, plugin, step_trait,
zero_one))]
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
#![cfg_attr(feature = "nightly-testing", allow(linkedlist))]
#![deny(missing_docs)]
#[cfg(feature = "nightly")]
extern crate collections;
#[cfg(feature = "nightly")]
extern crate core;
pub use ser::{Serialize, Serializer}; pub use ser::{Serialize, Serializer};
pub use de::{Deserialize, Deserializer, Error}; pub use de::{Deserialize, Deserializer, Error};
@@ -29,4 +15,5 @@ pub use de::{Deserialize, Deserializer, Error};
pub mod bytes; pub mod bytes;
pub mod de; pub mod de;
pub mod iter; pub mod iter;
pub mod json;
pub mod ser; pub mod ser;
+50 -294
View File
@@ -1,35 +1,10 @@
//! Implementations for all of Rust's builtin types. 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::hash::Hash;
#[cfg(feature = "nightly")]
use std::iter;
use std::net;
#[cfg(feature = "nightly")]
use std::num;
#[cfg(feature = "nightly")]
use std::ops;
use std::path; use std::path;
use std::rc::Rc; use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use std::marker::PhantomData;
#[cfg(feature = "nightly")]
use core::nonzero::{NonZero, Zeroable};
use super::{ use super::{
Error,
Serialize, Serialize,
Serializer, Serializer,
SeqVisitor, SeqVisitor,
@@ -51,20 +26,20 @@ macro_rules! impl_visit {
} }
} }
impl_visit!(bool, serialize_bool); impl_visit!(bool, visit_bool);
impl_visit!(isize, serialize_isize); impl_visit!(isize, visit_isize);
impl_visit!(i8, serialize_i8); impl_visit!(i8, visit_i8);
impl_visit!(i16, serialize_i16); impl_visit!(i16, visit_i16);
impl_visit!(i32, serialize_i32); impl_visit!(i32, visit_i32);
impl_visit!(i64, serialize_i64); impl_visit!(i64, visit_i64);
impl_visit!(usize, serialize_usize); impl_visit!(usize, visit_usize);
impl_visit!(u8, serialize_u8); impl_visit!(u8, visit_u8);
impl_visit!(u16, serialize_u16); impl_visit!(u16, visit_u16);
impl_visit!(u32, serialize_u32); impl_visit!(u32, visit_u32);
impl_visit!(u64, serialize_u64); impl_visit!(u64, visit_u64);
impl_visit!(f32, serialize_f32); impl_visit!(f32, visit_f32);
impl_visit!(f64, serialize_f64); impl_visit!(f64, visit_f64);
impl_visit!(char, serialize_char); impl_visit!(char, visit_char);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@@ -73,7 +48,7 @@ impl Serialize for str {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
serializer.serialize_str(self) serializer.visit_str(self)
} }
} }
@@ -94,66 +69,14 @@ impl<T> Serialize for Option<T> where T: Serialize {
where S: Serializer, where S: Serializer,
{ {
match *self { match *self {
Some(ref value) => serializer.serialize_some(value), Some(ref value) => serializer.visit_some(value),
None => serializer.serialize_none(), None => serializer.visit_none(),
} }
} }
} }
impl<T> SeqVisitor for Option<T> where T: Serialize {
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.take() {
Some(value) => {
try!(serializer.serialize_seq_elt(value));
Ok(Some(()))
}
None => Ok(None),
}
}
#[inline]
fn len(&self) -> Option<usize> {
Some(if self.is_some() { 1 } else { 0 })
}
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for PhantomData<T> {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.serialize_unit_struct("PhantomData")
}
}
///////////////////////////////////////////////////////////////////////////////
/// A `serde::Visitor` for sequence iterators.
///
/// # Examples
///
/// ```
/// use serde::{Serialize, Serializer};
/// use serde::ser::impls::SeqIteratorVisitor;
///
/// struct Seq(Vec<u32>);
///
/// impl Serialize for Seq {
/// fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
/// where S: Serializer,
/// {
/// ser.serialize_seq(SeqIteratorVisitor::new(
/// self.0.iter(),
/// Some(self.0.len()),
/// ))
/// }
/// }
/// ```
pub struct SeqIteratorVisitor<Iter> { pub struct SeqIteratorVisitor<Iter> {
iter: Iter, iter: Iter,
len: Option<usize>, len: Option<usize>,
@@ -162,7 +85,6 @@ pub struct SeqIteratorVisitor<Iter> {
impl<T, Iter> SeqIteratorVisitor<Iter> impl<T, Iter> SeqIteratorVisitor<Iter>
where Iter: Iterator<Item=T> where Iter: Iterator<Item=T>
{ {
/// Construct a new `SeqIteratorVisitor<Iter>`.
#[inline] #[inline]
pub fn new(iter: Iter, len: Option<usize>) -> SeqIteratorVisitor<Iter> { pub fn new(iter: Iter, len: Option<usize>) -> SeqIteratorVisitor<Iter> {
SeqIteratorVisitor { SeqIteratorVisitor {
@@ -182,8 +104,8 @@ impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
{ {
match self.iter.next() { match self.iter.next() {
Some(value) => { Some(value) => {
try!(serializer.serialize_seq_elt(value)); let value = try!(serializer.visit_seq_elt(value));
Ok(Some(())) Ok(Some(value))
} }
None => Ok(None), None => Ok(None),
} }
@@ -197,19 +119,17 @@ impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for [T] impl<'a, T> Serialize for &'a [T]
where T: Serialize, where T: Serialize,
{ {
#[inline] #[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len()))) serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
} }
} }
///////////////////////////////////////////////////////////////////////////////
macro_rules! array_impls { macro_rules! array_impls {
($len:expr) => { ($len:expr) => {
impl<T> Serialize for [T; $len] where T: Serialize { impl<T> Serialize for [T; $len] where T: Serialize {
@@ -217,8 +137,7 @@ macro_rules! array_impls {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
let visitor = SeqIteratorVisitor::new(self.iter(), Some($len)); serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some($len)))
serializer.serialize_fixed_size_array(visitor)
} }
} }
} }
@@ -258,16 +177,12 @@ array_impls!(30);
array_impls!(31); array_impls!(31);
array_impls!(32); array_impls!(32);
/////////////////////////////////////////////////////////////////////////////// impl<T> Serialize for Vec<T> where T: Serialize {
impl<T> Serialize for BinaryHeap<T>
where T: Serialize + Ord
{
#[inline] #[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len()))) (&self[..]).serialize(serializer)
} }
} }
@@ -278,19 +193,7 @@ impl<T> Serialize for BTreeSet<T>
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len()))) serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
#[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.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
} }
} }
@@ -301,50 +204,7 @@ impl<T> Serialize for HashSet<T>
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len()))) serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
impl<T> Serialize for LinkedList<T>
where T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
#[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.serialize_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.serialize_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
} }
} }
@@ -355,7 +215,7 @@ impl Serialize for () {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
serializer.serialize_unit() serializer.visit_unit()
} }
} }
@@ -373,14 +233,12 @@ macro_rules! tuple_impls {
} }
)+) => { )+) => {
$( $(
/// A tuple visitor.
pub struct $TupleVisitor<'a, $($T: 'a),+> { pub struct $TupleVisitor<'a, $($T: 'a),+> {
tuple: &'a ($($T,)+), tuple: &'a ($($T,)+),
state: u8, state: u8,
} }
impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> { impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> {
/// Construct a new, empty `TupleVisitor`.
pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> { pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> {
$TupleVisitor { $TupleVisitor {
tuple: tuple, tuple: tuple,
@@ -399,7 +257,7 @@ macro_rules! tuple_impls {
$( $(
$state => { $state => {
self.state += 1; self.state += 1;
Ok(Some(try!(serializer.serialize_tuple_elt(&e!(self.tuple.$idx))))) Ok(Some(try!(serializer.visit_seq_elt(&e!(self.tuple.$idx)))))
} }
)+ )+
_ => { _ => {
@@ -418,7 +276,7 @@ macro_rules! tuple_impls {
{ {
#[inline] #[inline]
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> { fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
serializer.serialize_tuple($TupleVisitor::new(self)) serializer.visit_seq($TupleVisitor::new(self))
} }
} }
)+ )+
@@ -532,28 +390,6 @@ tuple_impls! {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A `serde::Visitor` for (key, value) map iterators.
///
/// # Examples
///
/// ```
/// use std::collections::HashMap;
/// use serde::{Serialize, Serializer};
/// use serde::ser::impls::MapIteratorVisitor;
///
/// struct Map(HashMap<u32, u32>);
///
/// impl Serialize for Map {
/// fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
/// where S: Serializer,
/// {
/// ser.serialize_map(MapIteratorVisitor::new(
/// self.0.iter(),
/// Some(self.0.len()),
/// ))
/// }
/// }
/// ```
pub struct MapIteratorVisitor<Iter> { pub struct MapIteratorVisitor<Iter> {
iter: Iter, iter: Iter,
len: Option<usize>, len: Option<usize>,
@@ -562,7 +398,6 @@ pub struct MapIteratorVisitor<Iter> {
impl<K, V, Iter> MapIteratorVisitor<Iter> impl<K, V, Iter> MapIteratorVisitor<Iter>
where Iter: Iterator<Item=(K, V)> where Iter: Iterator<Item=(K, V)>
{ {
/// Construct a new `MapIteratorVisitor<Iter>`.
#[inline] #[inline]
pub fn new(iter: Iter, len: Option<usize>) -> MapIteratorVisitor<Iter> { pub fn new(iter: Iter, len: Option<usize>) -> MapIteratorVisitor<Iter> {
MapIteratorVisitor { MapIteratorVisitor {
@@ -583,8 +418,8 @@ impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
{ {
match self.iter.next() { match self.iter.next() {
Some((key, value)) => { Some((key, value)) => {
try!(serializer.serialize_map_elt(key, value)); let value = try!(serializer.visit_map_elt(key, value));
Ok(Some(())) Ok(Some(value))
} }
None => Ok(None) None => Ok(None)
} }
@@ -606,7 +441,7 @@ impl<K, V> Serialize for BTreeMap<K, V>
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
serializer.serialize_map(MapIteratorVisitor::new(self.iter(), Some(self.len()))) serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
} }
} }
@@ -618,10 +453,24 @@ impl<K, V> Serialize for HashMap<K, V>
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
serializer.serialize_map(MapIteratorVisitor::new(self.iter(), Some(self.len()))) serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
} }
} }
// 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 { impl<'a, T: ?Sized> Serialize for &'a T where T: Serialize {
@@ -669,99 +518,13 @@ 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.serialize_newtype_variant("Result", 0, "Ok", value)
}
Result::Err(ref value) => {
serializer.serialize_newtype_variant("Result", 1, "Err", value)
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "nightly")]
impl Serialize for net::IpAddr {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
match *self {
net::IpAddr::V4(ref addr) => addr.serialize(serializer),
net::IpAddr::V6(ref addr) => addr.serialize(serializer),
}
}
}
impl Serialize for net::Ipv4Addr {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
self.to_string().serialize(serializer)
}
}
impl Serialize for net::Ipv6Addr {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
self.to_string().serialize(serializer)
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for net::SocketAddr {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
match *self {
net::SocketAddr::V4(ref addr) => addr.serialize(serializer),
net::SocketAddr::V6(ref addr) => addr.serialize(serializer),
}
}
}
impl Serialize for net::SocketAddrV4 {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
self.to_string().serialize(serializer)
}
}
impl Serialize for net::SocketAddrV6 {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
self.to_string().serialize(serializer)
}
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
impl Serialize for path::Path { impl Serialize for path::Path {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
match self.to_str() { self.to_str().unwrap().serialize(serializer)
Some(s) => s.serialize(serializer),
None => Err(Error::invalid_value("Path contains invalid UTF-8 characters")),
}
} }
} }
@@ -769,13 +532,6 @@ impl Serialize for path::PathBuf {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer, where S: Serializer,
{ {
self.as_path().serialize(serializer) 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)
} }
} }
+109 -271
View File
@@ -1,351 +1,195 @@
//! Generic serialization framework. //! Generic serialization framework.
use std::error;
pub mod impls; pub mod impls;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// `Error` is a trait that allows a `Serialize` to generically create a
/// `Serializer` error.
pub trait Error: Sized + error::Error {
/// Raised when there is general error when deserializing a type.
fn custom<T: Into<String>>(msg: T) -> Self;
/// Raised when a `Serialize` was passed an incorrect value.
fn invalid_value(msg: &str) -> Self {
Error::custom(format!("invalid value: {}", msg))
}
}
///////////////////////////////////////////////////////////////////////////////
/// A trait that describes a type that can be serialized by a `Serializer`.
pub trait Serialize { pub trait Serialize {
/// Serializes this value into this serializer.
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer; where S: Serializer;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A trait that describes a type that can serialize a stream of values into the underlying format.
pub trait Serializer { pub trait Serializer {
/// The error type that can be returned if some error occurs during serialization. type Error;
type Error: Error;
/// Serializes a `bool` value. /// `visit_bool` serializes a `bool` value.
fn serialize_bool(&mut self, v: bool) -> Result<(), Self::Error>; fn visit_bool(&mut self, v: bool) -> Result<(), Self::Error>;
/// Serializes a `isize` value. By default it casts the value to a `i64` and /// `visit_isize` serializes a `isize` value. By default it casts the value to a `i64` and
/// passes it to the `serialize_i64` method. /// passes it to the `visit_i64` method.
#[inline] #[inline]
fn serialize_isize(&mut self, v: isize) -> Result<(), Self::Error> { fn visit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
self.serialize_i64(v as i64) self.visit_i64(v as i64)
} }
/// Serializes a `i8` value. By default it casts the value to a `i64` and /// `visit_i8` serializes a `i8` value. By default it casts the value to a `i64` and
/// passes it to the `serialize_i64` method. /// passes it to the `visit_i64` method.
#[inline] #[inline]
fn serialize_i8(&mut self, v: i8) -> Result<(), Self::Error> { fn visit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
self.serialize_i64(v as i64) self.visit_i64(v as i64)
} }
/// Serializes a `i16` value. By default it casts the value to a `i64` and /// `visit_i16` serializes a `i16` value. By default it casts the value to a `i64` and
/// passes it to the `serialize_i64` method. /// passes it to the `visit_i64` method.
#[inline] #[inline]
fn serialize_i16(&mut self, v: i16) -> Result<(), Self::Error> { fn visit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
self.serialize_i64(v as i64) self.visit_i64(v as i64)
} }
/// Serializes a `i32` value. By default it casts the value to a `i64` and /// `visit_i32` serializes a `i32` value. By default it casts the value to a `i64` and
/// passes it to the `serialize_i64` method. /// passes it to the `visit_i64` method.
#[inline] #[inline]
fn serialize_i32(&mut self, v: i32) -> Result<(), Self::Error> { fn visit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
self.serialize_i64(v as i64) self.visit_i64(v as i64)
} }
/// Serializes a `i64` value. /// `visit_i64` serializes a `i64` value.
#[inline] #[inline]
fn serialize_i64(&mut self, v: i64) -> Result<(), Self::Error>; fn visit_i64(&mut self, v: i64) -> Result<(), Self::Error>;
/// Serializes a `usize` value. By default it casts the value to a `u64` and /// `visit_usize` serializes a `usize` value. By default it casts the value to a `u64` and
/// passes it to the `serialize_u64` method. /// passes it to the `visit_u64` method.
#[inline] #[inline]
fn serialize_usize(&mut self, v: usize) -> Result<(), Self::Error> { fn visit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
self.serialize_u64(v as u64) self.visit_u64(v as u64)
} }
/// Serializes a `u8` value. By default it casts the value to a `u64` and passes /// `visit_u8` serializes a `u8` value. By default it casts the value to a `u64` and passes
/// it to the `serialize_u64` method. /// it to the `visit_u64` method.
#[inline] #[inline]
fn serialize_u8(&mut self, v: u8) -> Result<(), Self::Error> { fn visit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
self.serialize_u64(v as u64) self.visit_u64(v as u64)
} }
/// Serializes a `u32` value. By default it casts the value to a `u64` and passes /// `visit_u32` serializes a `u32` value. By default it casts the value to a `u64` and passes
/// it to the `serialize_u64` method. /// it to the `visit_u64` method.
#[inline] #[inline]
fn serialize_u16(&mut self, v: u16) -> Result<(), Self::Error> { fn visit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
self.serialize_u64(v as u64) self.visit_u64(v as u64)
} }
/// Serializes a `u32` value. By default it casts the value to a `u64` and passes /// `visit_u32` serializes a `u32` value. By default it casts the value to a `u64` and passes
/// it to the `serialize_u64` method. /// it to the `visit_u64` method.
#[inline] #[inline]
fn serialize_u32(&mut self, v: u32) -> Result<(), Self::Error> { fn visit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
self.serialize_u64(v as u64) self.visit_u64(v as u64)
} }
/// `Serializes a `u64` value. /// `visit_u64` serializes a `u64` value.
#[inline] #[inline]
fn serialize_u64(&mut self, v: u64) -> Result<(), Self::Error>; fn visit_u64(&mut self, v: u64) -> Result<(), Self::Error>;
/// Serializes a `f32` value. By default it casts the value to a `f64` and passes /// `visit_f32` serializes a `f32` value. By default it casts the value to a `f64` and passes
/// it to the `serialize_f64` method. /// it to the `visit_f64` method.
#[inline] #[inline]
fn serialize_f32(&mut self, v: f32) -> Result<(), Self::Error> { fn visit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
self.serialize_f64(v as f64) self.visit_f64(v as f64)
} }
/// Serializes a `f64` value. /// `visit_f64` serializes a `f64` value.
fn serialize_f64(&mut self, v: f64) -> Result<(), Self::Error>; fn visit_f64(&mut self, v: f64) -> Result<(), Self::Error>;
/// Serializes a character. By default it serializes it as a `&str` containing a /// `visit_char` serializes a character. By default it serializes it as a `&str` containing a
/// single character. /// single character.
#[inline] #[inline]
fn serialize_char(&mut self, v: char) -> Result<(), Self::Error> { fn visit_char(&mut self, v: char) -> Result<(), Self::Error> {
// FIXME: this allocation is required in order to be compatible with stable rust, which // FIXME: this allocation is required in order to be compatible with stable rust, which
// doesn't support encoding a `char` into a stack buffer. // doesn't support encoding a `char` into a stack buffer.
self.serialize_str(&v.to_string()) self.visit_str(&v.to_string())
} }
/// Serializes a `&str`. /// `visit_str` serializes a `&str`.
fn serialize_str(&mut self, value: &str) -> Result<(), Self::Error>; fn visit_str(&mut self, value: &str) -> Result<(), Self::Error>;
/// Enables those serialization formats that support serializing /// `visit_bytes` is a hook that enables those serialization formats that support serializing
/// byte slices separately from generic arrays. By default it serializes as a regular array. /// byte slices separately from generic arrays. By default it serializes as a regular array.
#[inline] #[inline]
fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> { fn visit_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> {
self.serialize_seq(impls::SeqIteratorVisitor::new(value.iter(), Some(value.len()))) self.visit_seq(impls::SeqIteratorVisitor::new(value.iter(), Some(value.len())))
} }
/// Serializes a `()` value. fn visit_unit(&mut self) -> Result<(), Self::Error>;
fn serialize_unit(&mut self) -> Result<(), Self::Error>;
/// Serializes a unit struct value.
///
/// By default, unit structs are serialized as a `()`.
#[inline] #[inline]
fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<(), Self::Error> { fn visit_named_unit(&mut self, _name: &str) -> Result<(), Self::Error> {
self.serialize_unit() self.visit_unit()
} }
/// Serializes a unit variant, otherwise known as a variant with no arguments.
///
/// By default, unit variants are serialized as a `()`.
#[inline] #[inline]
fn serialize_unit_variant(&mut self, fn visit_enum_unit(&mut self,
_name: &'static str, _name: &str,
_variant_index: usize, _variant: &str) -> Result<(), Self::Error> {
_variant: &'static str) -> Result<(), Self::Error> { self.visit_unit()
self.serialize_unit()
} }
/// Allows a tuple struct with a single element, also known as a fn visit_none(&mut self) -> Result<(), Self::Error>;
/// newtyped value, to be more efficiently serialized than a tuple struct with multiple items.
/// By default it just serializes the value as a tuple struct sequence.
#[inline]
fn serialize_newtype_struct<T>(&mut self,
name: &'static str,
value: T) -> Result<(), Self::Error>
where T: Serialize,
{
self.serialize_tuple_struct(name, Some(value))
}
/// Allows a variant with a single item to be more efficiently fn visit_some<V>(&mut self, value: V) -> Result<(), Self::Error>
/// serialized than a variant with multiple items. By default it just serializes the value as a
/// tuple variant sequence.
#[inline]
fn serialize_newtype_variant<T>(&mut self,
name: &'static str,
variant_index: usize,
variant: &'static str,
value: T) -> Result<(), Self::Error>
where T: Serialize,
{
self.serialize_tuple_variant(
name,
variant_index,
variant,
Some(value))
}
/// Serializes a `None` value..serialize
fn serialize_none(&mut self) -> Result<(), Self::Error>;
/// Serializes a `Some(...)` value.
fn serialize_some<V>(&mut self, value: V) -> Result<(), Self::Error>
where V: Serialize; where V: Serialize;
/// Serializes a sequence. fn visit_seq<V>(&mut self, visitor: V) -> Result<(), Self::Error>
///
/// Callees of this method need to construct a `SeqVisitor`, which iterates through each item
/// in the sequence.
fn serialize_seq<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor; where V: SeqVisitor;
/// Serializes a sequence element. #[inline]
fn serialize_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error> 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; where T: Serialize;
/// Serializes a tuple. fn visit_map<V>(&mut self, visitor: V) -> Result<(), Self::Error>
///
/// By default this serializes a tuple as a sequence.
#[inline]
fn serialize_tuple<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.serialize_seq(visitor)
}
/// Serializes a tuple element.
///
/// By default, tuples are serialized as a sequence.
#[inline]
fn serialize_tuple_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.serialize_seq_elt(value)
}
/// Serializes a fixed-size array.
///
/// By default this serializes an array as a sequence.
#[inline]
fn serialize_fixed_size_array<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.serialize_seq(visitor)
}
/// Serializes a tuple struct.
///
/// By default, tuple structs are serialized as a tuple.
#[inline]
fn serialize_tuple_struct<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.serialize_tuple(visitor)
}
/// Serializes a tuple struct element.
///
/// By default, tuple struct elements are serialized as a tuple element.
#[inline]
fn serialize_tuple_struct_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.serialize_tuple_elt(value)
}
/// Serializes a tuple variant.
///
/// By default, tuple variants are serialized as a tuple struct.
#[inline]
fn serialize_tuple_variant<V>(&mut self,
_name: &'static str,
_variant_index: usize,
variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.serialize_tuple_struct(variant, visitor)
}
/// Serializes a tuple element.
///
/// By default, tuples are serialized as a sequence.
#[inline]
fn serialize_tuple_variant_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize
{
self.serialize_tuple_struct_elt(value)
}
/// Serializes a map.
///
/// Callees of this method need to construct a `MapVisitor`, which iterates through each item
/// in the map.
fn serialize_map<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: MapVisitor; where V: MapVisitor;
/// Serializes a map element (key-value pair). #[inline]
fn serialize_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error> 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, where K: Serialize,
V: Serialize; V: Serialize;
/// Serializes a struct. /// Specify a format string for the serializer.
/// ///
/// By default, structs are serialized as a map with the field name as the key. /// The serializer format is used to determine which format
#[inline] /// specific field attributes should be used with the serializer.
fn serialize_struct<V>(&mut self, fn format() -> &'static str {
_name: &'static str, ""
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.serialize_map(visitor)
}
/// Serializes an element of a struct.
///
/// By default, struct elements are serialized as a map element with the field name as the key.
#[inline]
fn serialize_struct_elt<V>(&mut self,
key: &'static str,
value: V) -> Result<(), Self::Error>
where V: Serialize,
{
self.serialize_map_elt(key, value)
}
/// Serializes a struct variant.
///
/// By default, struct variants are serialized as a struct.
#[inline]
fn serialize_struct_variant<V>(&mut self,
_name: &'static str,
_variant_index: usize,
variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.serialize_struct(variant, visitor)
}
/// Serializes an element of a struct variant.
///
/// By default, struct variant elements are serialized as a struct element.
#[inline]
fn serialize_struct_variant_elt<V>(&mut self,
key: &'static str,
value: V) -> Result<(), Self::Error>
where V: Serialize,
{
self.serialize_struct_elt(key, value)
} }
} }
/// A trait that is used by a `Serialize` to iterate through a sequence.
#[cfg_attr(feature = "nightly-testing", allow(len_without_is_empty))]
pub trait SeqVisitor { pub trait SeqVisitor {
/// Serializes a sequence item in the serializer.
///
/// This returns `Ok(Some(()))` when there are more items to serialize, or `Ok(None)` when
/// complete.
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error> fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer; where S: Serializer;
@@ -356,13 +200,7 @@ pub trait SeqVisitor {
} }
} }
/// A trait that is used by a `Serialize` to iterate through a map.
#[cfg_attr(feature = "nightly-testing", allow(len_without_is_empty))]
pub trait MapVisitor { pub trait MapVisitor {
/// Serializes a map item in the serializer.
///
/// This returns `Ok(Some(()))` when there are more items to serialize, or `Ok(None)` when
/// complete.
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error> fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer; where S: Serializer;
+10 -14
View File
@@ -1,28 +1,24 @@
[package] [package]
name = "serde_codegen" name = "serde_codegen"
version = "0.7.5" version = "0.4.2"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework" description = "Macros to auto-generate implementations for the serde framework"
repository = "https://github.com/serde-rs/serde" repository = "https://github.com/erickt/rust-serde"
documentation = "https://github.com/serde-rs/serde"
keywords = ["serde", "serialization"]
build = "build.rs" build = "build.rs"
[features] [features]
default = ["with-syntex"] default = ["with-syntex"]
nightly = ["quasi_macros"] nightly = ["quasi_macros"]
nightly-testing = ["clippy"] 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] [build-dependencies]
quasi_codegen = { version = "^0.10.0", optional = true } quasi_codegen = { verision = "*", optional = true }
syntex = { version = "^0.32.0", optional = true } syntex = { version = "*", optional = true }
[dependencies] [dependencies]
aster = { version = "^0.16.0", default-features = false } aster = { version = "*", default-features = false }
clippy = { version = "^0.*", optional = true } quasi = { verision = "*", default-features = false }
quasi = { version = "^0.10.0", default-features = false } quasi_macros = { version = "*", optional = true }
quasi_macros = { version = "^0.10.0", optional = true } syntex = { version = "*", optional = true }
syntex = { version = "^0.32.0", optional = true } syntex_syntax = { version = "*", optional = true }
syntex_syntax = { version = "^0.32.0", optional = true }
+81 -567
View File
@@ -1,594 +1,108 @@
use std::rc::Rc; use std::collections::HashMap;
use syntax::ast::{self, TokenTree}; use std::collections::HashSet;
use syntax::attr;
use syntax::codemap::Span; use syntax::ast;
use syntax::ext::base::ExtCtxt; use syntax::ext::base::ExtCtxt;
use syntax::fold::Folder;
use syntax::parse::parser::PathStyle;
use syntax::parse::token::{self, InternedString};
use syntax::parse;
use syntax::print::pprust::{lit_to_string, meta_item_to_string};
use syntax::ptr::P; use syntax::ptr::P;
use aster::AstBuilder; /// Represents field name information
pub enum FieldNames {
use error::Error; Global(P<ast::Expr>),
Format{
#[derive(Debug)] formats: HashMap<P<ast::Expr>, P<ast::Expr>>,
pub struct Name { default: P<ast::Expr>,
ident: ast::Ident,
serialize_name: Option<InternedString>,
deserialize_name: Option<InternedString>,
}
impl Name {
fn new(ident: ast::Ident) -> Self {
Name {
ident: ident,
serialize_name: None,
deserialize_name: None,
}
}
/// Return the container name for the container when serializing.
pub fn serialize_name(&self) -> InternedString {
match self.serialize_name {
Some(ref name) => name.clone(),
None => self.ident.name.as_str(),
}
}
/// Return the container name expression for the container when deserializing.
pub fn serialize_name_expr(&self) -> P<ast::Expr> {
AstBuilder::new().expr().str(self.serialize_name())
}
/// Return the container name for the container when deserializing.
pub fn deserialize_name(&self) -> InternedString {
match self.deserialize_name {
Some(ref name) => name.clone(),
None => self.ident.name.as_str(),
}
}
/// Return the container name expression for the container when deserializing.
pub fn deserialize_name_expr(&self) -> P<ast::Expr> {
AstBuilder::new().expr().str(self.deserialize_name())
}
}
/// Represents container (e.g. struct) attribute information
#[derive(Debug)]
pub struct ContainerAttrs {
name: Name,
deny_unknown_fields: bool,
}
impl ContainerAttrs {
/// Extract out the `#[serde(...)]` attributes from an item.
pub fn from_item(cx: &ExtCtxt, item: &ast::Item) -> Result<Self, Error> {
let mut container_attrs = ContainerAttrs {
name: Name::new(item.ident),
deny_unknown_fields: false,
};
for meta_items in item.attrs().iter().filter_map(get_serde_meta_items) {
for meta_item in meta_items {
match meta_item.node {
// Parse `#[serde(rename="foo")]`
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"rename" => {
let s = try!(get_str_from_lit(cx, name, lit));
container_attrs.name.serialize_name = Some(s.clone());
container_attrs.name.deserialize_name = Some(s);
}
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
ast::MetaItemKind::List(ref name, ref meta_items) if name == &"rename" => {
let (ser_name, de_name) = try!(get_renames(cx, meta_items));
container_attrs.name.serialize_name = ser_name;
container_attrs.name.deserialize_name = de_name;
}
// Parse `#[serde(deny_unknown_fields)]`
ast::MetaItemKind::Word(ref name) if name == &"deny_unknown_fields" => {
container_attrs.deny_unknown_fields = true;
}
_ => {
cx.span_err(
meta_item.span,
&format!("unknown serde container attribute `{}`",
meta_item_to_string(meta_item)));
return Err(Error);
}
}
}
}
Ok(container_attrs)
}
pub fn name(&self) -> &Name {
&self.name
}
pub fn deny_unknown_fields(&self) -> bool {
self.deny_unknown_fields
}
}
/// Represents variant attribute information
#[derive(Debug)]
pub struct VariantAttrs {
name: Name,
}
impl VariantAttrs {
pub fn from_variant(cx: &ExtCtxt, variant: &ast::Variant) -> Result<Self, Error> {
let mut variant_attrs = VariantAttrs {
name: Name::new(variant.node.name),
};
for meta_items in variant.node.attrs.iter().filter_map(get_serde_meta_items) {
for meta_item in meta_items {
match meta_item.node {
// Parse `#[serde(rename="foo")]`
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"rename" => {
let s = try!(get_str_from_lit(cx, name, lit));
variant_attrs.name.serialize_name = Some(s.clone());
variant_attrs.name.deserialize_name = Some(s);
}
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
ast::MetaItemKind::List(ref name, ref meta_items) if name == &"rename" => {
let (ser_name, de_name) = try!(get_renames(cx, meta_items));
variant_attrs.name.serialize_name = ser_name;
variant_attrs.name.deserialize_name = de_name;
}
_ => {
cx.span_err(
meta_item.span,
&format!("unknown serde variant attribute `{}`",
meta_item_to_string(meta_item)));
return Err(Error);
}
}
}
}
Ok(variant_attrs)
}
pub fn name(&self) -> &Name {
&self.name
} }
} }
/// Represents field attribute information /// Represents field attribute information
#[derive(Debug)]
pub struct FieldAttrs { pub struct FieldAttrs {
name: Name, names: FieldNames,
skip_serializing_field: bool, use_default: bool,
skip_deserializing_field: bool,
skip_serializing_field_if: Option<P<ast::Expr>>,
default_expr_if_missing: Option<P<ast::Expr>>,
serialize_with: Option<P<ast::Expr>>,
deserialize_with: Option<ast::Path>,
} }
impl FieldAttrs { impl FieldAttrs {
/// Extract out the `#[serde(...)]` attributes from a struct field.
pub fn from_field(cx: &ExtCtxt,
container_ty: &P<ast::Ty>,
generics: &ast::Generics,
field: &ast::StructField,
is_enum: bool) -> Result<Self, Error> {
let builder = AstBuilder::new();
let field_ident = match field.ident { /// Create a FieldAttr with a single default field name
Some(ident) => ident, pub fn new(default_value: bool, name: P<ast::Expr>) -> FieldAttrs {
None => { cx.span_bug(field.span, "struct field has no name?") } FieldAttrs {
}; names: FieldNames::Global(name),
use_default: default_value,
let mut field_attrs = FieldAttrs {
name: Name::new(field_ident),
skip_serializing_field: false,
skip_deserializing_field: false,
skip_serializing_field_if: None,
default_expr_if_missing: None,
serialize_with: None,
deserialize_with: None,
};
for meta_items in field.attrs.iter().filter_map(get_serde_meta_items) {
for meta_item in meta_items {
match meta_item.node {
// Parse `#[serde(rename="foo")]`
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"rename" => {
let s = try!(get_str_from_lit(cx, name, lit));
field_attrs.name.serialize_name = Some(s.clone());
field_attrs.name.deserialize_name = Some(s);
}
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
ast::MetaItemKind::List(ref name, ref meta_items) if name == &"rename" => {
let (ser_name, de_name) = try!(get_renames(cx, meta_items));
field_attrs.name.serialize_name = ser_name;
field_attrs.name.deserialize_name = de_name;
}
// Parse `#[serde(default)]`
ast::MetaItemKind::Word(ref name) if name == &"default" => {
let default_expr = builder.expr().default();
field_attrs.default_expr_if_missing = Some(default_expr);
}
// Parse `#[serde(default="...")]`
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"default" => {
let wrapped_expr = wrap_default(
try!(parse_lit_into_path(cx, name, lit)),
);
field_attrs.default_expr_if_missing = Some(wrapped_expr);
}
// Parse `#[serde(skip_serializing)]`
ast::MetaItemKind::Word(ref name) if name == &"skip_serializing" => {
field_attrs.skip_serializing_field = true;
}
// Parse `#[serde(skip_deserializing)]`
ast::MetaItemKind::Word(ref name) if name == &"skip_deserializing" => {
field_attrs.skip_deserializing_field = true;
// Initialize field to Default::default() unless a different
// default is specified by `#[serde(default="...")]`
if field_attrs.default_expr_if_missing.is_none() {
let default_expr = builder.expr().default();
field_attrs.default_expr_if_missing = Some(default_expr);
}
}
// Parse `#[serde(skip_serializing_if="...")]`
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"skip_serializing_if" => {
let expr = wrap_skip_serializing(
field_ident,
try!(parse_lit_into_path(cx, name, lit)),
is_enum,
);
field_attrs.skip_serializing_field_if = Some(expr);
}
// Parse `#[serde(serialize_with="...")]`
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"serialize_with" => {
let expr = wrap_serialize_with(
cx,
container_ty,
generics,
field_ident,
try!(parse_lit_into_path(cx, name, lit)),
is_enum,
);
field_attrs.serialize_with = Some(expr);
}
// Parse `#[serde(deserialize_with="...")]`
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"deserialize_with" => {
let path = try!(parse_lit_into_path(cx, name, lit));
field_attrs.deserialize_with = Some(path);
}
_ => {
cx.span_err(
meta_item.span,
&format!("unknown serde field attribute `{}`",
meta_item_to_string(meta_item)));
return Err(Error);
}
}
}
}
Ok(field_attrs)
}
pub fn name(&self) -> &Name {
&self.name
}
pub fn skip_serializing_field(&self) -> bool {
self.skip_serializing_field
}
pub fn skip_deserializing_field(&self) -> bool {
self.skip_deserializing_field
}
pub fn skip_serializing_field_if(&self) -> Option<&P<ast::Expr>> {
self.skip_serializing_field_if.as_ref()
}
pub fn default_expr_if_missing(&self) -> Option<&P<ast::Expr>> {
self.default_expr_if_missing.as_ref()
}
pub fn serialize_with(&self) -> Option<&P<ast::Expr>> {
self.serialize_with.as_ref()
}
pub fn deserialize_with(&self) -> Option<&ast::Path> {
self.deserialize_with.as_ref()
}
}
/// Extract out the `#[serde(...)]` attributes from a struct field.
pub fn get_struct_field_attrs(cx: &ExtCtxt,
container_ty: &P<ast::Ty>,
generics: &ast::Generics,
fields: &[ast::StructField],
is_enum: bool) -> Result<Vec<FieldAttrs>, Error> {
fields.iter()
.map(|field| FieldAttrs::from_field(cx, container_ty, generics, field, is_enum))
.collect()
}
fn get_renames(cx: &ExtCtxt,
items: &[P<ast::MetaItem>],
)-> Result<(Option<InternedString>, Option<InternedString>), Error> {
let mut ser_name = None;
let mut de_name = None;
for item in items {
match item.node {
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"serialize" => {
let s = try!(get_str_from_lit(cx, name, lit));
ser_name = Some(s);
}
ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"deserialize" => {
let s = try!(get_str_from_lit(cx, name, lit));
de_name = Some(s);
}
_ => {
cx.span_err(
item.span,
&format!("unknown rename attribute `{}`",
meta_item_to_string(item)));
return Err(Error);
}
} }
} }
Ok((ser_name, de_name)) /// Create a FieldAttr with format specific field names
} pub fn new_with_formats(
default_value: bool,
pub fn get_serde_meta_items(attr: &ast::Attribute) -> Option<&[P<ast::MetaItem>]> { default_name: P<ast::Expr>,
match attr.node.value.node { formats: HashMap<P<ast::Expr>, P<ast::Expr>>,
ast::MetaItemKind::List(ref name, ref items) if name == &"serde" => { ) -> FieldAttrs {
attr::mark_used(&attr); FieldAttrs {
Some(items) names: FieldNames::Format {
formats: formats,
default: default_name,
},
use_default: default_value,
} }
_ => None
} }
}
/// This syntax folder rewrites tokens to say their spans are coming from a macro context. /// Return a set of formats that the field has attributes for.
struct Respanner<'a, 'b: 'a> { pub fn formats(&self) -> HashSet<P<ast::Expr>> {
cx: &'a ExtCtxt<'b>, match self.names {
} FieldNames::Format{ref formats, default: _} => {
let mut set = HashSet::new();
for (fmt, _) in formats.iter() {
set.insert(fmt.clone());
};
set
},
_ => HashSet::new()
}
}
impl<'a, 'b> Folder for Respanner<'a, 'b> { /// Return an expression for the field key name for serialisation.
fn fold_tt(&mut self, tt: &TokenTree) -> TokenTree { ///
match *tt { /// The resulting expression assumes that `S` refers to a type
TokenTree::Token(span, ref tok) => { /// that implements `Serializer`.
TokenTree::Token( pub fn serializer_key_expr(self, cx: &ExtCtxt) -> P<ast::Expr> {
self.new_span(span), match self.names {
self.fold_token(tok.clone()) FieldNames::Global(x) => x,
) FieldNames::Format{formats, default} => {
} let arms = formats.iter()
TokenTree::Delimited(span, ref delimed) => { .map(|(fmt, lit)| {
TokenTree::Delimited( quote_arm!(cx, $fmt => { $lit })
self.new_span(span),
Rc::new(ast::Delimited {
delim: delimed.delim,
open_span: delimed.open_span,
tts: self.fold_tts(&delimed.tts),
close_span: delimed.close_span,
}) })
) .collect::<Vec<_>>();
} quote_expr!(cx,
TokenTree::Sequence(span, ref seq) => { {
TokenTree::Sequence( match S::format() {
self.new_span(span), $arms
Rc::new(ast::SequenceRepetition { _ => { $default }
tts: self.fold_tts(&seq.tts), }
separator: seq.separator.clone().map(|tok| self.fold_token(tok)), })
..**seq },
})
)
}
} }
} }
fn new_span(&mut self, span: Span) -> Span { /// Return the default field name for the field.
Span { pub fn default_key_expr(&self) -> &P<ast::Expr> {
lo: span.lo, match self.names {
hi: span.hi, FieldNames::Global(ref expr) => expr,
expn_id: self.cx.backtrace(), FieldNames::Format{formats: _, ref default} => default
}
}
}
fn get_str_from_lit(cx: &ExtCtxt, name: &str, lit: &ast::Lit) -> Result<InternedString, Error> {
match lit.node {
ast::LitKind::Str(ref s, _) => Ok(s.clone()),
_ => {
cx.span_err(
lit.span,
&format!("serde annotation `{}` must be a string, not `{}`",
name,
lit_to_string(lit)));
return Err(Error);
}
}
}
fn parse_lit_into_path(cx: &ExtCtxt, name: &str, lit: &ast::Lit) -> Result<ast::Path, Error> {
let source = try!(get_str_from_lit(cx, name, lit));
// If we just parse the string into an expression, any syntax errors in the source will only
// have spans that point inside the string, and not back to the attribute. So to have better
// error reporting, we'll first parse the string into a token tree. Then we'll update those
// spans to say they're coming from a macro context that originally came from the attribute,
// and then finally parse them into an expression.
let tts = panictry!(parse::parse_tts_from_source_str(
format!("<serde {} expansion>", name),
(*source).to_owned(),
cx.cfg(),
cx.parse_sess()));
// Respan the spans to say they are all coming from this macro.
let tts = Respanner { cx: cx }.fold_tts(&tts);
let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts);
let path = match parser.parse_path(PathStyle::Type) {
Ok(path) => path,
Err(mut e) => {
e.emit();
return Err(Error);
}
};
// Make sure to error out if there are trailing characters in the stream.
match parser.expect(&token::Eof) {
Ok(()) => { }
Err(mut e) => {
e.emit();
return Err(Error);
} }
} }
Ok(path) /// Return the field name for the field in the specified format.
} pub fn key_expr(&self, format: &P<ast::Expr>) -> &P<ast::Expr> {
match self.names {
/// This function wraps the expression in `#[serde(default="...")]` in a function to prevent it FieldNames::Global(ref expr) =>
/// from accessing the internal `Deserialize` state. expr,
fn wrap_default(path: ast::Path) -> P<ast::Expr> { FieldNames::Format{ref formats, ref default} =>
AstBuilder::new().expr().call() formats.get(format).unwrap_or(default)
.build_path(path) }
.build() }
}
/// Predicate for using a field's default value
/// This function wraps the expression in `#[serde(skip_serializing_if="...")]` in a trait to pub fn use_default(&self) -> bool {
/// prevent it from accessing the internal `Serialize` state. self.use_default
fn wrap_skip_serializing(field_ident: ast::Ident, }
path: ast::Path,
is_enum: bool) -> P<ast::Expr> {
let builder = AstBuilder::new();
let expr = builder.expr()
.field(field_ident)
.field("value")
.self_();
let expr = if is_enum {
expr
} else {
builder.expr().ref_().build(expr)
};
builder.expr().call()
.build_path(path)
.arg().build(expr)
.build()
}
/// This function wraps the expression in `#[serde(serialize_with="...")]` in a trait to
/// prevent it from accessing the internal `Serialize` state.
fn wrap_serialize_with(cx: &ExtCtxt,
container_ty: &P<ast::Ty>,
generics: &ast::Generics,
field_ident: ast::Ident,
path: ast::Path,
is_enum: bool) -> P<ast::Expr> {
let builder = AstBuilder::new();
let expr = builder.expr()
.field(field_ident)
.self_();
let expr = if is_enum {
expr
} else {
builder.expr().ref_().build(expr)
};
let expr = builder.expr().call()
.build_path(path)
.arg().build(expr)
.arg()
.id("serializer")
.build();
let where_clause = &generics.where_clause;
quote_expr!(cx, {
trait __SerdeSerializeWith {
fn __serde_serialize_with<__S>(&self, serializer: &mut __S) -> Result<(), __S::Error>
where __S: _serde::ser::Serializer;
}
impl<'__a, __T> __SerdeSerializeWith for &'__a __T
where __T: '__a + __SerdeSerializeWith,
{
fn __serde_serialize_with<__S>(&self, serializer: &mut __S) -> Result<(), __S::Error>
where __S: _serde::ser::Serializer
{
(**self).__serde_serialize_with(serializer)
}
}
impl $generics __SerdeSerializeWith for $container_ty $where_clause {
fn __serde_serialize_with<__S>(&self, serializer: &mut __S) -> Result<(), __S::Error>
where __S: _serde::ser::Serializer
{
$expr
}
}
struct __SerdeSerializeWithStruct<'__a, __T: '__a> {
value: &'__a __T,
}
impl<'__a, __T> _serde::ser::Serialize for __SerdeSerializeWithStruct<'__a, __T>
where __T: '__a + __SerdeSerializeWith
{
fn serialize<__S>(&self, serializer: &mut __S) -> Result<(), __S::Error>
where __S: _serde::ser::Serializer
{
self.value.__serde_serialize_with(serializer)
}
}
__SerdeSerializeWithStruct {
value: &self.value,
}
})
} }
-147
View File
@@ -1,147 +0,0 @@
use std::collections::HashSet;
use aster::AstBuilder;
use syntax::ast;
use syntax::ext::base::ExtCtxt;
use syntax::ptr::P;
use syntax::visit;
// Remove the default from every type parameter because in the generated impls
// they look like associated types: "error: associated type bindings are not
// allowed here".
pub fn without_defaults(generics: &ast::Generics) -> ast::Generics {
ast::Generics {
ty_params: generics.ty_params.iter().map(|ty_param| {
ast::TyParam {
default: None,
.. ty_param.clone()
}}).collect(),
.. generics.clone()
}
}
pub fn with_bound(
cx: &ExtCtxt,
builder: &AstBuilder,
item: &ast::Item,
generics: &ast::Generics,
filter: &Fn(&ast::StructField) -> bool,
bound: &ast::Path,
) -> ast::Generics {
builder.from_generics(generics.clone())
.with_predicates(
all_variants(cx, item).iter()
.flat_map(|variant_data| all_struct_fields(variant_data))
.filter(|field| filter(field))
.map(|field| &field.ty)
// TODO this filter can be removed later, see comment on function
.filter(|ty| contains_generic(ty, generics))
.map(|ty| strip_reference(ty))
.map(|ty| builder.where_predicate()
// the type that is being bounded e.g. T
.bound().build(ty.clone())
// the bound e.g. Serialize
.bound().trait_(bound.clone()).build()
.build()))
.build()
}
fn all_variants<'a>(cx: &ExtCtxt, item: &'a ast::Item) -> Vec<&'a ast::VariantData> {
match item.node {
ast::ItemKind::Struct(ref variant_data, _) => {
vec![variant_data]
}
ast::ItemKind::Enum(ref enum_def, _) => {
enum_def.variants.iter()
.map(|variant| &variant.node.data)
.collect()
}
_ => {
cx.span_bug(item.span, "expected Item to be Struct or Enum");
}
}
}
fn all_struct_fields(variant_data: &ast::VariantData) -> &[ast::StructField] {
match *variant_data {
ast::VariantData::Struct(ref fields, _) |
ast::VariantData::Tuple(ref fields, _) => {
fields
}
ast::VariantData::Unit(_) => {
&[]
}
}
}
// Rust <1.7 enforces that `where` clauses involve generic type parameters. The
// corresponding compiler error is E0193. It is no longer enforced in Rust >=1.7
// so this filtering can be removed in the future when we stop supporting <1.7.
//
// E0193 means we must not generate a `where` clause like `i32: Serialize`
// because even though i32 implements Serialize, i32 is not a generic type
// parameter. Clauses like `T: Serialize` and `Option<T>: Serialize` are okay.
// This function decides whether a given type references any of the generic type
// parameters in the input `Generics`.
fn contains_generic(ty: &ast::Ty, generics: &ast::Generics) -> bool {
struct FindGeneric<'a> {
generic_names: &'a HashSet<ast::Name>,
found_generic: bool,
}
impl<'a, 'v> visit::Visitor<'v> for FindGeneric<'a> {
fn visit_path(&mut self, path: &'v ast::Path, _id: ast::NodeId) {
if !path.global
&& path.segments.len() == 1
&& self.generic_names.contains(&path.segments[0].identifier.name) {
self.found_generic = true;
} else {
visit::walk_path(self, path);
}
}
}
let generic_names: HashSet<_> = generics.ty_params.iter()
.map(|ty_param| ty_param.ident.name)
.collect();
let mut visitor = FindGeneric {
generic_names: &generic_names,
found_generic: false,
};
visit::walk_ty(&mut visitor, ty);
visitor.found_generic
}
// This is required to handle types that use both a reference and a value of
// the same type, as in:
//
// enum Test<'a, T> where T: 'a {
// Lifetime(&'a T),
// NoLifetime(T),
// }
//
// Preserving references, we would generate an impl like:
//
// impl<'a, T> Serialize for Test<'a, T>
// where &'a T: Serialize,
// T: Serialize { ... }
//
// And taking a reference to one of the elements would fail with:
//
// error: cannot infer an appropriate lifetime for pattern due
// to conflicting requirements [E0495]
// Test::NoLifetime(ref v) => { ... }
// ^~~~~
//
// Instead, we strip references before adding `T: Serialize` bounds in order to
// generate:
//
// impl<'a, T> Serialize for Test<'a, T>
// where T: Serialize { ... }
fn strip_reference(ty: &P<ast::Ty>) -> &P<ast::Ty> {
match ty.node {
ast::TyKind::Rptr(_, ref mut_ty) => &mut_ty.ty,
_ => ty
}
}
+336 -838
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -1,2 +0,0 @@
/// Error returned if failed to parse attribute.
pub struct Error;
+133
View File
@@ -0,0 +1,133 @@
use std::collections::HashMap;
use aster;
use syntax::ast;
use syntax::attr;
use syntax::ext::base::ExtCtxt;
use syntax::ptr::P;
use attr::FieldAttrs;
enum Rename<'a> {
None,
Global(&'a ast::Lit),
Format(HashMap<P<ast::Expr>, &'a ast::Lit>)
}
fn rename<'a>(
builder: &aster::AstBuilder,
mi: &'a ast::MetaItem,
) -> Option<Rename<'a>>
{
match mi.node {
ast::MetaNameValue(ref n, ref lit) => {
if n == &"rename" {
Some(Rename::Global(lit))
} else {
None
}
},
ast::MetaList(ref n, ref items) => {
if n == &"rename" {
let mut m = HashMap::new();
m.extend(
items.iter()
.filter_map(
|item|
match item.node {
ast::MetaNameValue(ref n, ref lit) =>
Some((builder.expr().str(n),
lit)),
_ => None
}));
Some(Rename::Format(m))
} else {
None
}
},
_ => None
}
}
fn default_value(mi: &ast::MetaItem) -> bool {
if let ast::MetaItem_::MetaWord(ref n) = mi.node {
n == &"default"
} else {
false
}
}
fn field_attrs<'a>(
builder: &aster::AstBuilder,
field: &'a ast::StructField,
) -> (Rename<'a>, bool) {
field.node.attrs.iter()
.find(|sa| {
if let ast::MetaList(ref n, _) = sa.node.value.node {
n == &"serde"
} else {
false
}
})
.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))))
} else {
Some((Rename::None, false))
}
})
.unwrap_or((Rename::None, false))
}
pub fn struct_field_attrs(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
struct_def: &ast::StructDef,
) -> Vec<FieldAttrs> {
struct_def.fields.iter()
.map(|field| {
match field_attrs(builder, field) {
(Rename::Global(rename), default_value) =>
FieldAttrs::new(
default_value,
builder.expr().build_lit(P(rename.clone()))),
(Rename::Format(renames), default_value) => {
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(
default_value,
default_field_name(cx, builder, field.node.kind),
res)
},
(Rename::None, default_value) => {
FieldAttrs::new(
default_value,
default_field_name(cx, builder, field.node.kind))
}
}
})
.collect()
}
fn default_field_name(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
kind: ast::StructFieldKind,
) -> P<ast::Expr> {
match kind {
ast::NamedField(name, _) => {
builder.expr().str(name)
}
ast::UnnamedField(_) => {
cx.bug("struct has named and unnamed fields")
}
}
}
+11 -22
View File
@@ -1,7 +1,3 @@
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
#![cfg_attr(feature = "nightly-testing", feature(plugin))]
#![cfg_attr(feature = "nightly-testing", allow(too_many_arguments))]
#![cfg_attr(feature = "nightly-testing", allow(used_underscore_binding))]
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))] #![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
#![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))] #![cfg_attr(not(feature = "with-syntex"), plugin(quasi_macros))]
@@ -12,18 +8,13 @@ extern crate quasi;
extern crate syntex; extern crate syntex;
#[cfg(feature = "with-syntex")] #[cfg(feature = "with-syntex")]
#[macro_use]
extern crate syntex_syntax as syntax; extern crate syntex_syntax as syntax;
#[cfg(not(feature = "with-syntex"))] #[cfg(not(feature = "with-syntex"))]
#[macro_use]
extern crate syntax; extern crate syntax;
#[cfg(not(feature = "with-syntex"))] #[cfg(not(feature = "with-syntex"))]
extern crate rustc_plugin; extern crate rustc;
#[cfg(not(feature = "with-syntex"))]
use syntax::feature_gate::AttributeType;
#[cfg(feature = "with-syntex")] #[cfg(feature = "with-syntex")]
include!(concat!(env!("OUT_DIR"), "/lib.rs")); include!(concat!(env!("OUT_DIR"), "/lib.rs"));
@@ -35,6 +26,14 @@ include!("lib.rs.in");
pub fn register(reg: &mut syntex::Registry) { pub fn register(reg: &mut syntex::Registry) {
use syntax::{ast, fold}; use syntax::{ast, fold};
reg.add_attr("feature(custom_derive)");
reg.add_attr("feature(custom_attribute)");
reg.add_decorator("derive_Serialize", ser::expand_derive_serialize);
reg.add_decorator("derive_Deserialize", de::expand_derive_deserialize);
reg.add_post_expansion_pass(strip_attributes);
/// Strip the serde attributes from the crate. /// Strip the serde attributes from the crate.
#[cfg(feature = "with-syntex")] #[cfg(feature = "with-syntex")]
fn strip_attributes(krate: ast::Crate) -> ast::Crate { fn strip_attributes(krate: ast::Crate) -> ast::Crate {
@@ -44,7 +43,7 @@ pub fn register(reg: &mut syntex::Registry) {
impl fold::Folder for StripAttributeFolder { impl fold::Folder for StripAttributeFolder {
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> { fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
match attr.node.value.node { match attr.node.value.node {
ast::MetaItemKind::List(ref n, _) if n == &"serde" => { return None; } ast::MetaList(ref n, _) if n == &"serde" => { return None; }
_ => {} _ => {}
} }
@@ -58,18 +57,10 @@ pub fn register(reg: &mut syntex::Registry) {
fold::Folder::fold_crate(&mut StripAttributeFolder, krate) fold::Folder::fold_crate(&mut StripAttributeFolder, krate)
} }
reg.add_attr("feature(custom_derive)");
reg.add_attr("feature(custom_attribute)");
reg.add_decorator("derive_Serialize", ser::expand_derive_serialize);
reg.add_decorator("derive_Deserialize", de::expand_derive_deserialize);
reg.add_post_expansion_pass(strip_attributes);
} }
#[cfg(not(feature = "with-syntex"))] #[cfg(not(feature = "with-syntex"))]
pub fn register(reg: &mut rustc_plugin::Registry) { pub fn register(reg: &mut rustc::plugin::Registry) {
reg.register_syntax_extension( reg.register_syntax_extension(
syntax::parse::token::intern("derive_Serialize"), syntax::parse::token::intern("derive_Serialize"),
syntax::ext::base::MultiDecorator( syntax::ext::base::MultiDecorator(
@@ -79,6 +70,4 @@ pub fn register(reg: &mut rustc_plugin::Registry) {
syntax::parse::token::intern("derive_Deserialize"), syntax::parse::token::intern("derive_Deserialize"),
syntax::ext::base::MultiDecorator( syntax::ext::base::MultiDecorator(
Box::new(de::expand_derive_deserialize))); Box::new(de::expand_derive_deserialize)));
reg.register_attribute("serde".to_owned(), AttributeType::Normal);
} }
+1 -2
View File
@@ -1,5 +1,4 @@
mod attr; mod attr;
mod bound;
mod de; mod de;
mod error; mod field;
mod ser; mod ser;
+238 -399
View File
@@ -4,15 +4,16 @@ use syntax::ast::{
Ident, Ident,
MetaItem, MetaItem,
Item, Item,
Expr,
StructDef,
}; };
use syntax::ast; use syntax::ast;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::ptr::P; use syntax::ptr::P;
use attr; use field::struct_field_attrs;
use bound;
use error::Error;
pub fn expand_derive_serialize( pub fn expand_derive_serialize(
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
@@ -26,105 +27,54 @@ pub fn expand_derive_serialize(
_ => { _ => {
cx.span_err( cx.span_err(
meta_item.span, meta_item.span,
"`#[derive(Serialize)]` may only be applied to structs and enums"); "`derive` may only be applied to structs and enums");
return; return;
} }
}; };
let builder = aster::AstBuilder::new().span(span); let builder = aster::AstBuilder::new().span(span);
let impl_item = match serialize_item(cx, &builder, &item) {
Ok(item) => item,
Err(Error) => {
// An error occured, but it should have been reported already.
return;
}
};
push(Annotatable::Item(impl_item))
}
fn serialize_item(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &Item,
) -> Result<P<ast::Item>, Error> {
let generics = match item.node { let generics = match item.node {
ast::ItemKind::Struct(_, ref generics) => generics, ast::ItemStruct(_, ref generics) => generics,
ast::ItemKind::Enum(_, ref generics) => generics, ast::ItemEnum(_, ref generics) => generics,
_ => { _ => cx.bug("expected ItemStruct or ItemEnum in #[derive(Serialize)]")
cx.span_err(
item.span,
"`#[derive(Serialize)]` may only be applied to structs and enums");
return Err(Error);
}
}; };
let impl_generics = build_impl_generics(cx, builder, item, generics); let impl_generics = builder.from_generics(generics.clone())
.add_ty_param_bound(
builder.path().global().ids(&["serde", "ser", "Serialize"]).build()
)
.build();
let ty = builder.ty().path() let ty = builder.ty().path()
.segment(item.ident).with_generics(impl_generics.clone()).build() .segment(item.ident).with_generics(impl_generics.clone()).build()
.build(); .build();
let body = try!(serialize_body(cx, let body = serialize_body(
&builder, cx,
&item, &builder,
&impl_generics, &item,
ty.clone())); &impl_generics,
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(ty.clone()),
);
let where_clause = &impl_generics.where_clause; let where_clause = &impl_generics.where_clause;
let dummy_const = builder.id(format!("_IMPL_SERIALIZE_FOR_{}", item.ident)); let impl_item = quote_item!(cx,
#[automatically_derived]
Ok(quote_item!(cx, impl $impl_generics ::serde::ser::Serialize for $ty $where_clause {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] fn serialize<__S>(&self, serializer: &mut __S) -> ::std::result::Result<(), __S::Error>
const $dummy_const: () = { where __S: ::serde::ser::Serializer,
extern crate serde as _serde; {
#[automatically_derived] $body
impl $impl_generics _serde::ser::Serialize for $ty $where_clause {
fn serialize<__S>(&self, _serializer: &mut __S) -> ::std::result::Result<(), __S::Error>
where __S: _serde::ser::Serializer,
{
$body
}
}
};
).unwrap())
}
// All the generics in the input, plus a bound `T: Serialize` for each generic
// field type that will be serialized by us.
fn build_impl_generics(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &Item,
generics: &ast::Generics,
) -> ast::Generics {
let generics = bound::without_defaults(generics);
let generics = bound::with_bound(cx, builder, item, &generics,
&serialized_by_us,
&builder.path().ids(&["_serde", "ser", "Serialize"]).build());
generics
}
// Fields with a `skip_serializing` or `serialize_with` attribute are not
// serialized by us. All other fields may need a `T: Serialize` bound where T is
// the type of the field.
fn serialized_by_us(field: &ast::StructField) -> bool {
for meta_items in field.attrs.iter().filter_map(attr::get_serde_meta_items) {
for meta_item in meta_items {
match meta_item.node {
ast::MetaItemKind::Word(ref name) if name == &"skip_serializing" => {
return false
}
ast::MetaItemKind::NameValue(ref name, _) if name == &"serialize_with" => {
return false
}
_ => {}
} }
} }
} ).unwrap();
true
push(Annotatable::Item(impl_item))
} }
fn serialize_body( fn serialize_body(
@@ -133,22 +83,19 @@ fn serialize_body(
item: &Item, item: &Item,
impl_generics: &ast::Generics, impl_generics: &ast::Generics,
ty: P<ast::Ty>, ty: P<ast::Ty>,
) -> Result<P<ast::Expr>, Error> { ) -> P<ast::Expr> {
let container_attrs = try!(attr::ContainerAttrs::from_item(cx, item));
match item.node { match item.node {
ast::ItemKind::Struct(ref variant_data, _) => { ast::ItemStruct(ref struct_def, _) => {
serialize_item_struct( serialize_item_struct(
cx, cx,
builder, builder,
item,
impl_generics, impl_generics,
ty, ty,
item.span, struct_def,
variant_data,
&container_attrs,
) )
} }
ast::ItemKind::Enum(ref enum_def, _) => { ast::ItemEnum(ref enum_def, _) => {
serialize_item_enum( serialize_item_enum(
cx, cx,
builder, builder,
@@ -156,158 +103,135 @@ fn serialize_body(
impl_generics, impl_generics,
ty, ty,
enum_def, enum_def,
&container_attrs,
) )
} }
_ => { _ => cx.bug("expected ItemStruct or ItemEnum in #[derive(Serialize)]")
cx.span_bug(item.span,
"expected ItemStruct or ItemEnum in #[derive(Serialize)]");
}
} }
} }
fn serialize_item_struct( fn serialize_item_struct(
cx: &ExtCtxt, cx: &ExtCtxt,
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
item: &Item,
impl_generics: &ast::Generics, impl_generics: &ast::Generics,
ty: P<ast::Ty>, ty: P<ast::Ty>,
span: Span, struct_def: &ast::StructDef,
variant_data: &ast::VariantData, ) -> P<ast::Expr> {
container_attrs: &attr::ContainerAttrs, let mut named_fields = vec![];
) -> Result<P<ast::Expr>, Error> { let mut unnamed_fields = 0;
match *variant_data {
ast::VariantData::Unit(_) => { for field in struct_def.fields.iter() {
match field.node.kind {
ast::NamedField(name, _) => { named_fields.push(name); }
ast::UnnamedField(_) => { unnamed_fields += 1; }
}
}
match (named_fields.is_empty(), unnamed_fields == 0) {
(true, true) => {
serialize_unit_struct( serialize_unit_struct(
cx, cx,
container_attrs, &builder,
item.ident,
) )
} }
ast::VariantData::Tuple(ref fields, _) if fields.len() == 1 => { (true, false) => {
serialize_newtype_struct(
cx,
container_attrs,
)
}
ast::VariantData::Tuple(ref fields, _) => {
if fields.iter().any(|field| field.ident.is_some()) {
cx.span_bug(span, "tuple struct has named fields")
}
serialize_tuple_struct( serialize_tuple_struct(
cx, cx,
&builder, &builder,
item.ident,
impl_generics, impl_generics,
ty, ty,
fields.len(), unnamed_fields,
container_attrs,
) )
} }
ast::VariantData::Struct(ref fields, _) => { (false, true) => {
if fields.iter().any(|field| field.ident.is_none()) {
cx.span_bug(span, "struct has unnamed fields")
}
serialize_struct( serialize_struct(
cx, cx,
&builder, &builder,
item.ident,
impl_generics, impl_generics,
ty, ty,
fields, struct_def,
container_attrs, named_fields,
) )
} }
(false, false) => {
cx.bug("struct has named and unnamed fields")
}
} }
} }
fn serialize_unit_struct( fn serialize_unit_struct(
cx: &ExtCtxt, cx: &ExtCtxt,
container_attrs: &attr::ContainerAttrs, builder: &aster::AstBuilder,
) -> Result<P<ast::Expr>, Error> { type_ident: Ident
let type_name = container_attrs.name().serialize_name_expr(); ) -> P<ast::Expr> {
let type_name = builder.expr().str(type_ident);
Ok(quote_expr!(cx, quote_expr!(cx, serializer.visit_named_unit($type_name))
_serializer.serialize_unit_struct($type_name)
))
}
fn serialize_newtype_struct(
cx: &ExtCtxt,
container_attrs: &attr::ContainerAttrs,
) -> Result<P<ast::Expr>, Error> {
let type_name = container_attrs.name().serialize_name_expr();
Ok(quote_expr!(cx,
_serializer.serialize_newtype_struct($type_name, &self.0)
))
} }
fn serialize_tuple_struct( fn serialize_tuple_struct(
cx: &ExtCtxt, cx: &ExtCtxt,
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics, impl_generics: &ast::Generics,
ty: P<ast::Ty>, ty: P<ast::Ty>,
fields: usize, fields: usize,
container_attrs: &attr::ContainerAttrs, ) -> P<ast::Expr> {
) -> Result<P<ast::Expr>, Error> {
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor( let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
cx, cx,
builder, builder,
ty.clone(), ty.clone(),
builder.ty() ty,
.ref_()
.lifetime("'__a")
.build_ty(ty.clone()),
builder.id("serialize_tuple_struct_elt"),
fields, fields,
impl_generics, impl_generics,
); );
let type_name = container_attrs.name().serialize_name_expr(); let type_name = builder.expr().str(type_ident);
Ok(quote_expr!(cx, { quote_expr!(cx, {
$visitor_struct $visitor_struct
$visitor_impl $visitor_impl
_serializer.serialize_tuple_struct($type_name, Visitor { serializer.visit_named_seq($type_name, Visitor {
value: self, value: self,
state: 0, state: 0,
_structure_ty: ::std::marker::PhantomData::<&$ty>, _structure_ty: ::std::marker::PhantomData,
}) })
})) })
} }
fn serialize_struct( fn serialize_struct(
cx: &ExtCtxt, cx: &ExtCtxt,
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics, impl_generics: &ast::Generics,
ty: P<ast::Ty>, ty: P<ast::Ty>,
fields: &[ast::StructField], struct_def: &StructDef,
container_attrs: &attr::ContainerAttrs, fields: Vec<Ident>,
) -> Result<P<ast::Expr>, Error> { ) -> P<ast::Expr> {
let (visitor_struct, visitor_impl) = try!(serialize_struct_visitor( let (visitor_struct, visitor_impl) = serialize_struct_visitor(
cx, cx,
builder, builder,
ty.clone(), ty.clone(),
builder.ty() ty,
.ref_() struct_def,
.lifetime("'__a")
.build_ty(ty.clone()),
builder.id("serialize_struct_elt"),
fields,
impl_generics, impl_generics,
false, fields.iter().map(|field| quote_expr!(cx, &self.value.$field)),
)); );
let type_name = container_attrs.name().serialize_name_expr(); let type_name = builder.expr().str(type_ident);
Ok(quote_expr!(cx, { quote_expr!(cx, {
$visitor_struct $visitor_struct
$visitor_impl $visitor_impl
_serializer.serialize_struct($type_name, Visitor { serializer.visit_named_map($type_name, Visitor {
value: self, value: self,
state: 0, state: 0,
_structure_ty: ::std::marker::PhantomData::<&$ty>, _structure_ty: ::std::marker::PhantomData,
}) })
})) })
} }
fn serialize_item_enum( fn serialize_item_enum(
@@ -317,31 +241,25 @@ fn serialize_item_enum(
impl_generics: &ast::Generics, impl_generics: &ast::Generics,
ty: P<ast::Ty>, ty: P<ast::Ty>,
enum_def: &ast::EnumDef, enum_def: &ast::EnumDef,
container_attrs: &attr::ContainerAttrs, ) -> P<ast::Expr> {
) -> Result<P<ast::Expr>, Error> { let arms: Vec<ast::Arm> = enum_def.variants.iter()
let arms: Vec<_> = try!( .map(|variant| {
enum_def.variants.iter() serialize_variant(
.enumerate() cx,
.map(|(variant_index, variant)| { builder,
serialize_variant( type_ident,
cx, impl_generics,
builder, ty.clone(),
type_ident, variant,
impl_generics, )
ty.clone(), })
variant, .collect();
variant_index,
container_attrs,
)
})
.collect()
);
Ok(quote_expr!(cx, quote_expr!(cx,
match *self { match *self {
$arms $arms
} }
)) )
} }
fn serialize_variant( fn serialize_variant(
@@ -351,96 +269,65 @@ fn serialize_variant(
generics: &ast::Generics, generics: &ast::Generics,
ty: P<ast::Ty>, ty: P<ast::Ty>,
variant: &ast::Variant, variant: &ast::Variant,
variant_index: usize, ) -> ast::Arm {
container_attrs: &attr::ContainerAttrs, let type_name = builder.expr().str(type_ident);
) -> Result<ast::Arm, Error> {
let type_name = container_attrs.name().serialize_name_expr();
let variant_ident = variant.node.name; let variant_ident = variant.node.name;
let variant_attrs = try!(attr::VariantAttrs::from_variant(cx, variant)); let variant_name = builder.expr().str(variant_ident);
let variant_name = variant_attrs.name().serialize_name_expr();
match variant.node.data { match variant.node.kind {
ast::VariantData::Unit(_) => { ast::TupleVariantKind(ref args) if args.is_empty() => {
let pat = builder.pat().path()
.id(type_ident).id(variant_ident)
.build();
Ok(quote_arm!(cx,
$pat => {
_serde::ser::Serializer::serialize_unit_variant(
_serializer,
$type_name,
$variant_index,
$variant_name,
)
}
))
},
ast::VariantData::Tuple(ref fields, _) if fields.len() == 1 => {
let field = builder.id("__simple_value");
let field = builder.pat().ref_id(field);
let pat = builder.pat().enum_() let pat = builder.pat().enum_()
.id(type_ident).id(variant_ident).build() .id(type_ident).id(variant_ident).build()
.with_pats(Some(field).into_iter())
.build(); .build();
Ok(quote_arm!(cx, quote_arm!(cx,
$pat => { $pat => {
_serde::ser::Serializer::serialize_newtype_variant( ::serde::ser::Serializer::visit_enum_unit(
_serializer, serializer,
$type_name, $type_name,
$variant_index,
$variant_name, $variant_name,
__simple_value,
) )
} }
)) )
}, }
ast::VariantData::Tuple(ref fields, _) => { ast::TupleVariantKind(ref args) => {
let field_names: Vec<ast::Ident> = (0 .. fields.len()) let fields: Vec<ast::Ident> = (0 .. args.len())
.map(|i| builder.id(format!("__field{}", i))) .map(|i| builder.id(format!("__field{}", i)))
.collect(); .collect();
let pat = builder.pat().enum_() let pat = builder.pat().enum_()
.id(type_ident).id(variant_ident).build() .id(type_ident).id(variant_ident).build()
.with_pats( .with_pats(fields.iter().map(|field| builder.pat().ref_id(field)))
field_names.iter()
.map(|field| builder.pat().ref_id(field))
)
.build(); .build();
let expr = serialize_tuple_variant( let expr = serialize_tuple_variant(
cx, cx,
builder, builder,
type_name, type_name,
variant_index,
variant_name, variant_name,
generics, generics,
ty, ty,
args,
fields, fields,
field_names,
); );
Ok(quote_arm!(cx, quote_arm!(cx, $pat => { $expr })
$pat => { $expr }
))
} }
ast::VariantData::Struct(ref fields, _) => { ast::StructVariantKind(ref struct_def) => {
let field_names: Vec<_> = (0 .. fields.len()) let fields: Vec<_> = (0 .. struct_def.fields.len())
.map(|i| builder.id(format!("__field{}", i))) .map(|i| builder.id(format!("__field{}", i)))
.collect(); .collect();
let pat = builder.pat().struct_() let pat = builder.pat().struct_()
.id(type_ident).id(variant_ident).build() .id(type_ident).id(variant_ident).build()
.with_pats( .with_pats(
field_names.iter() fields.iter()
.zip(fields.iter()) .zip(struct_def.fields.iter())
.map(|(id, field)| { .map(|(id, field)| {
let name = match field.ident { let name = match field.node.kind {
Some(name) => name, ast::NamedField(name, _) => name,
None => { ast::UnnamedField(_) => {
cx.span_bug(field.span, "struct variant has unnamed fields") cx.bug("struct variant has unnamed fields")
} }
}; };
@@ -449,21 +336,18 @@ fn serialize_variant(
) )
.build(); .build();
let expr = try!(serialize_struct_variant( let expr = serialize_struct_variant(
cx, cx,
builder, builder,
variant_index, type_name,
variant_name, variant_name,
generics, generics,
ty, ty,
struct_def,
fields, fields,
field_names, );
container_attrs,
));
Ok(quote_arm!(cx, quote_arm!(cx, $pat => { $expr })
$pat => { $expr }
))
} }
} }
} }
@@ -472,20 +356,19 @@ fn serialize_tuple_variant(
cx: &ExtCtxt, cx: &ExtCtxt,
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
type_name: P<ast::Expr>, type_name: P<ast::Expr>,
variant_index: usize,
variant_name: P<ast::Expr>, variant_name: P<ast::Expr>,
generics: &ast::Generics, generics: &ast::Generics,
structure_ty: P<ast::Ty>, structure_ty: P<ast::Ty>,
fields: &[ast::StructField], args: &[ast::VariantArg],
field_names: Vec<Ident>, fields: Vec<Ident>,
) -> P<ast::Expr> { ) -> P<ast::Expr> {
let variant_ty = builder.ty().tuple() let variant_ty = builder.ty().tuple()
.with_tys( .with_tys(
fields.iter().map(|field| { args.iter().map(|arg| {
builder.ty() builder.ty()
.ref_() .ref_()
.lifetime("'__a") .lifetime("'__a")
.build_ty(field.ty.clone()) .build_ty(arg.ty.clone())
}) })
) )
.build(); .build();
@@ -493,17 +376,18 @@ fn serialize_tuple_variant(
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor( let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
cx, cx,
builder, builder,
structure_ty.clone(), structure_ty,
variant_ty, variant_ty,
builder.id("serialize_tuple_variant_elt"), args.len(),
fields.len(),
generics, generics,
); );
let value_expr = builder.expr().tuple() let value_expr = builder.expr().tuple()
.with_exprs( .with_exprs(
field_names.iter().map(|field| { fields.iter().map(|field| {
builder.expr().id(field) builder.expr()
.addr_of()
.id(field)
}) })
) )
.build(); .build();
@@ -511,10 +395,10 @@ fn serialize_tuple_variant(
quote_expr!(cx, { quote_expr!(cx, {
$visitor_struct $visitor_struct
$visitor_impl $visitor_impl
_serializer.serialize_tuple_variant($type_name, $variant_index, $variant_name, Visitor { serializer.visit_enum_seq($type_name, $variant_name, Visitor {
value: $value_expr, value: $value_expr,
state: 0, state: 0,
_structure_ty: ::std::marker::PhantomData::<&$structure_ty>, _structure_ty: ::std::marker::PhantomData,
}) })
}) })
} }
@@ -522,90 +406,57 @@ fn serialize_tuple_variant(
fn serialize_struct_variant( fn serialize_struct_variant(
cx: &ExtCtxt, cx: &ExtCtxt,
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
variant_index: usize, type_name: P<ast::Expr>,
variant_name: P<ast::Expr>, variant_name: P<ast::Expr>,
generics: &ast::Generics, generics: &ast::Generics,
ty: P<ast::Ty>, structure_ty: P<ast::Ty>,
fields: &[ast::StructField], struct_def: &ast::StructDef,
field_names: Vec<Ident>, fields: Vec<Ident>,
container_attrs: &attr::ContainerAttrs, ) -> P<ast::Expr> {
) -> Result<P<ast::Expr>, Error> { let value_ty = builder.ty().tuple()
let variant_generics = builder.generics() .with_tys(
.with(generics.clone()) struct_def.fields.iter().map(|field| {
.add_lifetime_bound("'__serde_variant") builder.ty()
.lifetime_name("'__serde_variant")
.build();
let variant_struct = builder.item().struct_("__VariantStruct")
.with_generics(variant_generics.clone())
.with_fields(
fields.iter().map(|field| {
builder.struct_field(field.ident.expect("struct has unnamed fields"))
.with_attrs(field.attrs.iter().cloned())
.ty()
.ref_() .ref_()
.lifetime("'__serde_variant") .lifetime("'__a")
.build_ty(field.ty.clone()) .build_ty(field.node.ty.clone())
}) })
) )
.field("__serde_container_ty")
.ty().phantom_data().build(ty.clone())
.build(); .build();
let variant_expr = builder.expr().struct_id("__VariantStruct") let value_expr = builder.expr().tuple()
.with_id_exprs( .with_exprs(
fields.iter() fields.iter().map(|field| {
.zip(field_names.iter()) builder.expr()
.map(|(field, field_name)| { .addr_of()
( .id(field)
field.ident.expect("struct has unnamed fields"), })
builder.expr().id(field_name),
)
})
) )
.field("__serde_container_ty").path()
.global()
.id("std").id("marker")
.segment("PhantomData")
.with_ty(ty.clone())
.build()
.build()
.build(); .build();
let variant_ty = builder.ty().path() let (visitor_struct, visitor_impl) = serialize_struct_visitor(
.segment("__VariantStruct")
.with_generics(variant_generics.clone())
.build()
.build();
let (visitor_struct, visitor_impl) = try!(serialize_struct_visitor(
cx, cx,
builder, builder,
variant_ty.clone(), structure_ty,
variant_ty.clone(), value_ty,
builder.id("serialize_struct_variant_elt"), struct_def,
fields, generics,
&variant_generics, (0 .. fields.len()).map(|i| {
true, builder.expr()
)); .tup_field(i)
.field("value").self_()
})
);
let container_name = container_attrs.name().serialize_name_expr(); quote_expr!(cx, {
Ok(quote_expr!(cx, {
$variant_struct
$visitor_struct $visitor_struct
$visitor_impl $visitor_impl
_serializer.serialize_struct_variant( serializer.visit_enum_map($type_name, $variant_name, Visitor {
$container_name, value: $value_expr,
$variant_index, state: 0,
$variant_name, _structure_ty: ::std::marker::PhantomData,
Visitor { })
value: $variant_expr, })
state: 0,
_structure_ty: ::std::marker::PhantomData,
},
)
}))
} }
fn serialize_tuple_struct_visitor( fn serialize_tuple_struct_visitor(
@@ -613,21 +464,20 @@ fn serialize_tuple_struct_visitor(
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
structure_ty: P<ast::Ty>, structure_ty: P<ast::Ty>,
variant_ty: P<ast::Ty>, variant_ty: P<ast::Ty>,
serializer_method: ast::Ident,
fields: usize, fields: usize,
generics: &ast::Generics generics: &ast::Generics
) -> (P<ast::Item>, P<ast::Item>) { ) -> (P<ast::Item>, P<ast::Item>) {
let arms: Vec<ast::Arm> = (0 .. fields) let arms: Vec<ast::Arm> = (0 .. fields)
.map(|i| { .map(|i| {
let expr = builder.expr().method_call(serializer_method) let expr = builder.expr()
.id("_serializer") .tup_field(i)
.arg().ref_().tup_field(i).field("value").self_() .field("value").self_();
.build();
quote_arm!(cx, quote_arm!(cx,
$i => { $i => {
self.state += 1; self.state += 1;
Ok(Some(try!($expr))) let v = try!(serializer.visit_seq_elt(&$expr));
Ok(Some(v))
} }
) )
}) })
@@ -644,22 +494,29 @@ fn serialize_tuple_struct_visitor(
.strip_bounds() .strip_bounds()
.build(); .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, quote_item!(cx,
struct Visitor $visitor_impl_generics $where_clause { struct Visitor $visitor_impl_generics $where_clause {
state: usize, state: usize,
value: $variant_ty, value: $variant_ty,
_structure_ty: ::std::marker::PhantomData<&'__a $structure_ty>, _structure_ty: $structure_ty,
} }
).unwrap(), ).unwrap(),
quote_item!(cx, quote_item!(cx,
impl $visitor_impl_generics _serde::ser::SeqVisitor impl $visitor_impl_generics ::serde::ser::SeqVisitor
for Visitor $visitor_generics for Visitor $visitor_generics
$where_clause { $where_clause {
#[inline] #[inline]
fn visit<__S>(&mut self, _serializer: &mut __S) -> ::std::result::Result<Option<()>, __S::Error> fn visit<S>(&mut self, serializer: &mut S) -> ::std::result::Result<Option<()>, S::Error>
where __S: _serde::ser::Serializer where S: ::serde::ser::Serializer
{ {
match self.state { match self.state {
$arms $arms
@@ -676,48 +533,39 @@ fn serialize_tuple_struct_visitor(
) )
} }
fn serialize_struct_visitor( fn serialize_struct_visitor<I>(
cx: &ExtCtxt, cx: &ExtCtxt,
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
structure_ty: P<ast::Ty>, structure_ty: P<ast::Ty>,
variant_ty: P<ast::Ty>, variant_ty: P<ast::Ty>,
serializer_method: ast::Ident, struct_def: &StructDef,
fields: &[ast::StructField],
generics: &ast::Generics, generics: &ast::Generics,
is_enum: bool, value_exprs: I,
) -> Result<(P<ast::Item>, P<ast::Item>), Error> { ) -> (P<ast::Item>, P<ast::Item>)
let field_attrs = try!( where I: Iterator<Item=P<ast::Expr>>,
attr::get_struct_field_attrs(cx, &structure_ty, generics, fields, is_enum) {
); let len = struct_def.fields.len();
let arms: Vec<ast::Arm> = fields.iter().zip(field_attrs.iter()) let field_attrs = struct_field_attrs(cx, builder, struct_def);
.filter(|&(_, ref field_attr)| !field_attr.skip_serializing_field())
let arms: Vec<ast::Arm> = field_attrs.into_iter()
.zip(value_exprs)
.enumerate() .enumerate()
.map(|(i, (ref field, ref field_attr))| { .map(|(i, (field, value_expr))| {
let name = field.ident.expect("struct has unnamed field"); let key_expr = field.serializer_key_expr(cx);
let key_expr = field_attr.name().serialize_name_expr();
let stmt = if let Some(expr) = field_attr.skip_serializing_field_if() {
Some(quote_stmt!(cx, if $expr { continue; }))
} else {
None
};
let field_expr = match field_attr.serialize_with() {
Some(expr) => expr.clone(),
None => quote_expr!(cx, &self.value.$name),
};
let expr = quote_expr!(cx,
_serializer.$serializer_method($key_expr, $field_expr)
);
quote_arm!(cx, quote_arm!(cx,
$i => { $i => {
self.state += 1; self.state += 1;
$stmt Ok(
return Ok(Some(try!($expr))); Some(
try!(
serializer.visit_map_elt(
$key_expr,
$value_expr,
)
)
)
)
} }
) )
}) })
@@ -734,43 +582,34 @@ fn serialize_struct_visitor(
.strip_bounds() .strip_bounds()
.build(); .build();
let len = field_attrs.iter() // Variants don't necessarily reference all generic lifetimes and type parameters,
.filter(|field_attr| !field_attr.skip_serializing_field()) // so to avoid a compilation failure, we'll just add a phantom type to capture these
.map(|field_attr| { // unused values.
match field_attr.skip_serializing_field_if() { let structure_ty = builder.ty()
Some(expr) => { .phantom_data()
quote_expr!(cx, if $expr { 0 } else { 1 }) .build(structure_ty);
}
None => {
quote_expr!(cx, 1)
}
}
})
.fold(quote_expr!(cx, 0), |sum, expr| quote_expr!(cx, $sum + $expr));
Ok(( (
quote_item!(cx, quote_item!(cx,
struct Visitor $visitor_impl_generics $where_clause { struct Visitor $visitor_impl_generics $where_clause {
state: usize, state: usize,
value: $variant_ty, value: $variant_ty,
_structure_ty: ::std::marker::PhantomData<&'__a $structure_ty>, _structure_ty: $structure_ty,
} }
).unwrap(), ).unwrap(),
quote_item!(cx, quote_item!(cx,
impl $visitor_impl_generics impl $visitor_impl_generics
_serde::ser::MapVisitor ::serde::ser::MapVisitor
for Visitor $visitor_generics for Visitor $visitor_generics
$where_clause { $where_clause {
#[inline] #[inline]
fn visit<__S>(&mut self, _serializer: &mut __S) -> ::std::result::Result<Option<()>, __S::Error> fn visit<S>(&mut self, serializer: &mut S) -> ::std::result::Result<Option<()>, S::Error>
where __S: _serde::ser::Serializer, where S: ::serde::ser::Serializer,
{ {
loop { match self.state {
match self.state { $arms
$arms _ => Ok(None)
_ => { return Ok(None); }
}
} }
} }
@@ -780,5 +619,5 @@ fn serialize_struct_visitor(
} }
} }
).unwrap(), ).unwrap(),
)) )
} }
+6 -20
View File
@@ -1,33 +1,19 @@
[package] [package]
name = "serde_macros" name = "serde_macros"
version = "0.7.5" version = "0.4.2"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework" description = "Macros to auto-generate implementations for the serde framework"
repository = "https://github.com/serde-rs/serde" repository = "https://github.com/erickt/rust-serde"
documentation = "https://github.com/serde-rs/serde"
keywords = ["serde", "serialization"]
[lib] [lib]
name = "serde_macros" name = "serde_macros"
plugin = true plugin = true
[features]
nightly-testing = ["clippy", "serde/nightly-testing", "serde_codegen/nightly-testing"]
[dependencies] [dependencies]
clippy = { version = "^0.*", optional = true } serde_codegen = { version = "*", path = "../serde_codegen", default-features = false, features = ["nightly"] }
serde_codegen = { version = "^0.7.5", path = "../serde_codegen", default-features = false, features = ["nightly"] }
[dev-dependencies] [dev-dependencies]
compiletest_rs = "^0.1.1" num = "*"
rustc-serialize = "^0.3.16" rustc-serialize = "*"
serde = { version = "^0.7.5", path = "../serde" } serde = { version = "*", path = "../serde" }
[[test]]
name = "test"
path = "tests/test.rs"
[[bench]]
name = "bench"
path = "benches/bench.rs"
+1 -1
View File
@@ -1,7 +1,7 @@
#![feature(custom_attribute, custom_derive, plugin, test)] #![feature(custom_attribute, custom_derive, plugin, test)]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![plugin(serde_macros)] #![plugin(serde_macros)]
extern crate num;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate serde; extern crate serde;
extern crate test; extern crate test;
+64
View File
@@ -0,0 +1,64 @@
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
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.
#[derive(Debug, Serialize, Deserialize)]
struct Point {
x: i32,
y: i32,
}
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();
println!("{}", serialized_point);
// prints:
//
// {"x":5,"y":6}
// There is also support for pretty printing using `to_string_pretty`:
let serialized_point = json::to_string_pretty(&point).unwrap();
println!("{}", serialized_point);
// prints:
//
// {
// "x":5,
// "y":6
// }
// Values can also be deserialized with the same style using `from_str`:
let deserialized_point: Point = json::from_str(&serialized_point).unwrap();
println!("{:?}", deserialized_point);
// prints:
//
// Point { x: 5, y: 6 }
// `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();
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();
println!("{:?}", deserialized_value);
// prints:
//
// {"x":5,"y":6}
}
+2 -4
View File
@@ -1,12 +1,10 @@
#![feature(plugin_registrar, rustc_private)] #![feature(plugin_registrar, rustc_private)]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
extern crate serde_codegen; extern crate serde_codegen;
extern crate rustc_plugin; extern crate rustc;
#[plugin_registrar] #[plugin_registrar]
#[doc(hidden)] #[doc(hidden)]
pub fn plugin_registrar(reg: &mut rustc_plugin::Registry) { pub fn plugin_registrar(reg: &mut rustc::plugin::Registry) {
serde_codegen::register(reg); serde_codegen::register(reg);
} }
@@ -1,30 +0,0 @@
#![feature(custom_attribute, custom_derive, plugin)]
#![plugin(serde_macros)]
extern crate serde;
#[derive(Serialize)]
#[serde(abc="xyz")] //~ unknown serde container attribute `abc = "xyz"`
struct Foo {
x: u32,
}
#[derive(Deserialize)]
#[serde(abc="xyz")] //~ unknown serde container attribute `abc = "xyz"`
struct Foo {
x: u32,
}
#[derive(Serialize)]
struct Foo {
#[serde(abc="xyz")] //~ unknown serde field attribute `abc = "xyz"`
x: u32,
}
#[derive(Deserialize)]
struct Foo {
#[serde(abc="xyz")] //~ unknown serde field attribute `abc = "xyz"`
x: u32,
}
fn main() { }
-25
View File
@@ -1,25 +0,0 @@
extern crate compiletest_rs as compiletest;
use std::path::PathBuf;
use std::env::var;
fn run_mode(mode: &'static str) {
let mut config = compiletest::default_config();
let cfg_mode = mode.parse().ok().expect("Invalid mode");
config.target_rustcflags = Some("-L target/debug/ -L target/debug/deps/".to_owned());
if let Ok(name) = var::<&str>("TESTNAME") {
let s : String = name.to_owned();
config.filter = Some(s)
}
config.mode = cfg_mode;
config.src_base = PathBuf::from(format!("tests/{}", mode));
compiletest::run_tests(&config);
}
#[test]
fn compile_test() {
run_mode("compile-fail");
}
-2
View File
@@ -5,5 +5,3 @@ extern crate serde;
extern crate test; extern crate test;
include!("../../serde_tests/tests/test.rs.in"); include!("../../serde_tests/tests/test.rs.in");
mod compile_tests;
+6 -11
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_tests" name = "serde_tests"
version = "0.7.5" version = "0.4.1"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
@@ -10,21 +10,16 @@ readme = "README.md"
keywords = ["serialization"] keywords = ["serialization"]
build = "build.rs" build = "build.rs"
[features]
nightly-testing = ["clippy", "serde/nightly-testing", "serde_codegen/nightly-testing"]
[build-dependencies] [build-dependencies]
syntex = { version = "^0.32.0" } syntex = { version = "*", optional = true }
syntex_syntax = { version = "^0.32.0" } syntex_syntax = { version = "*" }
serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-syntex"] } serde_codegen = { version = "*", path = "../serde_codegen", features = ["with-syntex"] }
[dev-dependencies] [dev-dependencies]
rustc-serialize = "^0.3.16" num = "*"
rustc-serialize = "*"
serde = { version = "*", path = "../serde" } serde = { version = "*", path = "../serde" }
syntex = "^0.32.0" syntex = "*"
[dependencies]
clippy = { version = "^0.*", optional = true }
[[test]] [[test]]
name = "test" name = "test"
+1 -2
View File
@@ -1,7 +1,6 @@
#![feature(test)] #![feature(test)]
#![cfg_attr(feature = "nightly", feature(plugin))]
#![cfg_attr(feature = "nightly", plugin(clippy))]
extern crate num;
extern crate rustc_serialize; extern crate rustc_serialize;
extern crate serde; extern crate serde;
extern crate test; extern crate test;
+1
View File
@@ -1,4 +1,5 @@
mod bench_enum; mod bench_enum;
mod bench_log;
mod bench_map; mod bench_map;
mod bench_struct; mod bench_struct;
mod bench_vec; mod bench_vec;
+76 -98
View File
@@ -1,6 +1,4 @@
use test::Bencher; use test::Bencher;
use std::error;
use std::fmt;
use rustc_serialize::{Decoder, Decodable}; use rustc_serialize::{Decoder, Decodable};
use serde; use serde;
use serde::de::{Deserializer, Deserialize}; use serde::de::{Deserializer, Deserialize};
@@ -17,34 +15,18 @@ pub enum Animal {
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
EndOfStream, EndOfStreamError,
Syntax, SyntaxError,
} }
impl serde::de::Error for Error { impl serde::de::Error for Error {
fn custom<T: Into<String>>(_: T) -> Error { Error::Syntax } fn syntax_error() -> Error { Error::SyntaxError }
fn end_of_stream() -> Error { Error::EndOfStream } fn end_of_stream_error() -> Error { Error::EndOfStreamError }
fn unknown_field(_: &str) -> Error { Error::Syntax } fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn missing_field(_: &'static str) -> Error { Error::Syntax } fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError }
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(format!("{:?}", self).as_ref())
}
}
impl error::Error for Error {
fn description(&self) -> &str {
"Serde Deserialization Error"
}
fn cause(&self) -> Option<&error::Error> {
None
}
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@@ -54,11 +36,12 @@ mod decoder {
use super::{Animal, Error}; use super::{Animal, Error};
use super::Animal::{Dog, Frog}; use super::Animal::{Dog, Frog};
use self::State::{AnimalState, IsizeState, StringState};
enum State { enum State {
Animal(Animal), AnimalState(Animal),
Isize(isize), IsizeState(isize),
String(String), StringState(String),
} }
pub struct AnimalDecoder { pub struct AnimalDecoder {
@@ -70,7 +53,7 @@ mod decoder {
#[inline] #[inline]
pub fn new(animal: Animal) -> AnimalDecoder { pub fn new(animal: Animal) -> AnimalDecoder {
AnimalDecoder { AnimalDecoder {
stack: vec!(State::Animal(animal)), stack: vec!(AnimalState(animal)),
} }
} }
} }
@@ -78,35 +61,35 @@ mod decoder {
impl Decoder for AnimalDecoder { impl Decoder for AnimalDecoder {
type Error = Error; type Error = Error;
fn error(&mut self, _: &str) -> Error { Error::Syntax } fn error(&mut self, _: &str) -> Error { Error::SyntaxError }
// Primitive types: // Primitive types:
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::Syntax) } fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::Syntax) } fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::SyntaxError) }
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::Syntax) } fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::Syntax) } fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::Syntax) } fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::Syntax) } fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
#[inline] #[inline]
fn read_isize(&mut self) -> Result<isize, Error> { fn read_isize(&mut self) -> Result<isize, Error> {
match self.stack.pop() { match self.stack.pop() {
Some(State::Isize(x)) => Ok(x), Some(IsizeState(x)) => Ok(x),
_ => Err(Error::Syntax), _ => Err(Error::SyntaxError),
} }
} }
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::Syntax) } fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::Syntax) } fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::Syntax) } fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::Syntax) } fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::Syntax) } fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::Syntax) } fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::Syntax) } fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
fn read_char(&mut self) -> Result<char, Error> { Err(Error::Syntax) } fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
#[inline] #[inline]
fn read_str(&mut self) -> Result<String, Error> { fn read_str(&mut self) -> Result<String, Error> {
match self.stack.pop() { match self.stack.pop() {
Some(State::String(x)) => Ok(x), Some(StringState(x)) => Ok(x),
_ => Err(Error::Syntax), _ => Err(Error::SyntaxError),
} }
} }
@@ -116,15 +99,15 @@ mod decoder {
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
{ {
match self.stack.pop() { match self.stack.pop() {
Some(State::Animal(animal)) => { Some(AnimalState(animal)) => {
self.stack.push(State::Animal(animal)); self.stack.push(AnimalState(animal));
if name == "Animal" { if name == "Animal" {
f(self) f(self)
} else { } else {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
_ => Err(Error::Syntax) _ => Err(Error::SyntaxError)
} }
} }
@@ -133,18 +116,18 @@ mod decoder {
F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>,
{ {
let name = match self.stack.pop() { let name = match self.stack.pop() {
Some(State::Animal(Dog)) => "Dog", Some(AnimalState(Dog)) => "Dog",
Some(State::Animal(Frog(x0, x1))) => { Some(AnimalState(Frog(x0, x1))) => {
self.stack.push(State::Isize(x1)); self.stack.push(IsizeState(x1));
self.stack.push(State::String(x0)); self.stack.push(StringState(x0));
"Frog" "Frog"
} }
_ => { return Err(Error::Syntax); } _ => { return Err(Error::SyntaxError); }
}; };
let idx = match names.iter().position(|n| *n == name) { let idx = match names.iter().position(|n| *n == name) {
Some(idx) => idx, Some(idx) => idx,
None => { return Err(Error::Syntax); } None => { return Err(Error::SyntaxError); }
}; };
f(self, idx) f(self, idx)
@@ -160,56 +143,56 @@ mod decoder {
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
// Specialized types: // Specialized types:
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder, bool) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder, bool) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
#[inline] #[inline]
@@ -229,19 +212,19 @@ mod decoder {
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>, F: FnOnce(&mut AnimalDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
} }
@@ -255,10 +238,10 @@ mod deserializer {
#[derive(Debug)] #[derive(Debug)]
enum State { enum State {
Animal(Animal), AnimalState(Animal),
Isize(isize), IsizeState(isize),
Str(&'static str), StrState(&'static str),
String(String), StringState(String),
UnitState, UnitState,
} }
@@ -270,7 +253,7 @@ mod deserializer {
#[inline] #[inline]
pub fn new(animal: Animal) -> AnimalDeserializer { pub fn new(animal: Animal) -> AnimalDeserializer {
AnimalDeserializer { AnimalDeserializer {
stack: vec!(State::Animal(animal)), stack: vec!(State::AnimalState(animal)),
} }
} }
} }
@@ -279,60 +262,57 @@ mod deserializer {
type Error = Error; type Error = Error;
#[inline] #[inline]
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error> fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.stack.pop() { match self.stack.pop() {
Some(State::Isize(value)) => { Some(State::IsizeState(value)) => {
visitor.visit_isize(value) visitor.visit_isize(value)
} }
Some(State::String(value)) => { Some(State::StringState(value)) => {
visitor.visit_string(value) visitor.visit_string(value)
} }
Some(State::Str(value)) => { Some(State::StrState(value)) => {
visitor.visit_str(value) visitor.visit_str(value)
} }
Some(State::UnitState) => { Some(State::UnitState) => {
visitor.visit_unit() visitor.visit_unit()
} }
Some(_) => { Some(_) => {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
None => { None => {
Err(Error::EndOfStream) Err(Error::EndOfStreamError)
} }
} }
} }
#[inline] #[inline]
fn deserialize_enum<V>(&mut self, fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
_name: &str,
_variants: &[&str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor, where V: de::EnumVisitor,
{ {
match self.stack.pop() { match self.stack.pop() {
Some(State::Animal(Animal::Dog)) => { Some(State::AnimalState(Animal::Dog)) => {
self.stack.push(State::UnitState); self.stack.push(State::UnitState);
self.stack.push(State::Str("Dog")); self.stack.push(State::StrState("Dog"));
visitor.visit(DogVisitor { visitor.visit(DogVisitor {
de: self, de: self,
}) })
} }
Some(State::Animal(Animal::Frog(x0, x1))) => { Some(State::AnimalState(Animal::Frog(x0, x1))) => {
self.stack.push(State::Isize(x1)); self.stack.push(State::IsizeState(x1));
self.stack.push(State::String(x0)); self.stack.push(State::StringState(x0));
self.stack.push(State::Str("Frog")); self.stack.push(State::StrState("Frog"));
visitor.visit(FrogVisitor { visitor.visit(FrogVisitor {
de: self, de: self,
state: 0, state: 0,
}) })
} }
Some(_) => { Some(_) => {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
None => { None => {
Err(Error::EndOfStream) Err(Error::EndOfStreamError)
} }
} }
} }
@@ -370,9 +350,7 @@ mod deserializer {
de::Deserialize::deserialize(self.de) de::Deserialize::deserialize(self.de)
} }
fn visit_tuple<V>(&mut self, fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
_len: usize,
mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
visitor.visit_seq(self) visitor.visit_seq(self)
@@ -404,7 +382,7 @@ mod deserializer {
if self.state == 2 { if self.state == 2 {
Ok(()) Ok(())
} else { } else {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
@@ -432,7 +410,7 @@ fn bench_decoder_dog(b: &mut Bencher) {
#[bench] #[bench]
fn bench_decoder_frog(b: &mut Bencher) { fn bench_decoder_frog(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let animal = Animal::Frog("Henry".to_owned(), 349); let animal = Animal::Frog("Henry".to_string(), 349);
let mut d = decoder::AnimalDecoder::new(animal.clone()); let mut d = decoder::AnimalDecoder::new(animal.clone());
let value: Animal = Decodable::decode(&mut d).unwrap(); let value: Animal = Decodable::decode(&mut d).unwrap();
@@ -456,7 +434,7 @@ fn bench_deserializer_dog(b: &mut Bencher) {
#[bench] #[bench]
fn bench_deserializer_frog(b: &mut Bencher) { fn bench_deserializer_frog(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let animal = Animal::Frog("Henry".to_owned(), 349); let animal = Animal::Frog("Henry".to_string(), 349);
let mut d = deserializer::AnimalDeserializer::new(animal.clone()); let mut d = deserializer::AnimalDeserializer::new(animal.clone());
let value: Animal = Deserialize::deserialize(&mut d).unwrap(); let value: Animal = Deserialize::deserialize(&mut d).unwrap();
File diff suppressed because it is too large Load Diff
+74 -90
View File
@@ -1,6 +1,4 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::fmt;
use std::error;
use std::collections::HashMap; use std::collections::HashMap;
use test::Bencher; use test::Bencher;
@@ -14,37 +12,22 @@ use serde::de::{Deserializer, Deserialize};
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub enum Error { pub enum Error {
EndOfStream, EndOfStream,
Syntax, SyntaxError,
MissingField, MissingField,
} }
impl serde::de::Error for Error { impl serde::de::Error for Error {
fn custom<T: Into<String>>(_: T) -> Error { Error::Syntax } fn syntax_error() -> Error { Error::SyntaxError }
fn end_of_stream() -> Error { Error::EndOfStream } fn end_of_stream_error() -> Error { Error::EndOfStream }
fn unknown_field(_: &str) -> Error { Error::Syntax } fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn missing_field(_: &'static str) -> Error { fn missing_field_error(_: &'static str) -> Error {
Error::MissingField Error::MissingField
} }
} }
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(format!("{:?}", self).as_ref())
}
}
impl error::Error for Error {
fn description(&self) -> &str {
"Serde Deserialization Error"
}
fn cause(&self) -> Option<&error::Error> {
None
}
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
mod decoder { mod decoder {
@@ -53,10 +36,11 @@ mod decoder {
use rustc_serialize; use rustc_serialize;
use super::Error; use super::Error;
use self::Value::{StringValue, IsizeValue};
enum Value { enum Value {
String(String), StringValue(String),
Isize(isize), IsizeValue(isize),
} }
pub struct IsizeDecoder { pub struct IsizeDecoder {
@@ -80,37 +64,37 @@ mod decoder {
type Error = Error; type Error = Error;
fn error(&mut self, _msg: &str) -> Error { fn error(&mut self, _msg: &str) -> Error {
Error::Syntax Error::SyntaxError
} }
// Primitive types: // Primitive types:
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::Syntax) } fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::Syntax) } fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::SyntaxError) }
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::Syntax) } fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::Syntax) } fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::Syntax) } fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::Syntax) } fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
#[inline] #[inline]
fn read_isize(&mut self) -> Result<isize, Error> { fn read_isize(&mut self) -> Result<isize, Error> {
match self.stack.pop() { match self.stack.pop() {
Some(Value::Isize(x)) => Ok(x), Some(IsizeValue(x)) => Ok(x),
Some(_) => Err(Error::Syntax), Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStream), None => Err(Error::EndOfStream),
} }
} }
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::Syntax) } fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::Syntax) } fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::Syntax) } fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::Syntax) } fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::Syntax) } fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::Syntax) } fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::Syntax) } fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
fn read_char(&mut self) -> Result<char, Error> { Err(Error::Syntax) } fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
#[inline] #[inline]
fn read_str(&mut self) -> Result<String, Error> { fn read_str(&mut self) -> Result<String, Error> {
match self.stack.pop() { match self.stack.pop() {
Some(Value::String(x)) => Ok(x), Some(StringValue(x)) => Ok(x),
Some(_) => Err(Error::Syntax), Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStream), None => Err(Error::EndOfStream),
} }
} }
@@ -119,86 +103,86 @@ mod decoder {
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
// Specialized types: // Specialized types:
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder, bool) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder, bool) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_seq<T, F>(&mut self, _f: F) -> Result<T, Error> where fn read_seq<T, F>(&mut self, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_seq_elt<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where fn read_seq_elt<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut IsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
#[inline] #[inline]
@@ -214,12 +198,12 @@ mod decoder {
{ {
match self.iter.next() { match self.iter.next() {
Some((key, value)) => { Some((key, value)) => {
self.stack.push(Value::Isize(value)); self.stack.push(IsizeValue(value));
self.stack.push(Value::String(key)); self.stack.push(StringValue(key));
f(self) f(self)
} }
None => { None => {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
} }
@@ -246,8 +230,8 @@ mod deserializer {
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
enum State { enum State {
StartState, StartState,
Key(String), KeyState(String),
Value(isize), ValueState(isize),
} }
pub struct IsizeDeserializer { pub struct IsizeDeserializer {
@@ -268,17 +252,17 @@ mod deserializer {
impl de::Deserializer for IsizeDeserializer { impl de::Deserializer for IsizeDeserializer {
type Error = Error; type Error = Error;
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error> fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.stack.pop() { match self.stack.pop() {
Some(State::StartState) => { Some(State::StartState) => {
visitor.visit_map(self) visitor.visit_map(self)
} }
Some(State::Key(key)) => { Some(State::KeyState(key)) => {
visitor.visit_string(key) visitor.visit_string(key)
} }
Some(State::Value(value)) => { Some(State::ValueState(value)) => {
visitor.visit_isize(value) visitor.visit_isize(value)
} }
None => { None => {
@@ -296,8 +280,8 @@ mod deserializer {
{ {
match self.iter.next() { match self.iter.next() {
Some((key, value)) => { Some((key, value)) => {
self.stack.push(State::Value(value)); self.stack.push(State::ValueState(value));
self.stack.push(State::Key(key)); self.stack.push(State::KeyState(key));
Ok(Some(try!(de::Deserialize::deserialize(self)))) Ok(Some(try!(de::Deserialize::deserialize(self))))
} }
None => { None => {
@@ -314,7 +298,7 @@ mod deserializer {
fn end(&mut self) -> Result<(), Error> { fn end(&mut self) -> Result<(), Error> {
match self.iter.next() { match self.iter.next() {
Some(_) => Err(Error::Syntax), Some(_) => Err(Error::SyntaxError),
None => Ok(()), None => Ok(()),
} }
} }
@@ -331,14 +315,14 @@ mod deserializer {
#[inline] #[inline]
fn next(&mut self) -> Option<Result<de::Token, Error>> { fn next(&mut self) -> Option<Result<de::Token, Error>> {
match self.stack.pop() { match self.stack.pop() {
Some(State::StartState) => { Some(StartState) => {
self.stack.push(KeyOrEndState); self.stack.push(KeyOrEndState);
Some(Ok(de::Token::MapStart(self.len))) Some(Ok(de::Token::MapStart(self.len)))
} }
Some(State::KeyOrEndState) => { Some(KeyOrEndState) => {
match self.iter.next() { match self.iter.next() {
Some((key, value)) => { Some((key, value)) => {
self.stack.push(Value(value)); self.stack.push(ValueState(value));
Some(Ok(de::Token::String(key))) Some(Ok(de::Token::String(key)))
} }
None => { None => {
@@ -347,7 +331,7 @@ mod deserializer {
} }
} }
} }
Some(State::Value(x)) => { Some(ValueState(x)) => {
self.stack.push(KeyOrEndState); self.stack.push(KeyOrEndState);
Some(Ok(de::Token::Isize(x))) Some(Ok(de::Token::Isize(x)))
} }
@@ -363,30 +347,30 @@ mod deserializer {
impl de::Deserializer<Error> for IsizeDeserializer { impl de::Deserializer<Error> for IsizeDeserializer {
#[inline] #[inline]
fn end_of_stream(&mut self) -> Error { fn end_of_stream_error(&mut self) -> Error {
EndOfStream EndOfStream
} }
#[inline] #[inline]
fn syntax(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error { fn syntax_error(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error {
Syntax SyntaxError
} }
#[inline] #[inline]
fn unexpected_name(&mut self, _token: de::Token) -> Error { fn unexpected_name_error(&mut self, _token: de::Token) -> Error {
Syntax SyntaxError
} }
#[inline] #[inline]
fn conversion_error(&mut self, _token: de::Token) -> Error { fn conversion_error(&mut self, _token: de::Token) -> Error {
Syntax SyntaxError
} }
#[inline] #[inline]
fn missing_field< fn missing_field<
T: de::Deserialize<IsizeDeserializer, Error> T: de::Deserialize<IsizeDeserializer, Error>
>(&mut self, _field: &'static str) -> Result<T, Error> { >(&mut self, _field: &'static str) -> Result<T, Error> {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
*/ */
@@ -415,7 +399,7 @@ fn bench_decoder_000(b: &mut Bencher) {
fn bench_decoder_003(b: &mut Bencher) { fn bench_decoder_003(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new(); let mut m: HashMap<String, isize> = HashMap::new();
for i in 0 .. 3 { for i in (0 .. 3) {
m.insert(i.to_string(), i); m.insert(i.to_string(), i);
} }
run_decoder(decoder::IsizeDecoder::new(m.clone()), m) run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
@@ -426,21 +410,21 @@ fn bench_decoder_003(b: &mut Bencher) {
fn bench_decoder_100(b: &mut Bencher) { fn bench_decoder_100(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new(); let mut m: HashMap<String, isize> = HashMap::new();
for i in 0 .. 100 { for i in (0 .. 100) {
m.insert(i.to_string(), i); m.insert(i.to_string(), i);
} }
run_decoder(decoder::IsizeDecoder::new(m.clone()), m) run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
}) })
} }
fn run_deserializer<D, T>(mut d: D, value: T) fn run_deserializer<
where D: Deserializer, D: Deserializer<Error=E>,
D::Error: Debug + PartialEq, E: Debug,
T: Clone + PartialEq + Debug + Deserialize T: Clone + PartialEq + Debug + Deserialize
{ >(mut d: D, value: T) {
let v = T::deserialize(&mut d); let v: T = Deserialize::deserialize(&mut d).unwrap();
assert_eq!(Ok(value), v); assert_eq!(value, v);
} }
#[bench] #[bench]
@@ -455,7 +439,7 @@ fn bench_deserializer_000(b: &mut Bencher) {
fn bench_deserializer_003(b: &mut Bencher) { fn bench_deserializer_003(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new(); let mut m: HashMap<String, isize> = HashMap::new();
for i in 0 .. 3 { for i in (0 .. 3) {
m.insert(i.to_string(), i); m.insert(i.to_string(), i);
} }
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m) run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
@@ -466,7 +450,7 @@ fn bench_deserializer_003(b: &mut Bencher) {
fn bench_deserializer_100(b: &mut Bencher) { fn bench_deserializer_100(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new(); let mut m: HashMap<String, isize> = HashMap::new();
for i in 0 .. 100 { for i in (0 .. 100) {
m.insert(i.to_string(), i); m.insert(i.to_string(), i);
} }
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m) run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
+142 -150
View File
@@ -1,7 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use test::Bencher; use test::Bencher;
use std::fmt;
use std::error;
use rustc_serialize::{Decoder, Decodable}; use rustc_serialize::{Decoder, Decodable};
@@ -29,57 +27,54 @@ pub struct Outer {
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Error { pub enum Error {
EndOfStream, EndOfStream,
Syntax, SyntaxError,
MissingField, MissingField,
OtherError, OtherError,
} }
impl serde::de::Error for Error { impl serde::de::Error for Error {
fn custom<T: Into<String>>(_: T) -> Error { Error::Syntax } fn syntax_error() -> Error { Error::SyntaxError }
fn end_of_stream() -> Error { Error::EndOfStream } fn end_of_stream_error() -> Error { Error::EndOfStream }
fn unknown_field(_: &str) -> Error { Error::Syntax } fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn missing_field(_: &'static str) -> Error { fn missing_field_error(_: &'static str) -> Error {
Error::MissingField Error::MissingField
} }
} }
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(format!("{:?}", self).as_ref())
}
}
impl error::Error for Error {
fn description(&self) -> &str {
"Serde Deserialization Error"
}
fn cause(&self) -> Option<&error::Error> {
None
}
}
mod decoder { mod decoder {
use std::collections::HashMap; use std::collections::HashMap;
use rustc_serialize::Decoder; use rustc_serialize::Decoder;
use super::{Outer, Inner, Error}; use super::{Outer, Inner, Error};
use self::State::{
OuterState,
InnerState,
NullState,
UsizeState,
CharState,
StringState,
FieldState,
VecState,
MapState,
OptionState,
};
#[derive(Debug)] #[derive(Debug)]
enum State { enum State {
Outer(Outer), OuterState(Outer),
Inner(Inner), InnerState(Inner),
Null, NullState,
Usize(usize), UsizeState(usize),
Char(char), CharState(char),
String(String), StringState(String),
Field(&'static str), FieldState(&'static str),
Vec(Vec<Inner>), VecState(Vec<Inner>),
Map(HashMap<String, Option<char>>), MapState(HashMap<String, Option<char>>),
Option(bool), OptionState(bool),
} }
pub struct OuterDecoder { pub struct OuterDecoder {
@@ -91,7 +86,7 @@ mod decoder {
#[inline] #[inline]
pub fn new(animal: Outer) -> OuterDecoder { pub fn new(animal: Outer) -> OuterDecoder {
OuterDecoder { OuterDecoder {
stack: vec!(State::Outer(animal)), stack: vec!(OuterState(animal)),
} }
} }
} }
@@ -107,41 +102,41 @@ mod decoder {
#[inline] #[inline]
fn read_nil(&mut self) -> Result<(), Error> { fn read_nil(&mut self) -> Result<(), Error> {
match self.stack.pop() { match self.stack.pop() {
Some(State::Null) => Ok(()), Some(NullState) => Ok(()),
_ => Err(Error::Syntax), _ => Err(Error::SyntaxError),
} }
} }
#[inline] #[inline]
fn read_usize(&mut self) -> Result<usize, Error> { fn read_usize(&mut self) -> Result<usize, Error> {
match self.stack.pop() { match self.stack.pop() {
Some(State::Usize(value)) => Ok(value), Some(UsizeState(value)) => Ok(value),
_ => Err(Error::Syntax), _ => Err(Error::SyntaxError),
} }
} }
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::Syntax) } fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::Syntax) } fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::Syntax) } fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::Syntax) } fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::Syntax) } fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::SyntaxError) }
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::Syntax) } fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::Syntax) } fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::Syntax) } fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::Syntax) } fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::Syntax) } fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::Syntax) } fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::Syntax) } fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
#[inline] #[inline]
fn read_char(&mut self) -> Result<char, Error> { fn read_char(&mut self) -> Result<char, Error> {
match self.stack.pop() { match self.stack.pop() {
Some(State::Char(c)) => Ok(c), Some(CharState(c)) => Ok(c),
_ => Err(Error::Syntax), _ => Err(Error::SyntaxError),
} }
} }
#[inline] #[inline]
fn read_str(&mut self) -> Result<String, Error> { fn read_str(&mut self) -> Result<String, Error> {
match self.stack.pop() { match self.stack.pop() {
Some(State::String(value)) => Ok(value), Some(StringState(value)) => Ok(value),
_ => Err(Error::Syntax), _ => Err(Error::SyntaxError),
} }
} }
@@ -149,31 +144,31 @@ mod decoder {
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
#[inline] #[inline]
@@ -181,31 +176,31 @@ mod decoder {
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
{ {
match self.stack.pop() { match self.stack.pop() {
Some(State::Outer(Outer { inner })) => { Some(OuterState(Outer { inner })) => {
if s_name == "Outer" { if s_name == "Outer" {
self.stack.push(State::Vec(inner)); self.stack.push(VecState(inner));
self.stack.push(State::Field("inner")); self.stack.push(FieldState("inner"));
f(self) f(self)
} else { } else {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
Some(State::Inner(Inner { a: (), b, c })) => { Some(InnerState(Inner { a: (), b, c })) => {
if s_name == "Inner" { if s_name == "Inner" {
self.stack.push(State::Map(c)); self.stack.push(MapState(c));
self.stack.push(State::Field("c")); self.stack.push(FieldState("c"));
self.stack.push(State::Usize(b)); self.stack.push(UsizeState(b));
self.stack.push(State::Field("b")); self.stack.push(FieldState("b"));
self.stack.push(State::Null); self.stack.push(NullState);
self.stack.push(State::Field("a")); self.stack.push(FieldState("a"));
f(self) f(self)
} else { } else {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
_ => Err(Error::Syntax), _ => Err(Error::SyntaxError),
} }
} }
#[inline] #[inline]
@@ -213,39 +208,39 @@ mod decoder {
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
{ {
match self.stack.pop() { match self.stack.pop() {
Some(State::Field(name)) => { Some(FieldState(name)) => {
if f_name == name { if f_name == name {
f(self) f(self)
} else { } else {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
_ => Err(Error::Syntax) _ => Err(Error::SyntaxError)
} }
} }
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut OuterDecoder) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
// Specialized types: // Specialized types:
@@ -254,8 +249,8 @@ mod decoder {
F: FnOnce(&mut OuterDecoder, bool) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder, bool) -> Result<T, Error>,
{ {
match self.stack.pop() { match self.stack.pop() {
Some(State::Option(b)) => f(self, b), Some(OptionState(b)) => f(self, b),
_ => Err(Error::Syntax), _ => Err(Error::SyntaxError),
} }
} }
@@ -264,14 +259,14 @@ mod decoder {
F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>,
{ {
match self.stack.pop() { match self.stack.pop() {
Some(State::Vec(value)) => { Some(VecState(value)) => {
let len = value.len(); let len = value.len();
for inner in value.into_iter().rev() { for inner in value.into_iter().rev() {
self.stack.push(State::Inner(inner)); self.stack.push(InnerState(inner));
} }
f(self, len) f(self, len)
} }
_ => Err(Error::Syntax) _ => Err(Error::SyntaxError)
} }
} }
#[inline] #[inline]
@@ -286,23 +281,23 @@ mod decoder {
F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut OuterDecoder, usize) -> Result<T, Error>,
{ {
match self.stack.pop() { match self.stack.pop() {
Some(State::Map(map)) => { Some(MapState(map)) => {
let len = map.len(); let len = map.len();
for (key, value) in map { for (key, value) in map {
match value { match value {
Some(c) => { Some(c) => {
self.stack.push(State::Char(c)); self.stack.push(CharState(c));
self.stack.push(State::Option(true)); self.stack.push(OptionState(true));
} }
None => { None => {
self.stack.push(State::Option(false)); self.stack.push(OptionState(false));
} }
} }
self.stack.push(State::String(key)); self.stack.push(StringState(key));
} }
f(self, len) f(self, len)
} }
_ => Err(Error::Syntax), _ => Err(Error::SyntaxError),
} }
} }
#[inline] #[inline]
@@ -333,16 +328,16 @@ mod deserializer {
#[derive(Debug)] #[derive(Debug)]
enum State { enum State {
Outer(Outer), OuterState(Outer),
Inner(Inner), InnerState(Inner),
Str(&'static str), StrState(&'static str),
Null, NullState,
Usize(usize), UsizeState(usize),
Char(char), CharState(char),
String(String), StringState(String),
Option(bool), OptionState(bool),
Vec(Vec<Inner>), VecState(Vec<Inner>),
Map(HashMap<String, Option<char>>), MapState(HashMap<String, Option<char>>),
} }
pub struct OuterDeserializer { pub struct OuterDeserializer {
@@ -353,7 +348,7 @@ mod deserializer {
#[inline] #[inline]
pub fn new(outer: Outer) -> OuterDeserializer { pub fn new(outer: Outer) -> OuterDeserializer {
OuterDeserializer { OuterDeserializer {
stack: vec!(State::Outer(outer)), stack: vec!(State::OuterState(outer)),
} }
} }
} }
@@ -361,81 +356,78 @@ mod deserializer {
impl de::Deserializer for OuterDeserializer { impl de::Deserializer for OuterDeserializer {
type Error = Error; type Error = Error;
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error> fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.stack.pop() { match self.stack.pop() {
Some(State::Vec(value)) => { Some(State::VecState(value)) => {
visitor.visit_seq(OuterSeqVisitor { visitor.visit_seq(OuterSeqVisitor {
de: self, de: self,
iter: value.into_iter(), iter: value.into_iter(),
}) })
} }
Some(State::Map(value)) => { Some(State::MapState(value)) => {
visitor.visit_map(MapVisitor { visitor.visit_map(MapVisitor {
de: self, de: self,
iter: value.into_iter(), iter: value.into_iter(),
}) })
} }
Some(State::Null) => { Some(State::NullState) => {
visitor.visit_unit() visitor.visit_unit()
} }
Some(State::Usize(x)) => { Some(State::UsizeState(x)) => {
visitor.visit_usize(x) visitor.visit_usize(x)
} }
Some(State::Char(x)) => { Some(State::CharState(x)) => {
visitor.visit_char(x) visitor.visit_char(x)
} }
Some(State::Str(x)) => { Some(State::StrState(x)) => {
visitor.visit_str(x) visitor.visit_str(x)
} }
Some(State::String(x)) => { Some(State::StringState(x)) => {
visitor.visit_string(x) visitor.visit_string(x)
} }
Some(State::Option(false)) => { Some(State::OptionState(false)) => {
visitor.visit_none() visitor.visit_none()
} }
Some(State::Option(true)) => { Some(State::OptionState(true)) => {
visitor.visit_some(self) visitor.visit_some(self)
} }
Some(_) => Err(Error::Syntax), Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStream), None => Err(Error::EndOfStream),
} }
} }
fn deserialize_struct<V>(&mut self, fn visit_named_map<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value, Error>
name: &str,
_fields: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.stack.pop() { match self.stack.pop() {
Some(State::Outer(Outer { inner })) => { Some(State::OuterState(Outer { inner })) => {
if name != "Outer" { if name != "Outer" {
return Err(Error::Syntax); return Err(Error::SyntaxError);
} }
self.stack.push(State::Vec(inner)); self.stack.push(State::VecState(inner));
self.stack.push(State::Str("inner")); self.stack.push(State::StrState("inner"));
visitor.visit_map(OuterMapVisitor { visitor.visit_map(OuterMapVisitor {
de: self, de: self,
state: 0, state: 0,
}) })
} }
Some(State::Inner(Inner { a: (), b, c })) => { Some(State::InnerState(Inner { a: (), b, c })) => {
if name != "Inner" { if name != "Inner" {
return Err(Error::Syntax); return Err(Error::SyntaxError);
} }
self.stack.push(State::Map(c)); self.stack.push(State::MapState(c));
self.stack.push(State::Str("c")); self.stack.push(State::StrState("c"));
self.stack.push(State::Usize(b)); self.stack.push(State::UsizeState(b));
self.stack.push(State::Str("b")); self.stack.push(State::StrState("b"));
self.stack.push(State::Null); self.stack.push(State::NullState);
self.stack.push(State::Str("a")); self.stack.push(State::StrState("a"));
visitor.visit_map(InnerMapVisitor { visitor.visit_map(InnerMapVisitor {
de: self, de: self,
@@ -443,7 +435,7 @@ mod deserializer {
}) })
} }
_ => { _ => {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
} }
@@ -481,7 +473,7 @@ mod deserializer {
if self.state == 1 { if self.state == 1 {
Ok(()) Ok(())
} else { } else {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
@@ -504,7 +496,7 @@ mod deserializer {
{ {
match self.iter.next() { match self.iter.next() {
Some(value) => { Some(value) => {
self.de.stack.push(State::Inner(value)); self.de.stack.push(State::InnerState(value));
Ok(Some(try!(de::Deserialize::deserialize(self.de)))) Ok(Some(try!(de::Deserialize::deserialize(self.de))))
} }
None => { None => {
@@ -515,7 +507,7 @@ mod deserializer {
fn end(&mut self) -> Result<(), Error> { fn end(&mut self) -> Result<(), Error> {
match self.iter.next() { match self.iter.next() {
Some(_) => Err(Error::Syntax), Some(_) => Err(Error::SyntaxError),
None => Ok(()), None => Ok(()),
} }
} }
@@ -557,7 +549,7 @@ mod deserializer {
if self.state == 3 { if self.state == 3 {
Ok(()) Ok(())
} else { } else {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
@@ -580,14 +572,14 @@ mod deserializer {
{ {
match self.iter.next() { match self.iter.next() {
Some((key, Some(value))) => { Some((key, Some(value))) => {
self.de.stack.push(State::Char(value)); self.de.stack.push(State::CharState(value));
self.de.stack.push(State::Option(true)); self.de.stack.push(State::OptionState(true));
self.de.stack.push(State::String(key)); self.de.stack.push(State::StringState(key));
Ok(Some(try!(de::Deserialize::deserialize(self.de)))) Ok(Some(try!(de::Deserialize::deserialize(self.de))))
} }
Some((key, None)) => { Some((key, None)) => {
self.de.stack.push(State::Option(false)); self.de.stack.push(State::OptionState(false));
self.de.stack.push(State::String(key)); self.de.stack.push(State::StringState(key));
Ok(Some(try!(de::Deserialize::deserialize(self.de)))) Ok(Some(try!(de::Deserialize::deserialize(self.de))))
} }
None => { None => {
@@ -604,7 +596,7 @@ mod deserializer {
fn end(&mut self) -> Result<(), Error> { fn end(&mut self) -> Result<(), Error> {
match self.iter.next() { match self.iter.next() {
Some(_) => Err(Error::Syntax), Some(_) => Err(Error::SyntaxError),
None => Ok(()), None => Ok(()),
} }
} }
@@ -619,7 +611,7 @@ mod deserializer {
fn bench_decoder_0_0(b: &mut Bencher) { fn bench_decoder_0_0(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert("abc".to_owned(), Some('c')); map.insert("abc".to_string(), Some('c'));
let outer = Outer { let outer = Outer {
inner: vec!(), inner: vec!(),
@@ -658,11 +650,11 @@ fn bench_decoder_1_0(b: &mut Bencher) {
fn bench_decoder_1_5(b: &mut Bencher) { fn bench_decoder_1_5(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert("1".to_owned(), Some('a')); map.insert("1".to_string(), Some('a'));
map.insert("2".to_owned(), None); map.insert("2".to_string(), None);
map.insert("3".to_owned(), Some('b')); map.insert("3".to_string(), Some('b'));
map.insert("4".to_owned(), None); map.insert("4".to_string(), None);
map.insert("5".to_owned(), Some('c')); map.insert("5".to_string(), Some('c'));
let outer = Outer { let outer = Outer {
inner: vec!( inner: vec!(
@@ -721,11 +713,11 @@ fn bench_deserializer_1_0(b: &mut Bencher) {
fn bench_deserializer_1_5(b: &mut Bencher) { fn bench_deserializer_1_5(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert("1".to_owned(), Some('a')); map.insert("1".to_string(), Some('a'));
map.insert("2".to_owned(), None); map.insert("2".to_string(), None);
map.insert("3".to_owned(), Some('b')); map.insert("3".to_string(), Some('b'));
map.insert("4".to_owned(), None); map.insert("4".to_string(), None);
map.insert("5".to_owned(), Some('c')); map.insert("5".to_string(), Some('c'));
let outer = Outer { let outer = Outer {
inner: vec!( inner: vec!(
+99 -116
View File
@@ -1,6 +1,4 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::fmt;
use std::error;
use test::Bencher; use test::Bencher;
use rustc_serialize::{Decoder, Decodable}; use rustc_serialize::{Decoder, Decodable};
@@ -12,35 +10,20 @@ use serde::de::{Deserializer, Deserialize};
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
pub enum Error { pub enum Error {
EndOfStream, EndOfStreamError,
Syntax, SyntaxError,
} }
impl serde::de::Error for Error { impl serde::de::Error for Error {
fn custom<T: Into<String>>(_: T) -> Error { Error::Syntax } fn syntax_error() -> Error { Error::SyntaxError }
fn end_of_stream() -> Error { Error::EndOfStream } fn end_of_stream_error() -> Error { Error::EndOfStreamError }
fn unknown_field(_: &str) -> Error { Error::Syntax } fn unknown_field_error(_: &str) -> Error { Error::SyntaxError }
fn missing_field(_: &'static str) -> Error { Error::Syntax } fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError }
} }
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(format!("{:?}", self).as_ref())
}
}
impl error::Error for Error {
fn description(&self) -> &str {
"Serde Deserialization Error"
}
fn cause(&self) -> Option<&error::Error> {
None
}
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
mod decoder { mod decoder {
@@ -67,104 +50,104 @@ mod decoder {
impl rustc_serialize::Decoder for UsizeDecoder { impl rustc_serialize::Decoder for UsizeDecoder {
type Error = Error; type Error = Error;
fn error(&mut self, _: &str) -> Error { Error::Syntax } fn error(&mut self, _: &str) -> Error { Error::SyntaxError }
// Primitive types: // Primitive types:
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::Syntax) } fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
#[inline] #[inline]
fn read_usize(&mut self) -> Result<usize, Error> { fn read_usize(&mut self) -> Result<usize, Error> {
match self.iter.next() { match self.iter.next() {
Some(value) => Ok(value), Some(value) => Ok(value),
None => Err(Error::EndOfStream), None => Err(Error::EndOfStreamError),
} }
} }
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::Syntax) } fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::Syntax) } fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::Syntax) } fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::Syntax) } fn read_u8(&mut self) -> Result<u8, Error> { Err(Error::SyntaxError) }
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::Syntax) } fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::SyntaxError) }
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::Syntax) } fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::Syntax) } fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::Syntax) } fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::Syntax) } fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::Syntax) } fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::Syntax) } fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::Syntax) } fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
fn read_char(&mut self) -> Result<char, Error> { Err(Error::Syntax) } fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
fn read_str(&mut self) -> Result<String, Error> { Err(Error::Syntax) } fn read_str(&mut self) -> Result<String, Error> { Err(Error::SyntaxError) }
// Compound types: // Compound types:
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
// Specialized types: // Specialized types:
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder, bool) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder, bool) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
#[inline] #[inline]
@@ -184,19 +167,19 @@ mod decoder {
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>, F: FnOnce(&mut UsizeDecoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
@@ -219,105 +202,105 @@ mod decoder {
impl rustc_serialize::Decoder for U8Decoder { impl rustc_serialize::Decoder for U8Decoder {
type Error = Error; type Error = Error;
fn error(&mut self, _: &str) -> Error { Error::Syntax } fn error(&mut self, _: &str) -> Error { Error::SyntaxError }
// Primitive types: // Primitive types:
fn read_nil(&mut self) -> Result<(), Error> { Err(Error::Syntax) } fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) }
fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::Syntax) } fn read_usize(&mut self) -> Result<usize, Error> { Err(Error::SyntaxError) }
fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::Syntax) } fn read_u64(&mut self) -> Result<u64, Error> { Err(Error::SyntaxError) }
fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::Syntax) } fn read_u32(&mut self) -> Result<u32, Error> { Err(Error::SyntaxError) }
fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::Syntax) } fn read_u16(&mut self) -> Result<u16, Error> { Err(Error::SyntaxError) }
#[inline] #[inline]
fn read_u8(&mut self) -> Result<u8, Error> { fn read_u8(&mut self) -> Result<u8, Error> {
match self.iter.next() { match self.iter.next() {
Some(value) => Ok(value), Some(value) => Ok(value),
None => Err(Error::EndOfStream), None => Err(Error::EndOfStreamError),
} }
} }
#[inline] #[inline]
fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::Syntax) } fn read_isize(&mut self) -> Result<isize, Error> { Err(Error::SyntaxError) }
fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::Syntax) } fn read_i64(&mut self) -> Result<i64, Error> { Err(Error::SyntaxError) }
fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::Syntax) } fn read_i32(&mut self) -> Result<i32, Error> { Err(Error::SyntaxError) }
fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::Syntax) } fn read_i16(&mut self) -> Result<i16, Error> { Err(Error::SyntaxError) }
fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::Syntax) } fn read_i8(&mut self) -> Result<i8, Error> { Err(Error::SyntaxError) }
fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::Syntax) } fn read_bool(&mut self) -> Result<bool, Error> { Err(Error::SyntaxError) }
fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::Syntax) } fn read_f64(&mut self) -> Result<f64, Error> { Err(Error::SyntaxError) }
fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::Syntax) } fn read_f32(&mut self) -> Result<f32, Error> { Err(Error::SyntaxError) }
fn read_char(&mut self) -> Result<char, Error> { Err(Error::Syntax) } fn read_char(&mut self) -> Result<char, Error> { Err(Error::SyntaxError) }
fn read_str(&mut self) -> Result<String, Error> { Err(Error::Syntax) } fn read_str(&mut self) -> Result<String, Error> { Err(Error::SyntaxError) }
// Compound types: // Compound types:
fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where fn read_enum<T, F>(&mut self, _name: &str, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder) -> Result<T, Error>, F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where fn read_enum_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>, F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder) -> Result<T, Error>, F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>, F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where fn read_enum_struct_variant_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder) -> Result<T, Error>, F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder) -> Result<T, Error>, F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where fn read_struct_field<T, F>(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder) -> Result<T, Error>, F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where fn read_tuple<T, F>(&mut self, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder) -> Result<T, Error>, F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_tuple_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder) -> Result<T, Error>, F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder) -> Result<T, Error>, F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder) -> Result<T, Error>, F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
// Specialized types: // Specialized types:
fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where fn read_option<T, F>(&mut self, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder, bool) -> Result<T, Error>, F: FnOnce(&mut U8Decoder, bool) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
#[inline] #[inline]
@@ -337,19 +320,19 @@ mod decoder {
fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where fn read_map<T, F>(&mut self, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>, F: FnOnce(&mut U8Decoder, usize) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where fn read_map_elt_key<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder) -> Result<T, Error>, F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where fn read_map_elt_val<T, F>(&mut self, _idx: usize, _f: F) -> Result<T, Error> where
F: FnOnce(&mut U8Decoder) -> Result<T, Error>, F: FnOnce(&mut U8Decoder) -> Result<T, Error>,
{ {
Err(Error::Syntax) Err(Error::SyntaxError)
} }
} }
} }
@@ -366,9 +349,9 @@ mod deserializer {
#[derive(PartialEq, Debug)] #[derive(PartialEq, Debug)]
enum State { enum State {
Start, StartState,
SepOrEnd, SepOrEndState,
End, EndState,
} }
pub struct Deserializer<A> { pub struct Deserializer<A> {
@@ -383,7 +366,7 @@ mod deserializer {
pub fn new(values: Vec<A>) -> Deserializer<A> { pub fn new(values: Vec<A>) -> Deserializer<A> {
let len = values.len(); let len = values.len();
Deserializer { Deserializer {
state: State::Start, state: State::StartState,
iter: values.into_iter(), iter: values.into_iter(),
len: len, len: len,
value: None, value: None,
@@ -395,19 +378,19 @@ mod deserializer {
type Error = Error; type Error = Error;
#[inline] #[inline]
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error> fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.state { match self.state {
State::Start => { State::StartState => {
self.state = State::SepOrEnd; self.state = State::SepOrEndState;
visitor.visit_seq(self) visitor.visit_seq(self)
} }
State::SepOrEnd => { State::SepOrEndState => {
visitor.visit_usize(self.value.take().unwrap()) visitor.visit_usize(self.value.take().unwrap())
} }
State::End => { State::EndState => {
Err(Error::EndOfStream) Err(Error::EndOfStreamError)
} }
} }
} }
@@ -427,7 +410,7 @@ mod deserializer {
Ok(Some(try!(de::Deserialize::deserialize(self)))) Ok(Some(try!(de::Deserialize::deserialize(self))))
} }
None => { None => {
self.state = State::End; self.state = State::EndState;
Ok(None) Ok(None)
} }
} }
@@ -436,9 +419,9 @@ mod deserializer {
#[inline] #[inline]
fn end(&mut self) -> Result<(), Error> { fn end(&mut self) -> Result<(), Error> {
match self.iter.next() { match self.iter.next() {
Some(_) => Err(Error::Syntax), Some(_) => Err(Error::SyntaxError),
None => { None => {
self.state = State::End; self.state = State::EndState;
Ok(()) Ok(())
} }
} }
@@ -454,19 +437,19 @@ mod deserializer {
type Error = Error; type Error = Error;
#[inline] #[inline]
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error> fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
match self.state { match self.state {
State::Start => { State::StartState => {
self.state = State::SepOrEnd; self.state = State::SepOrEndState;
visitor.visit_seq(self) visitor.visit_seq(self)
} }
State::SepOrEnd => { State::SepOrEndState => {
visitor.visit_u8(self.value.take().unwrap()) visitor.visit_u8(self.value.take().unwrap())
} }
State::End => { State::EndState => {
Err(Error::EndOfStream) Err(Error::EndOfStreamError)
} }
} }
} }
@@ -486,7 +469,7 @@ mod deserializer {
Ok(Some(try!(de::Deserialize::deserialize(self)))) Ok(Some(try!(de::Deserialize::deserialize(self))))
} }
None => { None => {
self.state = State::End; self.state = State::EndState;
Ok(None) Ok(None)
} }
} }
@@ -495,9 +478,9 @@ mod deserializer {
#[inline] #[inline]
fn end(&mut self) -> Result<(), Error> { fn end(&mut self) -> Result<(), Error> {
match self.iter.next() { match self.iter.next() {
Some(_) => Err(Error::Syntax), Some(_) => Err(Error::SyntaxError),
None => { None => {
self.state = State::End; self.state = State::EndState;
Ok(()) Ok(())
} }
} }
@@ -521,14 +504,14 @@ fn run_decoder<
assert_eq!(Ok(value), v); assert_eq!(Ok(value), v);
} }
fn run_deserializer<D, T>(mut d: D, value: T) fn run_deserializer<
where D: Deserializer, D: Deserializer<Error=E>,
D::Error: Debug + PartialEq, E: Debug,
T: Clone + PartialEq + Debug + Deserialize T: Clone + PartialEq + Debug + Deserialize
{ >(mut d: D, value: T) {
let v = T::deserialize(&mut d); let v: T = Deserialize::deserialize(&mut d).unwrap();
assert_eq!(Ok(value), v); assert_eq!(value, v);
} }
#[bench] #[bench]
-79
View File
@@ -1,79 +0,0 @@
#[macro_export]
macro_rules! declare_ser_tests {
($($name:ident { $($value:expr => $tokens:expr,)+ })+) => {
$(
#[test]
fn $name() {
$(
::token::assert_ser_tokens(&$value, $tokens);
)+
}
)+
}
}
#[macro_export]
macro_rules! btreemap {
() => {
BTreeMap::new()
};
($($key:expr => $value:expr),+) => {
{
let mut map = BTreeMap::new();
$(map.insert($key, $value);)+
map
}
}
}
macro_rules! btreeset {
() => {
BTreeSet::new()
};
($($value:expr),+) => {
{
let mut set = BTreeSet::new();
$(set.insert($value);)+
set
}
}
}
macro_rules! btreemap {
() => {
BTreeMap::new()
};
($($key:expr => $value:expr),+) => {
{
let mut map = BTreeMap::new();
$(map.insert($key, $value);)+
map
}
}
}
macro_rules! hashset {
() => {
HashSet::new()
};
($($value:expr),+) => {
{
let mut set = HashSet::new();
$(set.insert($value);)+
set
}
}
}
macro_rules! hashmap {
() => {
HashMap::new()
};
($($key:expr => $value:expr),+) => {
{
let mut map = HashMap::new();
$(map.insert($key, $value);)+
map
}
}
}
+1 -2
View File
@@ -1,4 +1,3 @@
#![cfg_attr(feature = "nightly", feature(plugin))] extern crate serde;
#![cfg_attr(feature = "nightly", plugin(clippy))]
include!(concat!(env!("OUT_DIR"), "/test.rs")); include!(concat!(env!("OUT_DIR"), "/test.rs"));
+6 -6
View File
@@ -1,11 +1,11 @@
#[macro_use] /*
mod macros;
mod token;
mod test_annotations; mod test_annotations;
mod test_bytes; mod test_bytes;
mod test_de; mod test_de;
mod test_gen; mod test_json;
mod test_json_builder;
*/
mod test_macros; mod test_macros;
/*
mod test_ser; mod test_ser;
*/
+36 -912
View File
@@ -1,949 +1,73 @@
extern crate serde; use serde::json;
use self::serde::{Serialize, Serializer, Deserialize, Deserializer};
use token::{
Error,
Token,
assert_tokens,
assert_ser_tokens,
assert_de_tokens,
assert_de_tokens_error
};
trait MyDefault: Sized {
fn my_default() -> Self;
}
trait ShouldSkip: Sized {
fn should_skip(&self) -> bool;
}
trait SerializeWith: Sized {
fn serialize_with<S>(&self, ser: &mut S) -> Result<(), S::Error>
where S: Serializer;
}
trait DeserializeWith: Sized {
fn deserialize_with<D>(de: &mut D) -> Result<Self, D::Error>
where D: Deserializer;
}
impl MyDefault for i32 {
fn my_default() -> Self { 123 }
}
impl ShouldSkip for i32 {
fn should_skip(&self) -> bool { *self == 123 }
}
impl SerializeWith for i32 {
fn serialize_with<S>(&self, ser: &mut S) -> Result<(), S::Error>
where S: Serializer
{
if *self == 123 {
true.serialize(ser)
} else {
false.serialize(ser)
}
}
}
impl DeserializeWith for i32 {
fn deserialize_with<D>(de: &mut D) -> Result<Self, D::Error>
where D: Deserializer
{
if try!(Deserialize::deserialize(de)) {
Ok(123)
} else {
Ok(2)
}
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
struct DefaultStruct<A, B, C, D, E> struct Default {
where C: MyDefault,
E: MyDefault,
{
a1: A,
#[serde(default)]
a2: B,
#[serde(default="MyDefault::my_default")]
a3: C,
#[serde(skip_deserializing)]
a4: D,
#[serde(skip_deserializing, default="MyDefault::my_default")]
a5: E,
}
#[test]
fn test_default_struct() {
assert_de_tokens(
&DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
vec![
Token::StructStart("DefaultStruct", Some(3)),
Token::StructSep,
Token::Str("a1"),
Token::I32(1),
Token::StructSep,
Token::Str("a2"),
Token::I32(2),
Token::StructSep,
Token::Str("a3"),
Token::I32(3),
Token::StructSep,
Token::Str("a4"),
Token::I32(4),
Token::StructSep,
Token::Str("a5"),
Token::I32(5),
Token::StructEnd,
]
);
assert_de_tokens(
&DefaultStruct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 },
vec![
Token::StructStart("DefaultStruct", Some(1)),
Token::StructSep,
Token::Str("a1"),
Token::I32(1),
Token::StructEnd,
]
);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
enum DefaultEnum<A, B, C, D, E>
where C: MyDefault,
E: MyDefault
{
Struct {
a1: A,
#[serde(default)]
a2: B,
#[serde(default="MyDefault::my_default")]
a3: C,
#[serde(skip_deserializing)]
a4: D,
#[serde(skip_deserializing, default="MyDefault::my_default")]
a5: E,
}
}
#[test]
fn test_default_enum() {
assert_de_tokens(
&DefaultEnum::Struct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
vec![
Token::EnumMapStart("DefaultEnum", "Struct", Some(5)),
Token::EnumMapSep,
Token::Str("a1"),
Token::I32(1),
Token::EnumMapSep,
Token::Str("a2"),
Token::I32(2),
Token::EnumMapSep,
Token::Str("a3"),
Token::I32(3),
Token::EnumMapSep,
Token::Str("a4"),
Token::I32(4),
Token::EnumMapSep,
Token::Str("a5"),
Token::I32(5),
Token::EnumMapEnd,
]
);
assert_de_tokens(
&DefaultEnum::Struct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 },
vec![
Token::EnumMapStart("DefaultEnum", "Struct", Some(5)),
Token::EnumMapSep,
Token::Str("a1"),
Token::I32(1),
Token::EnumMapEnd,
]
);
}
// Does not implement std::default::Default.
#[derive(Debug, PartialEq, Deserialize)]
struct NoStdDefault(i8);
impl MyDefault for NoStdDefault {
fn my_default() -> Self {
NoStdDefault(123)
}
}
#[derive(Debug, PartialEq, Deserialize)]
struct ContainsNoStdDefault<A: MyDefault> {
#[serde(default="MyDefault::my_default")]
a: A,
}
// Tests that a struct field does not need to implement std::default::Default if
// it is annotated with `default=...`.
#[test]
fn test_no_std_default() {
assert_de_tokens(
&ContainsNoStdDefault { a: NoStdDefault(123) },
vec![
Token::StructStart("ContainsNoStdDefault", Some(1)),
Token::StructEnd,
]
);
assert_de_tokens(
&ContainsNoStdDefault { a: NoStdDefault(8) },
vec![
Token::StructStart("ContainsNoStdDefault", Some(1)),
Token::StructSep,
Token::Str("a"),
Token::StructNewType("NoStdDefault"),
Token::I8(8),
Token::StructEnd,
]
);
}
// Does not implement Deserialize.
#[derive(Debug, PartialEq)]
struct NotDeserializeStruct(i8);
impl Default for NotDeserializeStruct {
fn default() -> Self {
NotDeserializeStruct(123)
}
}
impl DeserializeWith for NotDeserializeStruct {
fn deserialize_with<D>(_: &mut D) -> Result<Self, D::Error>
where D: Deserializer
{
panic!()
}
}
// Does not implement Deserialize.
#[derive(Debug, PartialEq)]
enum NotDeserializeEnum { Trouble }
impl MyDefault for NotDeserializeEnum {
fn my_default() -> Self {
NotDeserializeEnum::Trouble
}
}
#[derive(Debug, PartialEq, Deserialize)]
struct ContainsNotDeserialize<A, B, C: DeserializeWith, E: MyDefault> {
#[serde(skip_deserializing)]
a: A,
#[serde(skip_deserializing, default)]
b: B,
#[serde(deserialize_with="DeserializeWith::deserialize_with", default)]
c: C,
#[serde(skip_deserializing, default="MyDefault::my_default")]
e: E,
}
// Tests that a struct field does not need to implement Deserialize if it is
// annotated with skip_deserializing, whether using the std Default or a
// custom default.
#[test]
fn test_elt_not_deserialize() {
assert_de_tokens(
&ContainsNotDeserialize {
a: NotDeserializeStruct(123),
b: NotDeserializeStruct(123),
c: NotDeserializeStruct(123),
e: NotDeserializeEnum::Trouble,
},
vec![
Token::StructStart("ContainsNotDeserialize", Some(3)),
Token::StructEnd,
]
);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct DenyUnknown {
a1: i32, a1: i32,
} #[serde(default)]
a2: i32,
#[test]
fn test_ignore_unknown() {
// 'Default' allows unknown. Basic smoke test of ignore...
assert_de_tokens(
&DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
vec![
Token::StructStart("DefaultStruct", Some(5)),
Token::StructSep,
Token::Str("whoops1"),
Token::I32(2),
Token::StructSep,
Token::Str("a1"),
Token::I32(1),
Token::StructSep,
Token::Str("whoops2"),
Token::SeqStart(Some(1)),
Token::SeqSep,
Token::I32(2),
Token::SeqEnd,
Token::StructSep,
Token::Str("a2"),
Token::I32(2),
Token::StructSep,
Token::Str("whoops3"),
Token::I32(2),
Token::StructSep,
Token::Str("a3"),
Token::I32(3),
Token::StructEnd,
]
);
assert_de_tokens_error::<DenyUnknown>(
vec![
Token::StructStart("DenyUnknown", Some(2)),
Token::StructSep,
Token::Str("a1"),
Token::I32(1),
Token::StructSep,
Token::Str("whoops"),
Token::I32(2),
Token::StructEnd,
],
Error::UnknownFieldError("whoops".to_owned())
);
} }
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename="Superhero")] struct Rename {
struct RenameStruct {
a1: i32, a1: i32,
#[serde(rename="a3")] #[serde(rename="a3")]
a2: i32, a2: i32,
} }
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename(serialize="SuperheroSer", deserialize="SuperheroDe"))] struct FormatRename {
struct RenameStructSerializeDeserialize {
a1: i32, a1: i32,
#[serde(rename(serialize="a4", deserialize="a5"))] #[serde(rename(xml= "a4", json="a5"))]
a2: i32, a2: i32,
} }
#[test]
fn test_rename_struct() {
assert_tokens(
&RenameStruct { a1: 1, a2: 2 },
vec![
Token::StructStart("Superhero", Some(2)),
Token::StructSep,
Token::Str("a1"),
Token::I32(1),
Token::StructSep,
Token::Str("a3"),
Token::I32(2),
Token::StructEnd,
]
);
assert_ser_tokens(
&RenameStructSerializeDeserialize { a1: 1, a2: 2 },
&[
Token::StructStart("SuperheroSer", Some(2)),
Token::StructSep,
Token::Str("a1"),
Token::I32(1),
Token::StructSep,
Token::Str("a4"),
Token::I32(2),
Token::StructEnd,
]
);
assert_de_tokens(
&RenameStructSerializeDeserialize { a1: 1, a2: 2 },
vec![
Token::StructStart("SuperheroDe", Some(2)),
Token::StructSep,
Token::Str("a1"),
Token::I32(1),
Token::StructSep,
Token::Str("a5"),
Token::I32(2),
Token::StructEnd,
]
);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename="Superhero")]
enum RenameEnum {
#[serde(rename="bruce_wayne")]
Batman,
#[serde(rename="clark_kent")]
Superman(i8),
#[serde(rename="diana_prince")]
WonderWoman(i8, i8),
#[serde(rename="barry_allan")]
Flash {
#[serde(rename="b")]
a: i32,
},
}
#[derive(Debug, PartialEq, Deserialize, Serialize)] #[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename(serialize="SuperheroSer", deserialize="SuperheroDe"))] enum SerEnum<A> {
enum RenameEnumSerializeDeserialize<A> { Map {
#[serde(rename(serialize="dick_grayson", deserialize="jason_todd"))]
Robin {
a: i8, a: i8,
#[serde(rename(serialize="c", deserialize="d"))] #[serde(rename(xml= "c", json="d"))]
b: A, b: A,
}, },
} }
#[test] #[test]
fn test_rename_enum() { fn test_default() {
assert_tokens( let deserialized_value: Default = json::from_str(&"{\"a1\":1,\"a2\":2}").unwrap();
&RenameEnum::Batman, assert_eq!(deserialized_value, Default { a1: 1, a2: 2 });
vec![
Token::EnumUnit("Superhero", "bruce_wayne"),
]
);
assert_tokens( let deserialized_value: Default = json::from_str(&"{\"a1\":1}").unwrap();
&RenameEnum::Superman(0), assert_eq!(deserialized_value, Default { a1: 1, a2: 0 });
vec![
Token::EnumNewType("Superhero", "clark_kent"),
Token::I8(0),
]
);
assert_tokens(
&RenameEnum::WonderWoman(0, 1),
vec![
Token::EnumSeqStart("Superhero", "diana_prince", Some(2)),
Token::EnumSeqSep,
Token::I8(0),
Token::EnumSeqSep,
Token::I8(1),
Token::EnumSeqEnd,
]
);
assert_tokens(
&RenameEnum::Flash { a: 1 },
vec![
Token::EnumMapStart("Superhero", "barry_allan", Some(1)),
Token::EnumMapSep,
Token::Str("b"),
Token::I32(1),
Token::EnumMapEnd,
]
);
assert_ser_tokens(
&RenameEnumSerializeDeserialize::Robin {
a: 0,
b: String::new(),
},
&[
Token::EnumMapStart("SuperheroSer", "dick_grayson", Some(2)),
Token::EnumMapSep,
Token::Str("a"),
Token::I8(0),
Token::EnumMapSep,
Token::Str("c"),
Token::Str(""),
Token::EnumMapEnd,
]
);
assert_de_tokens(
&RenameEnumSerializeDeserialize::Robin {
a: 0,
b: String::new(),
},
vec![
Token::EnumMapStart("SuperheroDe", "jason_todd", Some(2)),
Token::EnumMapSep,
Token::Str("a"),
Token::I8(0),
Token::EnumMapSep,
Token::Str("d"),
Token::Str(""),
Token::EnumMapEnd,
]
);
}
#[derive(Debug, PartialEq, Serialize)]
struct SkipSerializingStruct<'a, B, C> where C: ShouldSkip {
a: &'a i8,
#[serde(skip_serializing)]
b: B,
#[serde(skip_serializing_if="ShouldSkip::should_skip")]
c: C,
} }
#[test] #[test]
fn test_skip_serializing_struct() { fn test_rename() {
let a = 1; let value = Rename { a1: 1, a2: 2 };
assert_ser_tokens( let serialized_value = json::to_string(&value).unwrap();
&SkipSerializingStruct { assert_eq!(serialized_value, "{\"a1\":1,\"a3\":2}");
a: &a,
b: 2,
c: 3,
},
&[
Token::StructStart("SkipSerializingStruct", Some(2)),
Token::StructSep, let deserialized_value: Rename = json::from_str(&serialized_value).unwrap();
Token::Str("a"), assert_eq!(value, deserialized_value);
Token::I8(1),
Token::StructSep,
Token::Str("c"),
Token::I32(3),
Token::StructEnd,
]
);
assert_ser_tokens(
&SkipSerializingStruct {
a: &a,
b: 2,
c: 123,
},
&[
Token::StructStart("SkipSerializingStruct", Some(1)),
Token::StructSep,
Token::Str("a"),
Token::I8(1),
Token::StructEnd,
]
);
}
#[derive(Debug, PartialEq, Serialize)]
enum SkipSerializingEnum<'a, B, C> where C: ShouldSkip {
Struct {
a: &'a i8,
#[serde(skip_serializing)]
_b: B,
#[serde(skip_serializing_if="ShouldSkip::should_skip")]
c: C,
}
} }
#[test] #[test]
fn test_skip_serializing_enum() { fn test_format_rename() {
let a = 1; let value = FormatRename { a1: 1, a2: 2 };
assert_ser_tokens( let serialized_value = json::to_string(&value).unwrap();
&SkipSerializingEnum::Struct { assert_eq!(serialized_value, "{\"a1\":1,\"a5\":2}");
a: &a,
_b: 2,
c: 3,
},
&[
Token::EnumMapStart("SkipSerializingEnum", "Struct", Some(2)),
Token::EnumMapSep, let deserialized_value = json::from_str("{\"a1\":1,\"a5\":2}").unwrap();
Token::Str("a"), assert_eq!(value, deserialized_value);
Token::I8(1),
Token::EnumMapSep,
Token::Str("c"),
Token::I32(3),
Token::EnumMapEnd,
]
);
assert_ser_tokens(
&SkipSerializingEnum::Struct {
a: &a,
_b: 2,
c: 123,
},
&[
Token::EnumMapStart("SkipSerializingEnum", "Struct", Some(1)),
Token::EnumMapSep,
Token::Str("a"),
Token::I8(1),
Token::EnumMapEnd,
]
);
}
#[derive(Debug, PartialEq)]
struct NotSerializeStruct(i8);
#[derive(Debug, PartialEq)]
enum NotSerializeEnum { Trouble }
impl SerializeWith for NotSerializeEnum {
fn serialize_with<S>(&self, ser: &mut S) -> Result<(), S::Error>
where S: Serializer
{
"trouble".serialize(ser)
}
}
#[derive(Debug, PartialEq, Serialize)]
struct ContainsNotSerialize<'a, B, C, D> where B: 'a, D: SerializeWith {
a: &'a Option<i8>,
#[serde(skip_serializing)]
b: &'a B,
#[serde(skip_serializing)]
c: Option<C>,
#[serde(serialize_with="SerializeWith::serialize_with")]
d: D,
} }
#[test] #[test]
fn test_elt_not_serialize() { fn test_enum_format_rename() {
let a = 1; let s1 = String::new();
assert_ser_tokens( let value = SerEnum::Map { a: 0i8, b: s1 };
&ContainsNotSerialize { let serialized_value = json::to_string(&value).unwrap();
a: &Some(a), let ans = "{\"Map\":{\"a\":0,\"d\":\"\"}}";
b: &NotSerializeStruct(2), assert_eq!(serialized_value, ans);
c: Some(NotSerializeEnum::Trouble),
d: NotSerializeEnum::Trouble,
},
&[
Token::StructStart("ContainsNotSerialize", Some(2)),
Token::StructSep, let deserialized_value = json::from_str(ans).unwrap();
Token::Str("a"), assert_eq!(value, deserialized_value);
Token::Option(true),
Token::I8(1),
Token::StructSep,
Token::Str("d"),
Token::Str("trouble"),
Token::StructEnd,
]
);
}
#[derive(Debug, PartialEq, Serialize)]
struct SerializeWithStruct<'a, B> where B: SerializeWith {
a: &'a i8,
#[serde(serialize_with="SerializeWith::serialize_with")]
b: B,
}
#[test]
fn test_serialize_with_struct() {
let a = 1;
assert_ser_tokens(
&SerializeWithStruct {
a: &a,
b: 2,
},
&[
Token::StructStart("SerializeWithStruct", Some(2)),
Token::StructSep,
Token::Str("a"),
Token::I8(1),
Token::StructSep,
Token::Str("b"),
Token::Bool(false),
Token::StructEnd,
]
);
assert_ser_tokens(
&SerializeWithStruct {
a: &a,
b: 123,
},
&[
Token::StructStart("SerializeWithStruct", Some(2)),
Token::StructSep,
Token::Str("a"),
Token::I8(1),
Token::StructSep,
Token::Str("b"),
Token::Bool(true),
Token::StructEnd,
]
);
}
#[derive(Debug, PartialEq, Serialize)]
enum SerializeWithEnum<'a, B> where B: SerializeWith {
Struct {
a: &'a i8,
#[serde(serialize_with="SerializeWith::serialize_with")]
b: B,
}
}
#[test]
fn test_serialize_with_enum() {
let a = 1;
assert_ser_tokens(
&SerializeWithEnum::Struct {
a: &a,
b: 2,
},
&[
Token::EnumMapStart("SerializeWithEnum", "Struct", Some(2)),
Token::EnumMapSep,
Token::Str("a"),
Token::I8(1),
Token::EnumMapSep,
Token::Str("b"),
Token::Bool(false),
Token::EnumMapEnd,
]
);
assert_ser_tokens(
&SerializeWithEnum::Struct {
a: &a,
b: 123,
},
&[
Token::EnumMapStart("SerializeWithEnum", "Struct", Some(2)),
Token::EnumMapSep,
Token::Str("a"),
Token::I8(1),
Token::EnumMapSep,
Token::Str("b"),
Token::Bool(true),
Token::EnumMapEnd,
]
);
}
#[derive(Debug, PartialEq, Deserialize)]
struct DeserializeWithStruct<B> where B: DeserializeWith {
a: i8,
#[serde(deserialize_with="DeserializeWith::deserialize_with")]
b: B,
}
#[test]
fn test_deserialize_with_struct() {
assert_de_tokens(
&DeserializeWithStruct {
a: 1,
b: 2,
},
vec![
Token::StructStart("DeserializeWithStruct", Some(2)),
Token::StructSep,
Token::Str("a"),
Token::I8(1),
Token::StructSep,
Token::Str("b"),
Token::Bool(false),
Token::StructEnd,
]
);
assert_de_tokens(
&DeserializeWithStruct {
a: 1,
b: 123,
},
vec![
Token::StructStart("DeserializeWithStruct", Some(2)),
Token::StructSep,
Token::Str("a"),
Token::I8(1),
Token::StructSep,
Token::Str("b"),
Token::Bool(true),
Token::StructEnd,
]
);
}
#[derive(Debug, PartialEq, Deserialize)]
enum DeserializeWithEnum<B> where B: DeserializeWith {
Struct {
a: i8,
#[serde(deserialize_with="DeserializeWith::deserialize_with")]
b: B,
}
}
#[test]
fn test_deserialize_with_enum() {
assert_de_tokens(
&DeserializeWithEnum::Struct {
a: 1,
b: 2,
},
vec![
Token::EnumMapStart("DeserializeWithEnum", "Struct", Some(2)),
Token::EnumMapSep,
Token::Str("a"),
Token::I8(1),
Token::EnumMapSep,
Token::Str("b"),
Token::Bool(false),
Token::EnumMapEnd,
]
);
assert_de_tokens(
&DeserializeWithEnum::Struct {
a: 1,
b: 123,
},
vec![
Token::EnumMapStart("DeserializeWithEnum", "Struct", Some(2)),
Token::EnumMapSep,
Token::Str("a"),
Token::I8(1),
Token::EnumMapSep,
Token::Str("b"),
Token::Bool(true),
Token::EnumMapEnd,
]
);
}
#[test]
fn test_missing_renamed_field_struct() {
assert_de_tokens_error::<RenameStruct>(
vec![
Token::StructStart("Superhero", Some(2)),
Token::StructSep,
Token::Str("a1"),
Token::I32(1),
Token::StructEnd,
],
Error::MissingFieldError("a3"),
);
assert_de_tokens_error::<RenameStructSerializeDeserialize>(
vec![
Token::StructStart("SuperheroDe", Some(2)),
Token::StructSep,
Token::Str("a1"),
Token::I32(1),
Token::StructEnd,
],
Error::MissingFieldError("a5"),
);
}
#[test]
fn test_missing_renamed_field_enum() {
assert_de_tokens_error::<RenameEnum>(
vec![
Token::EnumMapStart("Superhero", "barry_allan", Some(1)),
Token::EnumMapEnd,
],
Error::MissingFieldError("b"),
);
assert_de_tokens_error::<RenameEnumSerializeDeserialize<i8>>(
vec![
Token::EnumMapStart("SuperheroDe", "jason_todd", Some(2)),
Token::EnumMapSep,
Token::Str("a"),
Token::I8(0),
Token::EnumMapEnd,
],
Error::MissingFieldError("d"),
);
} }
+67 -43
View File
@@ -1,39 +1,21 @@
use std::fmt; use serde;
use std::error; use serde::Serialize;
use serde::bytes::{ByteBuf, Bytes};
extern crate serde; use serde::json;
use self::serde::Serialize;
use self::serde::bytes::{ByteBuf, Bytes};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
struct Error; struct Error;
impl serde::ser::Error for Error {
fn custom<T: Into<String>>(_: T) -> Error { Error }
}
impl serde::de::Error for Error { impl serde::de::Error for Error {
fn custom<T: Into<String>>(_: T) -> Error { Error } fn syntax_error() -> Error { Error }
fn end_of_stream() -> Error { Error } fn end_of_stream_error() -> Error { Error }
}
impl fmt::Display for Error { fn unknown_field_error(_field: &str) -> Error { Error }
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(format!("{:?}", self).as_ref())
}
}
impl error::Error for Error { fn missing_field_error(_field: &'static str) -> Error { Error }
fn description(&self) -> &str {
"Serde Deserialization Error"
}
fn cause(&self) -> Option<&error::Error> {
None
}
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@@ -53,74 +35,74 @@ impl BytesSerializer {
impl serde::Serializer for BytesSerializer { impl serde::Serializer for BytesSerializer {
type Error = Error; type Error = Error;
fn serialize_unit(&mut self) -> Result<(), Error> { fn visit_unit(&mut self) -> Result<(), Error> {
Err(Error) Err(Error)
} }
fn serialize_bool(&mut self, _v: bool) -> Result<(), Error> { fn visit_bool(&mut self, _v: bool) -> Result<(), Error> {
Err(Error) Err(Error)
} }
fn serialize_i64(&mut self, _v: i64) -> Result<(), Error> { fn visit_i64(&mut self, _v: i64) -> Result<(), Error> {
Err(Error) Err(Error)
} }
fn serialize_u64(&mut self, _v: u64) -> Result<(), Error> { fn visit_u64(&mut self, _v: u64) -> Result<(), Error> {
Err(Error) Err(Error)
} }
fn serialize_f32(&mut self, _v: f32) -> Result<(), Error> { fn visit_f32(&mut self, _v: f32) -> Result<(), Error> {
Err(Error) Err(Error)
} }
fn serialize_f64(&mut self, _v: f64) -> Result<(), Error> { fn visit_f64(&mut self, _v: f64) -> Result<(), Error> {
Err(Error) Err(Error)
} }
fn serialize_char(&mut self, _v: char) -> Result<(), Error> { fn visit_char(&mut self, _v: char) -> Result<(), Error> {
Err(Error) Err(Error)
} }
fn serialize_str(&mut self, _v: &str) -> Result<(), Error> { fn visit_str(&mut self, _v: &str) -> Result<(), Error> {
Err(Error) Err(Error)
} }
fn serialize_none(&mut self) -> Result<(), Error> { fn visit_none(&mut self) -> Result<(), Error> {
Err(Error) Err(Error)
} }
fn serialize_some<V>(&mut self, _value: V) -> Result<(), Error> fn visit_some<V>(&mut self, _value: V) -> Result<(), Error>
where V: serde::Serialize, where V: serde::Serialize,
{ {
Err(Error) Err(Error)
} }
fn serialize_seq<V>(&mut self, _visitor: V) -> Result<(), Error> fn visit_seq<V>(&mut self, _visitor: V) -> Result<(), Error>
where V: serde::ser::SeqVisitor, where V: serde::ser::SeqVisitor,
{ {
Err(Error) Err(Error)
} }
fn serialize_seq_elt<T>(&mut self, _value: T) -> Result<(), Error> fn visit_seq_elt<T>(&mut self, _value: T) -> Result<(), Error>
where T: serde::Serialize where T: serde::Serialize
{ {
Err(Error) Err(Error)
} }
fn serialize_map<V>(&mut self, _visitor: V) -> Result<(), Error> fn visit_map<V>(&mut self, _visitor: V) -> Result<(), Error>
where V: serde::ser::MapVisitor, where V: serde::ser::MapVisitor,
{ {
Err(Error) Err(Error)
} }
fn serialize_map_elt<K, V>(&mut self, _key: K, _value: V) -> Result<(), Error> fn visit_map_elt<K, V>(&mut self, _key: K, _value: V) -> Result<(), Error>
where K: serde::Serialize, where K: serde::Serialize,
V: serde::Serialize, V: serde::Serialize,
{ {
Err(Error) Err(Error)
} }
fn serialize_bytes(&mut self, bytes: &[u8]) -> Result<(), Error> { fn visit_bytes(&mut self, bytes: &[u8]) -> Result<(), Error> {
assert_eq!(self.bytes, bytes); assert_eq!(self.bytes, bytes);
Ok(()) Ok(())
} }
@@ -143,13 +125,13 @@ impl BytesDeserializer {
impl serde::Deserializer for BytesDeserializer { impl serde::Deserializer for BytesDeserializer {
type Error = Error; type Error = Error;
fn deserialize<V>(&mut self, _visitor: V) -> Result<V::Value, Error> fn visit<V>(&mut self, _visitor: V) -> Result<V::Value, Error>
where V: serde::de::Visitor, where V: serde::de::Visitor,
{ {
Err(Error) Err(Error)
} }
fn deserialize_bytes<V>(&mut self, mut visitor: V) -> Result<V::Value, Error> fn visit_bytes<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: serde::de::Visitor, where V: serde::de::Visitor,
{ {
visitor.visit_byte_buf(self.bytes.take().unwrap()) visitor.visit_byte_buf(self.bytes.take().unwrap())
@@ -158,6 +140,17 @@ impl serde::Deserializer for BytesDeserializer {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#[test]
fn test_bytes_ser_json() {
let buf = vec![];
let bytes = Bytes::from(&buf);
assert_eq!(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());
}
#[test] #[test]
fn test_bytes_ser_bytes() { fn test_bytes_ser_bytes() {
let buf = vec![]; let buf = vec![];
@@ -171,8 +164,39 @@ fn test_bytes_ser_bytes() {
bytes.serialize(&mut ser).unwrap(); bytes.serialize(&mut ser).unwrap();
} }
#[test]
fn test_byte_buf_ser_json() {
let bytes = ByteBuf::new();
assert_eq!(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());
}
#[test]
fn test_byte_buf_ser_bytes() {
let bytes = ByteBuf::new();
let mut ser = BytesSerializer::new(vec![]);
bytes.serialize(&mut ser).unwrap();
let bytes = ByteBuf::from(vec![1, 2, 3]);
let mut ser = BytesSerializer::new(vec![1, 2, 3]);
bytes.serialize(&mut ser).unwrap();
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#[test]
fn test_byte_buf_de_json() {
let bytes = ByteBuf::new();
let v: ByteBuf = 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();
assert_eq!(v, bytes);
}
#[test] #[test]
fn test_byte_buf_de_bytes() { fn test_byte_buf_de_bytes() {
let mut de = BytesDeserializer::new(vec![]); let mut de = BytesDeserializer::new(vec![]);
File diff suppressed because it is too large Load Diff
-56
View File
@@ -1,56 +0,0 @@
// These just test that serde_codegen is able to produce code that compiles
// successfully when there are a variety of generics involved.
extern crate serde;
use self::serde::ser::{Serialize, Serializer};
use self::serde::de::{Deserialize, Deserializer};
//////////////////////////////////////////////////////////////////////////
#[derive(Serialize, Deserialize)]
struct With<T> {
t: T,
#[serde(serialize_with="ser_i32", deserialize_with="de_i32")]
i: i32,
}
#[derive(Serialize, Deserialize)]
struct WithRef<'a, T: 'a> {
#[serde(skip_deserializing)]
t: Option<&'a T>,
#[serde(serialize_with="ser_i32", deserialize_with="de_i32")]
i: i32,
}
#[derive(Serialize, Deserialize)]
struct Bounds<T: Serialize + Deserialize> {
t: T,
option: Option<T>,
boxed: Box<T>,
option_boxed: Option<Box<T>>,
}
#[derive(Serialize, Deserialize)]
struct NoBounds<T> {
t: T,
option: Option<T>,
boxed: Box<T>,
option_boxed: Option<Box<T>>,
}
#[derive(Serialize, Deserialize)]
enum EnumWith<T> {
A(
#[serde(serialize_with="ser_i32", deserialize_with="de_i32")]
i32),
B {
t: T,
#[serde(serialize_with="ser_i32", deserialize_with="de_i32")]
i: i32 },
}
//////////////////////////////////////////////////////////////////////////
fn ser_i32<S: Serializer>(_: &i32, _: &mut S) -> Result<(), S::Error> { panic!() }
fn de_i32<D: Deserializer>(_: &mut D) -> Result<i32, D::Error> { panic!() }
File diff suppressed because it is too large Load Diff
+50
View File
@@ -0,0 +1,50 @@
use std::collections::BTreeMap;
use serde::json::value::Value;
use serde::json::builder::{ArrayBuilder, ObjectBuilder};
#[test]
fn test_array_builder() {
let value = ArrayBuilder::new().unwrap();
assert_eq!(value, Value::Array(Vec::new()));
let value = ArrayBuilder::new()
.push(1)
.push(2)
.push(3)
.unwrap();
assert_eq!(value, Value::Array(vec!(Value::U64(1), Value::U64(2), Value::U64(3))));
let value = ArrayBuilder::new()
.push_array(|bld| bld.push(1).push(2).push(3))
.unwrap();
assert_eq!(value, Value::Array(vec!(Value::Array(vec!(Value::U64(1), Value::U64(2), Value::U64(3))))));
let value = ArrayBuilder::new()
.push_object(|bld|
bld
.insert("a".to_string(), 1)
.insert("b".to_string(), 2))
.unwrap();
let mut map = BTreeMap::new();
map.insert("a".to_string(), Value::U64(1));
map.insert("b".to_string(), Value::U64(2));
assert_eq!(value, Value::Array(vec!(Value::Object(map))));
}
#[test]
fn test_object_builder() {
let value = ObjectBuilder::new().unwrap();
assert_eq!(value, Value::Object(BTreeMap::new()));
let value = ObjectBuilder::new()
.insert("a".to_string(), 1)
.insert("b".to_string(), 2)
.unwrap();
let mut map = BTreeMap::new();
map.insert("a".to_string(), Value::U64(1));
map.insert("b".to_string(), Value::U64(2));
assert_eq!(value, Value::Object(map));
}
+224 -380
View File
@@ -1,5 +1,18 @@
use std::marker::PhantomData; use std::collections::BTreeMap;
use token::{Token, assert_tokens, assert_ser_tokens, assert_de_tokens}; use serde::json::{self, Value};
macro_rules! btreemap {
() => {
BTreeMap::new()
};
($($key:expr => $value:expr),+) => {
{
let mut map = BTreeMap::new();
$(map.insert($key, $value);)+
map
}
}
}
/* /*
trait Trait { trait Trait {
@@ -7,13 +20,6 @@ trait Trait {
} }
*/ */
// That tests that the derived Serialize implementation doesn't trigger
// any warning about `serializer` not being used, in case of empty enums.
#[derive(Serialize)]
#[allow(dead_code)]
#[deny(unused_variables)]
enum Void {}
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
struct NamedUnit; struct NamedUnit;
@@ -77,7 +83,7 @@ enum SerEnum<'a, B: 'a, C: /* Trait + */ 'a, D> where D: /* Trait + */ 'a {
}, },
} }
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Deserialize)]
enum DeEnum<B, C: /* Trait */, D> /* where D: Trait */ { enum DeEnum<B, C: /* Trait */, D> /* where D: Trait */ {
Unit, Unit,
Seq( Seq(
@@ -125,44 +131,25 @@ enum Lifetimes<'a> {
NoLifetimeMap { a: i32 }, 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 },
}
trait AssociatedType {
type X;
}
impl AssociatedType for i32 {
type X = i32;
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct DefaultTyParam<T: AssociatedType<X=i32> = i32> {
phantom: PhantomData<T>
}
#[test] #[test]
fn test_named_unit() { fn test_named_unit() {
assert_tokens( let named_unit = NamedUnit;
&NamedUnit,
vec![Token::UnitStruct("NamedUnit")] assert_eq!(
json::to_string(&named_unit).unwrap(),
"null".to_string()
); );
assert_eq!(
json::to_value(&named_unit),
Value::Null
);
let v: NamedUnit = json::from_str("null").unwrap();
assert_eq!(v, named_unit);
let v: NamedUnit = json::from_value(Value::Null).unwrap();
assert_eq!(v, named_unit);
} }
#[test] #[test]
@@ -170,58 +157,35 @@ fn test_ser_named_tuple() {
let a = 5; let a = 5;
let mut b = 6; let mut b = 6;
let c = 7; let c = 7;
assert_ser_tokens( let named_tuple = SerNamedTuple(&a, &mut b, c);
&SerNamedTuple(&a, &mut b, c),
&[
Token::TupleStructStart("SerNamedTuple", Some(3)),
Token::TupleStructSep,
Token::I32(5),
Token::TupleStructSep, assert_eq!(
Token::I32(6), json::to_string(&named_tuple).unwrap(),
"[5,6,7]"
);
Token::TupleStructSep, assert_eq!(
Token::I32(7), json::to_value(&named_tuple),
Value::Array(vec![Value::U64(5), Value::U64(6), Value::U64(7)])
Token::TupleStructEnd,
],
); );
} }
#[test] #[test]
fn test_de_named_tuple() { fn test_de_named_tuple() {
assert_de_tokens( let v: DeNamedTuple<i32, i32, i32> = json::from_str("[1,2,3]").unwrap();
&DeNamedTuple(5, 6, 7), assert_eq!(
vec![ v,
Token::SeqStart(Some(3)), DeNamedTuple(1, 2, 3)
Token::SeqSep,
Token::I32(5),
Token::SeqSep,
Token::I32(6),
Token::SeqSep,
Token::I32(7),
Token::SeqEnd,
]
); );
assert_de_tokens( let v: Value = json::from_str("[1,2,3]").unwrap();
&DeNamedTuple(5, 6, 7), assert_eq!(
vec![ v,
Token::TupleStructStart("DeNamedTuple", Some(3)), Value::Array(vec![
Token::TupleStructSep, Value::U64(1),
Token::I32(5), Value::U64(2),
Value::U64(3),
Token::TupleStructSep, ])
Token::I32(6),
Token::TupleStructSep,
Token::I32(7),
Token::TupleStructEnd,
]
); );
} }
@@ -230,68 +194,60 @@ fn test_ser_named_map() {
let a = 5; let a = 5;
let mut b = 6; let mut b = 6;
let c = 7; let c = 7;
let named_map = SerNamedMap {
a: &a,
b: &mut b,
c: c,
};
assert_ser_tokens( assert_eq!(
&SerNamedMap { json::to_string(&named_map).unwrap(),
a: &a, "{\"a\":5,\"b\":6,\"c\":7}"
b: &mut b, );
c: c,
},
&[
Token::StructStart("SerNamedMap", Some(3)),
Token::StructSep, assert_eq!(
Token::Str("a"), json::to_value(&named_map),
Token::I32(5), Value::Object(btreemap![
"a".to_string() => Value::U64(5),
Token::StructSep, "b".to_string() => Value::U64(6),
Token::Str("b"), "c".to_string() => Value::U64(7)
Token::I32(6), ])
Token::StructSep,
Token::Str("c"),
Token::I32(7),
Token::StructEnd,
]
); );
} }
#[test] #[test]
fn test_de_named_map() { fn test_de_named_map() {
assert_de_tokens( let v = DeNamedMap {
&DeNamedMap { a: 5,
a: 5, b: 6,
b: 6, c: 7,
c: 7, };
},
vec![
Token::StructStart("DeNamedMap", Some(3)),
Token::StructSep, let v2: DeNamedMap<i32, i32, i32> = json::from_str(
Token::Str("a"), "{\"a\":5,\"b\":6,\"c\":7}"
Token::I32(5), ).unwrap();
assert_eq!(v, v2);
Token::StructSep, let v2 = json::from_value(Value::Object(btreemap![
Token::Str("b"), "a".to_string() => Value::U64(5),
Token::I32(6), "b".to_string() => Value::U64(6),
"c".to_string() => Value::U64(7)
Token::StructSep, ])).unwrap();
Token::Str("c"), assert_eq!(v, v2);
Token::I32(7),
Token::StructEnd,
]
);
} }
#[test] #[test]
fn test_ser_enum_unit() { fn test_ser_enum_unit() {
assert_ser_tokens( assert_eq!(
&SerEnum::Unit::<u32, u32, u32>, json::to_string(&SerEnum::Unit::<u32, u32, u32>).unwrap(),
&[ "{\"Unit\":[]}"
Token::EnumUnit("SerEnum", "Unit"), );
]
assert_eq!(
json::to_value(&SerEnum::Unit::<u32, u32, u32>),
Value::Object(btreemap!(
"Unit".to_string() => Value::Array(vec![]))
)
); );
} }
@@ -304,32 +260,37 @@ fn test_ser_enum_seq() {
let mut e = 5; let mut e = 5;
//let f = 6; //let f = 6;
assert_ser_tokens( assert_eq!(
&SerEnum::Seq( json::to_string(&SerEnum::Seq(
a, a,
b, b,
&c, &c,
//d, //d,
&mut e, &mut e,
//f, //f,
), )).unwrap(),
&[ "{\"Seq\":[1,2,3,5]}".to_string()
Token::EnumSeqStart("SerEnum", "Seq", Some(4)), );
Token::EnumSeqSep, assert_eq!(
Token::I8(1), json::to_value(&SerEnum::Seq(
a,
Token::EnumSeqSep, b,
Token::I32(2), &c,
//d,
Token::EnumSeqSep, &mut e,
Token::I32(3), //e,
)),
Token::EnumSeqSep, Value::Object(btreemap!(
Token::I32(5), "Seq".to_string() => Value::Array(vec![
Value::U64(1),
Token::EnumSeqEnd, Value::U64(2),
], Value::U64(3),
//Value::U64(4),
Value::U64(5),
//Value::U64(6),
])
))
); );
} }
@@ -342,46 +303,54 @@ fn test_ser_enum_map() {
let mut e = 5; let mut e = 5;
//let f = 6; //let f = 6;
assert_ser_tokens( assert_eq!(
&SerEnum::Map { json::to_string(&SerEnum::Map {
a: a, a: a,
b: b, b: b,
c: &c, c: &c,
//d: d, //d: d,
e: &mut e, e: &mut e,
//f: f, //f: f,
}, }).unwrap(),
&[ "{\"Map\":{\"a\":1,\"b\":2,\"c\":3,\"e\":5}}".to_string()
Token::EnumMapStart("SerEnum", "Map", Some(4)), );
Token::EnumMapSep, assert_eq!(
Token::Str("a"), json::to_value(&SerEnum::Map {
Token::I8(1), a: a,
b: b,
Token::EnumMapSep, c: &c,
Token::Str("b"), //d: d,
Token::I32(2), e: &mut e,
//f: f,
Token::EnumMapSep, }),
Token::Str("c"), Value::Object(btreemap!(
Token::I32(3), "Map".to_string() => Value::Object(btreemap![
"a".to_string() => Value::U64(1),
Token::EnumMapSep, "b".to_string() => Value::U64(2),
Token::Str("e"), "c".to_string() => Value::U64(3),
Token::I32(5), //"d".to_string() => Value::U64(4)
"e".to_string() => Value::U64(5)
Token::EnumMapEnd, //"f".to_string() => Value::U64(6)
], ])
))
); );
} }
#[test] #[test]
fn test_de_enum_unit() { fn test_de_enum_unit() {
assert_tokens( let v: DeEnum<_, _, _> = json::from_str("{\"Unit\":[]}").unwrap();
&DeEnum::Unit::<u32, u32, u32>, assert_eq!(
vec![ v,
Token::EnumUnit("DeEnum", "Unit"), DeEnum::Unit::<u32, u32, u32>
], );
let v: DeEnum<_, _, _> = json::from_value(Value::Object(btreemap!(
"Unit".to_string() => Value::Array(vec![]))
)).unwrap();
assert_eq!(
v,
DeEnum::Unit::<u32, u32, u32>
); );
} }
@@ -394,32 +363,39 @@ fn test_de_enum_seq() {
let e = 5; let e = 5;
//let f = 6; //let f = 6;
assert_tokens( let v: DeEnum<_, _, _> = json::from_str("{\"Seq\":[1,2,3,5]}").unwrap();
&DeEnum::Seq( assert_eq!(
v,
DeEnum::Seq(
a, a,
b, b,
c, c,
//d, //d,
e, e,
//f, //f,
), )
vec![ );
Token::EnumSeqStart("DeEnum", "Seq", Some(4)),
Token::EnumSeqSep, let v: DeEnum<_, _, _> = json::from_value(Value::Object(btreemap!(
Token::I8(1), "Seq".to_string() => Value::Array(vec![
Value::U64(1),
Token::EnumSeqSep, Value::U64(2),
Token::I32(2), Value::U64(3),
//Value::U64(4),
Token::EnumSeqSep, Value::U64(5),
Token::I32(3), //Value::U64(6),
])
Token::EnumSeqSep, ))).unwrap();
Token::I32(5), assert_eq!(
v,
Token::EnumSeqEnd, DeEnum::Seq(
], a,
b,
c,
//d,
e,
//e,
)
); );
} }
@@ -432,202 +408,70 @@ fn test_de_enum_map() {
let e = 5; let e = 5;
//let f = 6; //let f = 6;
assert_tokens( let v: DeEnum<_, _, _> = json::from_str(
&DeEnum::Map { "{\"Map\":{\"a\":1,\"b\":2,\"c\":3,\"e\":5}}"
).unwrap();
assert_eq!(
v,
DeEnum::Map {
a: a, a: a,
b: b, b: b,
c: c, c: c,
//d: d, //d: d,
e: e, e: e,
//f: f, //f: f,
}, }
vec![ );
Token::EnumMapStart("DeEnum", "Map", Some(4)),
Token::EnumMapSep, let v: DeEnum<_, _, _> = json::from_value(Value::Object(btreemap!(
Token::Str("a"), "Map".to_string() => Value::Object(btreemap![
Token::I8(1), "a".to_string() => Value::U64(1),
"b".to_string() => Value::U64(2),
"c".to_string() => Value::U64(3),
//"d".to_string() => Value::U64(4)
"e".to_string() => Value::U64(5)
//"f".to_string() => Value::U64(6)
])
))).unwrap();
Token::EnumMapSep, assert_eq!(
Token::Str("b"), v,
Token::I32(2), DeEnum::Map {
a: a,
Token::EnumMapSep, b: b,
Token::Str("c"), c: c,
Token::I32(3), //d: d,
e: e,
Token::EnumMapSep, //f: f,
Token::Str("e"), }
Token::I32(5),
Token::EnumMapEnd,
],
); );
} }
#[test] #[test]
fn test_lifetimes() { fn test_lifetimes() {
let value = 5; let value = 5;
let lifetime = Lifetimes::LifetimeSeq(&value);
assert_ser_tokens( assert_eq!(
&Lifetimes::LifetimeSeq(&value), json::to_string(&lifetime).unwrap(),
&[ "{\"LifetimeSeq\":[5]}"
Token::EnumNewType("Lifetimes", "LifetimeSeq"),
Token::I32(5),
]
); );
assert_ser_tokens( let lifetime = Lifetimes::NoLifetimeSeq(5);
&Lifetimes::NoLifetimeSeq(5), assert_eq!(
&[ json::to_string(&lifetime).unwrap(),
Token::EnumNewType("Lifetimes", "NoLifetimeSeq"), "{\"NoLifetimeSeq\":[5]}"
Token::I32(5),
]
); );
assert_ser_tokens( let value = 5;
&Lifetimes::LifetimeMap { a: &value }, let lifetime = Lifetimes::LifetimeMap { a: &value };
&[ assert_eq!(
Token::EnumMapStart("Lifetimes", "LifetimeMap", Some(1)), json::to_string(&lifetime).unwrap(),
"{\"LifetimeMap\":{\"a\":5}}"
Token::EnumMapSep,
Token::Str("a"),
Token::I32(5),
Token::EnumMapEnd,
]
); );
assert_ser_tokens( let lifetime = Lifetimes::NoLifetimeMap { a: 5 };
&Lifetimes::NoLifetimeMap { a: 5 }, assert_eq!(
&[ json::to_string(&lifetime).unwrap(),
Token::EnumMapStart("Lifetimes", "NoLifetimeMap", Some(1)), "{\"NoLifetimeMap\":{\"a\":5}}"
Token::EnumMapSep,
Token::Str("a"),
Token::I32(5),
Token::EnumMapEnd,
]
);
}
#[test]
fn test_generic_struct() {
assert_tokens(
&GenericStruct { x: 5u32 },
vec![
Token::StructStart("GenericStruct", Some(1)),
Token::StructSep,
Token::Str("x"),
Token::U32(5),
Token::StructEnd,
]
);
}
#[test]
fn test_generic_newtype_struct() {
assert_tokens(
&GenericNewTypeStruct(5u32),
vec![
Token::StructNewType("GenericNewTypeStruct"),
Token::U32(5),
]
);
}
#[test]
fn test_generic_tuple_struct() {
assert_tokens(
&GenericTupleStruct(5u32, 6u32),
vec![
Token::TupleStructStart("GenericTupleStruct", Some(2)),
Token::TupleStructSep,
Token::U32(5),
Token::TupleStructSep,
Token::U32(6),
Token::TupleStructEnd,
]
);
}
#[test]
fn test_generic_enum_unit() {
assert_tokens(
&GenericEnum::Unit::<u32, u32>,
vec![
Token::EnumUnit("GenericEnum", "Unit"),
]
);
}
#[test]
fn test_generic_enum_newtype() {
assert_tokens(
&GenericEnum::NewType::<u32, u32>(5),
vec![
Token::EnumNewType("GenericEnum", "NewType"),
Token::U32(5),
]
);
}
#[test]
fn test_generic_enum_seq() {
assert_tokens(
&GenericEnum::Seq::<u32, u32>(5, 6),
vec![
Token::EnumSeqStart("GenericEnum", "Seq", Some(2)),
Token::EnumSeqSep,
Token::U32(5),
Token::EnumSeqSep,
Token::U32(6),
Token::EnumSeqEnd,
]
);
}
#[test]
fn test_generic_enum_map() {
assert_tokens(
&GenericEnum::Map::<u32, u32> { x: 5, y: 6 },
vec![
Token::EnumMapStart("GenericEnum", "Map", Some(2)),
Token::EnumMapSep,
Token::Str("x"),
Token::U32(5),
Token::EnumMapSep,
Token::Str("y"),
Token::U32(6),
Token::EnumMapEnd,
]
);
}
#[test]
fn test_default_ty_param() {
assert_tokens(
&DefaultTyParam::<i32> { phantom: PhantomData },
vec![
Token::StructStart("DefaultTyParam", Some(1)),
Token::StructSep,
Token::Str("phantom"),
Token::UnitStruct("PhantomData"),
Token::StructEnd,
]
); );
} }
+380 -169
View File
@@ -1,20 +1,274 @@
use std::vec;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::net;
use std::path::{Path, PathBuf};
use std::str;
use token::{self, Token}; use serde::ser::{Serialize, Serializer, SeqVisitor, MapVisitor};
#[derive(Clone, PartialEq, Debug)]
pub enum Token<'a> {
Bool(bool),
Isize(isize),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
Usize(usize),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
F32(f32),
F64(f64),
Char(char),
Str(&'a str),
Option(bool),
Unit,
NamedUnit(&'a str),
EnumUnit(&'a str, &'a str),
SeqStart(Option<usize>),
NamedSeqStart(&'a str, Option<usize>),
EnumSeqStart(&'a str, &'a str, Option<usize>),
SeqSep,
SeqEnd,
MapStart(Option<usize>),
NamedMapStart(&'a str, Option<usize>),
EnumMapStart(&'a str, &'a str, Option<usize>),
MapSep,
MapEnd,
}
struct AssertSerializer<'a> {
iter: vec::IntoIter<Token<'a>>,
}
impl<'a> AssertSerializer<'a> {
fn new(values: Vec<Token<'a>>) -> AssertSerializer {
AssertSerializer {
iter: values.into_iter(),
}
}
fn visit_sequence<V>(&mut self, mut visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
while let Some(()) = try!(visitor.visit(self)) { }
assert_eq!(self.iter.next(), Some(Token::SeqEnd));
Ok(())
}
fn visit_mapping<V>(&mut self, mut visitor: V) -> Result<(), ()>
where V: MapVisitor
{
while let Some(()) = try!(visitor.visit(self)) { }
assert_eq!(self.iter.next(), Some(Token::MapEnd));
Ok(())
}
}
impl<'a> Serializer for AssertSerializer<'a> {
type Error = ();
fn visit_unit(&mut self) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::Unit));
Ok(())
}
fn visit_named_unit(&mut self, name: &str) -> Result<(), ()> {
assert_eq!(self.iter.next().unwrap(), Token::NamedUnit(name));
Ok(())
}
fn visit_enum_unit(&mut self, name: &str, variant: &str) -> Result<(), ()> {
assert_eq!(self.iter.next().unwrap(), Token::EnumUnit(name, variant));
Ok(())
}
fn visit_bool(&mut self, v: bool) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::Bool(v)));
Ok(())
}
fn visit_isize(&mut self, v: isize) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::Isize(v)));
Ok(())
}
fn visit_i8(&mut self, v: i8) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::I8(v)));
Ok(())
}
fn visit_i16(&mut self, v: i16) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::I16(v)));
Ok(())
}
fn visit_i32(&mut self, v: i32) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::I32(v)));
Ok(())
}
fn visit_i64(&mut self, v: i64) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::I64(v)));
Ok(())
}
fn visit_usize(&mut self, v: usize) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::Usize(v)));
Ok(())
}
fn visit_u8(&mut self, v: u8) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::U8(v)));
Ok(())
}
fn visit_u16(&mut self, v: u16) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::U16(v)));
Ok(())
}
fn visit_u32(&mut self, v: u32) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::U32(v)));
Ok(())
}
fn visit_u64(&mut self, v: u64) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::U64(v)));
Ok(())
}
fn visit_f32(&mut self, v: f32) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::F32(v)));
Ok(())
}
fn visit_f64(&mut self, v: f64) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::F64(v)));
Ok(())
}
fn visit_char(&mut self, v: char) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::Char(v)));
Ok(())
}
fn visit_str(&mut self, v: &str) -> Result<(), ()> {
assert_eq!(self.iter.next().unwrap(), Token::Str(v));
Ok(())
}
fn visit_none(&mut self) -> Result<(), ()> {
assert_eq!(self.iter.next(), Some(Token::Option(false)));
Ok(())
}
fn visit_some<V>(&mut self, value: V) -> Result<(), ()>
where V: Serialize,
{
assert_eq!(self.iter.next(), Some(Token::Option(true)));
value.serialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let len = visitor.len();
assert_eq!(self.iter.next(), Some(Token::SeqStart(len)));
self.visit_sequence(visitor)
}
fn visit_named_seq<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));
self.visit_sequence(visitor)
}
fn visit_enum_seq<V>(&mut self,
name: &str,
variant: &str,
visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let len = visitor.len();
assert_eq!(self.iter.next().unwrap(), Token::EnumSeqStart(name, variant, len));
self.visit_sequence(visitor)
}
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), ()>
where T: Serialize
{
assert_eq!(self.iter.next(), Some(Token::SeqSep));
value.serialize(self)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let len = visitor.len();
assert_eq!(self.iter.next(), Some(Token::MapStart(len)));
self.visit_mapping(visitor)
}
fn visit_named_map<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));
self.visit_mapping(visitor)
}
fn visit_enum_map<V>(&mut self, name: &str, variant: &str, visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let len = visitor.len();
assert_eq!(self.iter.next().unwrap(), Token::EnumMapStart(name, variant, len));
self.visit_mapping(visitor)
}
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), ()>
where K: Serialize,
V: Serialize,
{
assert_eq!(self.iter.next(), Some(Token::MapSep));
try!(key.serialize(self));
value.serialize(self)
}
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
#[derive(Serialize)] #[derive(Serialize)]
struct UnitStruct; struct NamedUnit;
#[derive(Serialize)] #[derive(Serialize)]
struct TupleStruct(i32, i32, i32); struct NamedSeq(i32, i32, i32);
#[derive(Serialize)] #[derive(Serialize)]
struct Struct { struct NamedMap {
a: i32, a: i32,
b: i32, b: i32,
c: i32, c: i32,
@@ -23,69 +277,91 @@ struct Struct {
#[derive(Serialize)] #[derive(Serialize)]
enum Enum { enum Enum {
Unit, Unit,
One(i32),
Seq(i32, i32), Seq(i32, i32),
Map { a: i32, b: i32 }, Map { a: i32, b: i32 },
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
declare_ser_tests! { macro_rules! btreemap {
() => {
BTreeMap::new()
};
($($key:expr => $value:expr),+) => {
{
let mut map = BTreeMap::new();
$(map.insert($key, $value);)+
map
}
}
}
macro_rules! declare_test {
($name:ident { $($value:expr => $tokens:expr,)+ }) => {
#[test]
fn $name() {
$(
let mut ser = AssertSerializer::new($tokens);
assert_eq!($value.serialize(&mut ser), Ok(()));
)+
}
}
}
macro_rules! declare_tests {
($($name:ident { $($value:expr => $tokens:expr,)+ })+) => {
$(
declare_test!($name { $($value => $tokens,)+ });
)+
}
}
declare_tests! {
test_unit { test_unit {
() => &[Token::Unit], () => vec![Token::Unit],
} }
test_bool { test_bool {
true => &[Token::Bool(true)], true => vec![Token::Bool(true)],
false => &[Token::Bool(false)], false => vec![Token::Bool(false)],
} }
test_isizes { test_isizes {
0isize => &[Token::Isize(0)], 0isize => vec![Token::Isize(0)],
0i8 => &[Token::I8(0)], 0i8 => vec![Token::I8(0)],
0i16 => &[Token::I16(0)], 0i16 => vec![Token::I16(0)],
0i32 => &[Token::I32(0)], 0i32 => vec![Token::I32(0)],
0i64 => &[Token::I64(0)], 0i64 => vec![Token::I64(0)],
} }
test_usizes { test_usizes {
0usize => &[Token::Usize(0)], 0usize => vec![Token::Usize(0)],
0u8 => &[Token::U8(0)], 0u8 => vec![Token::U8(0)],
0u16 => &[Token::U16(0)], 0u16 => vec![Token::U16(0)],
0u32 => &[Token::U32(0)], 0u32 => vec![Token::U32(0)],
0u64 => &[Token::U64(0)], 0u64 => vec![Token::U64(0)],
} }
test_floats { test_floats {
0f32 => &[Token::F32(0.)], 0f32 => vec![Token::F32(0.)],
0f64 => &[Token::F64(0.)], 0f64 => vec![Token::F64(0.)],
} }
test_char { test_char {
'a' => &[Token::Char('a')], 'a' => vec![Token::Char('a')],
} }
test_str { test_str {
"abc" => &[Token::Str("abc")], "abc" => vec![Token::Str("abc")],
"abc".to_owned() => &[Token::Str("abc")], "abc".to_string() => vec![Token::Str("abc")],
} }
test_option { test_option {
None::<i32> => &[Token::Option(false)], None::<i32> => vec![Token::Option(false)],
Some(1) => &[ Some(1) => vec![
Token::Option(true), Token::Option(true),
Token::I32(1), Token::I32(1),
], ],
} }
test_result {
Ok::<i32, i32>(0) => &[
Token::EnumNewType("Result", "Ok"),
Token::I32(0),
],
Err::<i32, i32>(1) => &[
Token::EnumNewType("Result", "Err"),
Token::I32(1),
],
}
test_slice { test_slice {
&[0][..0] => &[ &[0][..0] => vec![
Token::SeqStart(Some(0)), Token::SeqStart(Some(0)),
Token::SeqEnd, Token::SeqEnd,
], ],
&[1, 2, 3][..] => &[ &[1, 2, 3][..] => vec![
Token::SeqStart(Some(3)), Token::SeqStart(Some(3)),
Token::SeqSep, Token::SeqSep,
Token::I32(1), Token::I32(1),
@@ -99,12 +375,12 @@ declare_ser_tests! {
], ],
} }
test_array { test_array {
[0; 0] => &[ [0; 0] => vec![
Token::SeqArrayStart(0), Token::SeqStart(Some(0)),
Token::SeqEnd, Token::SeqEnd,
], ],
[1, 2, 3] => &[ [1, 2, 3] => vec![
Token::SeqArrayStart(3), Token::SeqStart(Some(3)),
Token::SeqSep, Token::SeqSep,
Token::I32(1), Token::I32(1),
@@ -117,11 +393,11 @@ declare_ser_tests! {
], ],
} }
test_vec { test_vec {
Vec::<isize>::new() => &[ Vec::<isize>::new() => vec![
Token::SeqStart(Some(0)), Token::SeqStart(Some(0)),
Token::SeqEnd, Token::SeqEnd,
], ],
vec![vec![], vec![1], vec![2, 3]] => &[ vec![vec![], vec![1], vec![2, 3]] => vec![
Token::SeqStart(Some(3)), Token::SeqStart(Some(3)),
Token::SeqSep, Token::SeqSep,
Token::SeqStart(Some(0)), Token::SeqStart(Some(0)),
@@ -145,34 +421,34 @@ declare_ser_tests! {
], ],
} }
test_tuple { test_tuple {
(1,) => &[ (1,) => vec![
Token::TupleStart(1), Token::SeqStart(Some(1)),
Token::TupleSep, Token::SeqSep,
Token::I32(1), Token::I32(1),
Token::TupleEnd, Token::SeqEnd,
], ],
(1, 2, 3) => &[ (1, 2, 3) => vec![
Token::TupleStart(3), Token::SeqStart(Some(3)),
Token::TupleSep, Token::SeqSep,
Token::I32(1), Token::I32(1),
Token::TupleSep, Token::SeqSep,
Token::I32(2), Token::I32(2),
Token::TupleSep, Token::SeqSep,
Token::I32(3), Token::I32(3),
Token::TupleEnd, Token::SeqEnd,
], ],
} }
test_btreemap { test_btreemap {
btreemap![1 => 2] => &[ btreemap![1 => 2] => vec![
Token::MapStart(Some(1)), Token::MapStart(Some(1)),
Token::MapSep, Token::MapSep,
Token::I32(1), Token::I32(1),
Token::I32(2), Token::I32(2),
Token::MapEnd, Token::MapEnd,
], ],
btreemap![1 => 2, 3 => 4] => &[ btreemap![1 => 2, 3 => 4] => vec![
Token::MapStart(Some(2)), Token::MapStart(Some(2)),
Token::MapSep, Token::MapSep,
Token::I32(1), Token::I32(1),
@@ -183,7 +459,7 @@ declare_ser_tests! {
Token::I32(4), Token::I32(4),
Token::MapEnd, Token::MapEnd,
], ],
btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => &[ btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![
Token::MapStart(Some(2)), Token::MapStart(Some(2)),
Token::MapSep, Token::MapSep,
Token::I32(1), Token::I32(1),
@@ -204,126 +480,61 @@ declare_ser_tests! {
Token::MapEnd, Token::MapEnd,
], ],
} }
test_unit_struct { test_named_unit {
UnitStruct => &[Token::UnitStruct("UnitStruct")], NamedUnit => vec![Token::NamedUnit("NamedUnit")],
} }
test_tuple_struct { test_named_seq {
TupleStruct(1, 2, 3) => &[ NamedSeq(1, 2, 3) => vec![
Token::TupleStructStart("TupleStruct", Some(3)), Token::NamedSeqStart("NamedSeq", Some(3)),
Token::TupleStructSep, Token::SeqSep,
Token::I32(1), Token::I32(1),
Token::TupleStructSep, Token::SeqSep,
Token::I32(2), Token::I32(2),
Token::TupleStructSep, Token::SeqSep,
Token::I32(3), Token::I32(3),
Token::TupleStructEnd,
],
}
test_struct {
Struct { a: 1, b: 2, c: 3 } => &[
Token::StructStart("Struct", Some(3)),
Token::StructSep,
Token::Str("a"),
Token::I32(1),
Token::StructSep,
Token::Str("b"),
Token::I32(2),
Token::StructSep,
Token::Str("c"),
Token::I32(3),
Token::StructEnd,
],
}
test_enum {
Enum::Unit => &[Token::EnumUnit("Enum", "Unit")],
Enum::One(42) => &[Token::EnumNewType("Enum", "One"), Token::I32(42)],
Enum::Seq(1, 2) => &[
Token::EnumSeqStart("Enum", "Seq", Some(2)),
Token::EnumSeqSep,
Token::I32(1),
Token::EnumSeqSep,
Token::I32(2),
Token::EnumSeqEnd,
],
Enum::Map { a: 1, b: 2 } => &[
Token::EnumMapStart("Enum", "Map", Some(2)),
Token::EnumMapSep,
Token::Str("a"),
Token::I32(1),
Token::EnumMapSep,
Token::Str("b"),
Token::I32(2),
Token::EnumMapEnd,
],
}
test_box {
Box::new(0i32) => &[Token::I32(0)],
}
test_boxed_slice {
Box::new([0, 1, 2]) => &[
Token::SeqArrayStart(3),
Token::SeqSep,
Token::I32(0),
Token::SeqSep,
Token::I32(1),
Token::SeqSep,
Token::I32(2),
Token::SeqEnd, Token::SeqEnd,
], ],
} }
test_net_ipv4addr { test_named_map {
"1.2.3.4".parse::<net::Ipv4Addr>().unwrap() => &[Token::Str("1.2.3.4")], NamedMap { a: 1, b: 2, c: 3 } => vec![
} Token::NamedMapStart("NamedMap", Some(3)),
test_net_ipv6addr { Token::MapSep,
"::1".parse::<net::Ipv6Addr>().unwrap() => &[Token::Str("::1")], Token::Str("a"),
} Token::I32(1),
test_net_socketaddr {
"1.2.3.4:1234".parse::<net::SocketAddr>().unwrap() => &[Token::Str("1.2.3.4:1234")], Token::MapSep,
"1.2.3.4:1234".parse::<net::SocketAddrV4>().unwrap() => &[Token::Str("1.2.3.4:1234")], Token::Str("b"),
"[::1]:1234".parse::<net::SocketAddrV6>().unwrap() => &[Token::Str("[::1]:1234")], Token::I32(2),
}
test_path { Token::MapSep,
Path::new("/usr/local/lib") => &[ Token::Str("c"),
Token::Str("/usr/local/lib"), Token::I32(3),
Token::MapEnd,
], ],
} }
test_path_buf { test_enum {
PathBuf::from("/usr/local/lib") => &[ Enum::Unit => vec![Token::EnumUnit("Enum", "Unit")],
Token::Str("/usr/local/lib"), Enum::Seq(1, 2) => vec![
Token::EnumSeqStart("Enum", "Seq", Some(2)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep,
Token::I32(2),
Token::SeqEnd,
],
Enum::Map { a: 1, b: 2 } => vec![
Token::EnumMapStart("Enum", "Map", Some(2)),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapEnd,
], ],
} }
} }
#[cfg(feature = "nightly")]
#[test]
fn test_net_ipaddr() {
assert_ser_tokens(
"1.2.3.4".parse::<net::IpAddr>().unwrap(),
&[Token::Str("1.2.3.4")],
);
}
#[test]
fn test_cannot_serialize_paths() {
let path = unsafe {
str::from_utf8_unchecked(b"Hello \xF0\x90\x80World")
};
token::assert_ser_tokens_error(
&Path::new(path),
&[Token::Str("Hello World")],
token::Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
let mut path_buf = PathBuf::new();
path_buf.push(path);
token::assert_ser_tokens_error(
&path_buf,
&[Token::Str("Hello World")],
token::Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
}
File diff suppressed because it is too large Load Diff