Compare commits

...

71 Commits

Author SHA1 Message Date
Erick Tryzelaar 45bd239202 Release 0.3.0 2015-03-31 13:01:17 -07:00
Erick Tryzelaar 54009e0991 Factor out value deserializers 2015-03-31 12:56:17 -07:00
Erick Tryzelaar bfe7a04c4d Update the location of json errors coming from "Deserialize" 2015-03-30 19:50:41 -07:00
Erick Tryzelaar 3167da72d8 Minor whitespace cleanup 2015-03-28 15:40:56 -07:00
Erick Tryzelaar 0d725a63b0 Add some serialization docs 2015-03-26 08:11:43 -07:00
Erick Tryzelaar ee0cd4aba9 Pull the serialization impls into their own file 2015-03-26 08:05:29 -07:00
Erick Tryzelaar 1b1c605102 Pull deserialization impls into their own file 2015-03-26 07:58:26 -07:00
Erick Tryzelaar 44edfa5974 Add {,de}serializer for VecMap 2015-03-26 07:45:22 -07:00
Erick Tryzelaar aa8d13456a Add bytes type to enable {,de}serializing to a byte array 2015-03-25 23:03:01 -07:00
Erick Tryzelaar 4beb86ab7e Update to rust HEAD 2015-03-25 10:43:25 -07:00
Erick Tryzelaar c369010d3d Allow json::de to work with io::Read 2015-03-24 08:55:20 -07:00
Erick Tryzelaar 1618faed63 Add deserialization impls for {BTree,Hash}{Map,Set} 2015-03-23 19:02:20 -07:00
Erick Tryzelaar 9059b734aa Merge pull request #46 from oli-obk/no_rustc_serialize_propagation
require rustc-serialize only in tests and benchmarks
2015-03-23 17:59:55 -07:00
Erick Tryzelaar 89f463111e Merge pull request #42 from Byron/master
fix(macros): fully qualified usage of `Result`
2015-03-23 09:59:55 -07:00
Sebastian Thiel 2962287703 fix(macros): fully qualified usage of Result
Otherwise it was possible for the expanded macro to pickup a
user-defined `Result` type, which didn't fulfill the required type
bounds and cause compilation failure.
2015-03-23 17:04:23 +01:00
Oliver 'ker' Schneider aa3c55fd98 require rustc-serialize only in tests and benchmarks 2015-03-22 14:16:58 +01:00
Erick Tryzelaar 17c295680e Remove an unused variable 2015-03-20 08:47:48 -07:00
Erick Tryzelaar 09de237033 Allow Vecs, BTreeMaps, and HashMaps to be deserialized from a unit
Closes #36
2015-03-20 08:47:33 -07:00
Erick Tryzelaar d17846eff1 Add deserializer type hinting hooks
Formats like xml have trouble knowing if they should deserialize
tags into a sequence from the stream they are deserializing from.
This PR adds hooks so the deserializee can inform the deserializer
to provide them a sequence if possible.

Closes #38.
2015-03-20 08:32:33 -07:00
Erick Tryzelaar 5378d22708 Switch to the new custom_deserialize syntax 2015-03-19 20:19:49 -07:00
Erick Tryzelaar c8b2ad01b5 Update to rust HEAD 2015-03-19 20:19:49 -07:00
Erick Tryzelaar e778c7e25c Update to rust HEAD 2015-03-19 20:19:48 -07:00
Erick Tryzelaar f0d0dd2982 Merge pull request #41 from hugoduncan/feature/mark-field-attributes-used
Mark serde field attributes as used
2015-03-19 20:08:50 -07:00
Hugo Duncan 3e63d34c00 Mark serde field attributes as used
Prevents unused attribute warnings in code that marks fields with
field level #[serde] attributes.
2015-03-19 11:04:08 -04:00
Erick Tryzelaar 8821421357 Docs, json::Value::U64, and bring many of the rust-serialize fns to Value 2015-03-18 20:51:48 -07:00
Erick Tryzelaar eb4af09456 Simplify the variant deserializer visitor 2015-03-18 07:35:05 -07:00
Erick Tryzelaar 78137ee3a4 Rewrite enum deserialization to not require allocations 2015-03-16 22:42:04 -07:00
Erick Tryzelaar b40d8f7bac Remove the first argument from visit_{seq,map}_elt 2015-03-16 22:30:02 -07:00
Erick Tryzelaar a6ba251ef9 Enable a missing field test 2015-03-16 21:23:20 -07:00
Erick Tryzelaar c6cc2340c8 Rename a variable 2015-03-16 21:11:30 -07:00
Erick Tryzelaar a212ef11a9 Fix compiling bench_struct 2015-03-16 21:10:16 -07:00
Erick Tryzelaar 7bd4c6963b Merge pull request #37 from oli-obk/fix_seq_map_end
MapVisitor::end and SeqVisitor::end were mostly never called
2015-03-16 20:54:35 -07:00
Oliver Schneider f21cbb71e2 MapVisitor::end and SeqVisitor::end were mostly never called 2015-03-16 13:27:00 +01:00
Erick Tryzelaar f4f8194f46 More cleanup 2015-03-15 18:38:52 -07:00
Erick Tryzelaar 90e02206fe Cleanup, and move default::Default #[derive_deserialize] support to get called when missing 2015-03-15 18:37:26 -07:00
Erick Tryzelaar 9fc9d1b33a Get rid of syntax::ext::generic from #[derive_deserialize] 2015-03-15 17:47:25 -07:00
Erick Tryzelaar b9f5d22630 Spring cleaning 2015-03-15 15:31:31 -07:00
Erick Tryzelaar cbafc83af4 Cleanup palooza 2015-03-15 15:14:57 -07:00
Erick Tryzelaar b628446768 Cleanup train 2015-03-15 15:04:11 -07:00
Erick Tryzelaar aacc14ad7b More cleanup 2015-03-15 14:50:00 -07:00
Erick Tryzelaar 35eb234c41 More aster driven cleanup 2015-03-15 14:31:05 -07:00
Erick Tryzelaar 989c8ff809 Include running the benchmarks in travis 2015-03-15 13:12:21 -07:00
Erick Tryzelaar 49c2585a20 Try to fix travis 2015-03-15 13:08:08 -07:00
Erick Tryzelaar 9972478066 Fix #35 by not relying on the crate being import in the current module 2015-03-15 13:02:34 -07:00
Erick Tryzelaar 00287bd055 Cleanup 2015-03-14 21:47:23 -07:00
Erick Tryzelaar 11f47bd51f Minor cleanup 2015-03-14 15:20:00 -07:00
Erick Tryzelaar 5e98a83717 Remove redundant bounds 2015-03-14 15:03:41 -07:00
Erick Tryzelaar ec8b7c9b89 Update to rust HEAD 2015-03-14 14:57:13 -07:00
Erick Tryzelaar 008ce75ae5 Replace #[derive_serialize] syntax::ext::deriving::generic with aster 2015-03-14 14:57:05 -07:00
Erick Tryzelaar 5c62b7ed06 Split serde_macros into multiple files 2015-03-14 13:09:37 -07:00
Erick Tryzelaar 99f4efd313 Merge #[derive_serialize] for structs and struct variants 2015-03-14 12:53:53 -07:00
Erick Tryzelaar 87ff636c10 Fix some warnings 2015-03-14 12:03:53 -07:00
Erick Tryzelaar d2bd361d9c Merge #[derive_serialize] backend for serializing tuple structs and variants 2015-03-14 12:02:21 -07:00
Erick Tryzelaar 5a32d420cd More cleanup 2015-03-14 00:47:10 -07:00
Erick Tryzelaar a3b2f00c92 More cleanup 2015-03-14 00:08:23 -07:00
Erick Tryzelaar 13fcf1ad5b More cleanup 2015-03-14 00:04:25 -07:00
Erick Tryzelaar 8cb2ff6e2e Fix multiple unnamed enum seq/map variants
Closes #32.
2015-03-13 23:44:18 -07:00
Erick Tryzelaar c917941ec3 More cleanup 2015-03-13 23:43:21 -07:00
Erick Tryzelaar f699d29fb3 More cleanup 2015-03-13 23:38:12 -07:00
Erick Tryzelaar 6723097a3f More cleanup 2015-03-13 23:26:38 -07:00
Erick Tryzelaar 80e27344f1 More cleanup 2015-03-13 23:17:44 -07:00
Erick Tryzelaar f244e0f522 More cleanup 2015-03-13 23:11:05 -07:00
Erick Tryzelaar 61317f5935 Replace some aster with quasi in serde_macros 2015-03-13 22:46:21 -07:00
Erick Tryzelaar 9ca1e2a8f7 Bump aster and quasi 2015-03-13 19:37:01 -07:00
Erick Tryzelaar aedd5f57cf Split json compact and pretty serializer. Recover 20MB/s 2015-03-12 21:15:47 -07:00
Erick Tryzelaar dc87288f48 Allow json missing fields to be treated as a null
Closes #34.
2015-03-12 20:44:16 -07:00
Erick Tryzelaar 5dd53e7ea3 Change ser::{Seq,Map}Visitor to return an optional exact length
This is necessary for formats that serialize the length in the
format stream. Those formats need the exact length, so the
iterator-style size_hint has the wrong semantics.
2015-03-12 19:40:46 -07:00
Erick Tryzelaar 9e454a243a Rename Serialize::visit to Serialize::serialize 2015-03-12 07:33:34 -07:00
Erick Tryzelaar 3f62b6d2bf Merge ser::Serializer and ser::Visitor 2015-03-11 11:05:46 -07:00
Erick Tryzelaar fbd6d1974a Remove the unused Serializer::Value associated type 2015-03-11 10:15:27 -07:00
Erick Tryzelaar 5d22be26d8 Fixed the description 2015-03-08 23:12:33 -07:00
31 changed files with 5433 additions and 3408 deletions
+14 -11
View File
@@ -1,13 +1,16 @@
language: rust
rust:
- nightly
script:
- cargo build --verbose
- cargo test --verbose
- cargo bench --verbose
- cd serde2
- cargo build --verbose
- cargo test --verbose
- cargo bench --verbose
- cargo test
- cargo bench
- cargo doc
after_success: |
[ $TRAVIS_BRANCH = "master" ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
cargo doc &&
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
env:
global:
secure: HO41LMpMXkF2In9+1sxWVu7fgolL+y9+4Q5PI6wZX2L5pDwpPJCjxaQarQXCEnoIxED1PlP03JuF7ULNz0zw1ylYhAOfOSdkxFZRnE2wMZqq6qvXBHwyMiDrAociIzoPKSGv7JVrKPsjsnd+96K6xxueIodQZrmAdyq7N/M82Mc=
+8 -10
View File
@@ -1,16 +1,14 @@
[package]
name = "serde"
version = "0.2.0"
version = "0.3.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A quasi-quoting macro system"
repository = "https://github.com/erickt/rust-quasi"
[lib]
name = "serde"
[dependencies]
rustc-serialize = "*"
description = "A serialization/deserialization framework"
repository = "https://github.com/erickt/rust-serde"
[dev-dependencies]
serde_macros = "0.2.0"
rustc-serialize = "*"
[dev-dependencies.serde_macros]
path = "serde_macros/"
version = "0.3.0"
+61 -24
View File
@@ -2,7 +2,7 @@
#![plugin(serde_macros)]
extern crate serde;
extern crate "rustc-serialize" as rustc_serialize;
extern crate rustc_serialize;
extern crate test;
use test::Bencher;
@@ -15,9 +15,8 @@ use Animal::{Dog, Frog};
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug, RustcDecodable)]
#[derive_deserialize]
enum Animal {
#[derive(Clone, PartialEq, Debug, RustcDecodable, Deserialize)]
pub enum Animal {
Dog,
Frog(String, isize)
}
@@ -245,9 +244,11 @@ mod deserializer {
use serde::de;
#[derive(Debug)]
enum State {
AnimalState(Animal),
IsizeState(isize),
StrState(&'static str),
StringState(String),
UnitState,
}
@@ -273,29 +274,51 @@ mod deserializer {
where V: de::Visitor,
{
match self.stack.pop() {
Some(State::AnimalState(Animal::Dog)) => {
self.stack.push(State::UnitState);
visitor.visit_enum("Animal", "Dog", DogVisitor {
de: self,
})
}
Some(State::AnimalState(Animal::Frog(x0, x1))) => {
self.stack.push(State::IsizeState(x1));
self.stack.push(State::StringState(x0));
visitor.visit_enum("Animal", "Frog", FrogVisitor {
de: self,
state: 0,
})
}
Some(State::IsizeState(value)) => {
visitor.visit_isize(value)
}
Some(State::StringState(value)) => {
visitor.visit_string(value)
}
Some(State::StrState(value)) => {
visitor.visit_str(value)
}
Some(State::UnitState) => {
visitor.visit_unit()
}
Some(_) => {
Err(Error::SyntaxError)
}
None => {
Err(Error::EndOfStreamError)
}
}
}
#[inline]
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
match self.stack.pop() {
Some(State::AnimalState(Animal::Dog)) => {
self.stack.push(State::UnitState);
self.stack.push(State::StrState("Dog"));
visitor.visit(DogVisitor {
de: self,
})
}
Some(State::AnimalState(Animal::Frog(x0, x1))) => {
self.stack.push(State::IsizeState(x1));
self.stack.push(State::StringState(x0));
self.stack.push(State::StrState("Frog"));
visitor.visit(FrogVisitor {
de: self,
state: 0,
})
}
Some(_) => {
Err(Error::SyntaxError)
}
None => {
Err(Error::EndOfStreamError)
}
@@ -307,12 +330,20 @@ mod deserializer {
de: &'a mut AnimalDeserializer,
}
impl<'a> de::EnumVisitor for DogVisitor<'a> {
impl<'a> de::VariantVisitor for DogVisitor<'a> {
type Error = Error;
fn visit_unit(&mut self) -> Result<(), Error> {
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize
{
de::Deserialize::deserialize(self.de)
}
fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self.de, visitor)
}
}
struct FrogVisitor<'a> {
@@ -320,13 +351,19 @@ mod deserializer {
state: usize,
}
impl<'a> de::EnumVisitor for FrogVisitor<'a> {
impl<'a> de::VariantVisitor for FrogVisitor<'a> {
type Error = Error;
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize
{
visitor.visit(self)
de::Deserialize::deserialize(self.de)
}
fn visit_value<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_seq(self)
}
}
+47 -53
View File
@@ -1,12 +1,12 @@
#![feature(custom_derive, collections, core, io, plugin, test)]
#![feature(custom_derive, collections, core, plugin, test)]
#![allow(non_camel_case_types)]
#![plugin(serde_macros)]
extern crate serde;
extern crate "rustc-serialize" as rustc_serialize;
extern crate rustc_serialize;
extern crate test;
use std::io::{self, ReadExt, WriteExt};
use std::io::{self, Read, Write};
use std::num::FromPrimitive;
use test::Bencher;
@@ -17,9 +17,7 @@ use serde::ser::{self, Serialize, Serializer};
use rustc_serialize::Encodable;
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
struct Http {
protocol: HttpProtocol,
status: u32,
@@ -56,10 +54,10 @@ impl rustc_serialize::Decodable for HttpProtocol {
impl ser::Serialize for HttpProtocol {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -68,7 +66,7 @@ impl de::Deserialize for HttpProtocol {
fn deserialize<
S: Deserializer,
>(state: &mut S) -> Result<HttpProtocol, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
@@ -104,10 +102,10 @@ impl rustc_serialize::Decodable for HttpMethod {
impl ser::Serialize for HttpMethod {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -116,7 +114,7 @@ impl de::Deserialize for HttpMethod {
fn deserialize<
S: de::Deserializer,
>(state: &mut S) -> Result<HttpMethod, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
@@ -145,10 +143,10 @@ impl rustc_serialize::Decodable for CacheStatus {
impl ser::Serialize for CacheStatus {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -157,13 +155,11 @@ impl de::Deserialize for CacheStatus {
fn deserialize<
S: de::Deserializer,
>(state: &mut S) -> Result<CacheStatus, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
struct Origin {
ip: String,
port: u32,
@@ -195,10 +191,10 @@ impl rustc_serialize::Decodable for OriginProtocol {
impl ser::Serialize for OriginProtocol {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -207,7 +203,7 @@ impl de::Deserialize for OriginProtocol {
fn deserialize<
S: de::Deserializer,
>(state: &mut S) -> Result<OriginProtocol, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
@@ -237,10 +233,10 @@ impl rustc_serialize::Decodable for ZonePlan {
impl ser::Serialize for ZonePlan {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -249,7 +245,7 @@ impl de::Deserialize for ZonePlan {
fn deserialize<
S: de::Deserializer,
>(state: &mut S) -> Result<ZonePlan, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
@@ -530,10 +526,10 @@ impl rustc_serialize::Decodable for Country {
impl ser::Serialize for Country {
#[inline]
fn visit<
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_u8(*self as u8)
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
serializer.visit_u8(*self as u8)
}
}
@@ -542,13 +538,11 @@ impl de::Deserialize for Country {
fn deserialize<
S: de::Deserializer,
>(state: &mut S) -> Result<Country, S::Error> {
state.visit(de::PrimitiveVisitor::new())
state.visit(de::impls::PrimitiveVisitor::new())
}
}
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
struct Log {
timestamp: i64,
zone_id: u32,
@@ -637,7 +631,7 @@ impl MyMemWriter0 {
}
impl io::Write for MyMemWriter0 {
impl Write for MyMemWriter0 {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.buf.push_all(buf);
@@ -682,7 +676,7 @@ fn push_all_bytes(dst: &mut Vec<u8>, src: &[u8]) {
}
}
impl io::Write for MyMemWriter1 {
impl Write for MyMemWriter1 {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
push_all_bytes(&mut self.buf, buf);
@@ -757,7 +751,7 @@ fn test_serializer_vec() {
let log = Log::new();
let wr = Vec::with_capacity(1024);
let mut serializer = json::Serializer::new(wr);
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let json = serializer.into_inner();
assert_eq!(&json, &JSON_STR.as_bytes());
@@ -775,7 +769,7 @@ fn bench_serializer_vec(b: &mut Bencher) {
wr.clear();
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
}
@@ -793,7 +787,7 @@ fn bench_serializer_slice(b: &mut Bencher) {
let mut wr = &mut buf[..];
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
}
@@ -806,7 +800,7 @@ fn test_serializer_my_mem_writer0() {
{
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
}
@@ -825,7 +819,7 @@ fn bench_serializer_my_mem_writer0(b: &mut Bencher) {
wr.buf.clear();
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
}
@@ -838,7 +832,7 @@ fn test_serializer_my_mem_writer1() {
{
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
}
@@ -857,7 +851,7 @@ fn bench_serializer_my_mem_writer1(b: &mut Bencher) {
wr.buf.clear();
let mut serializer = json::Serializer::new(wr.by_ref());
serializer.visit(&log).unwrap();
log.serialize(&mut serializer).unwrap();
let _json = serializer.into_inner();
});
}
@@ -872,7 +866,7 @@ fn bench_copy(b: &mut Bencher) {
});
}
fn manual_serialize_no_escape<W: io::Write>(wr: &mut W, log: &Log) {
fn manual_serialize_no_escape<W: Write>(wr: &mut W, log: &Log) {
wr.write(b"{\"timestamp\":").unwrap();
(write!(wr, "{}", log.timestamp)).unwrap();
wr.write(b",\"zone_id\":").unwrap();
@@ -929,7 +923,7 @@ fn manual_serialize_no_escape<W: io::Write>(wr: &mut W, log: &Log) {
wr.write(b"}").unwrap();
}
fn manual_serialize_escape<W: io::Write>(wr: &mut W, log: &Log) {
fn manual_serialize_escape<W: Write>(wr: &mut W, log: &Log) {
wr.write_all(b"{").unwrap();
escape_str(wr, "timestamp").unwrap();
wr.write_all(b":").unwrap();
+6 -6
View File
@@ -1,8 +1,8 @@
#![feature(custom_derive, core, plugin, test)]
#![feature(custom_derive, plugin, test)]
#![plugin(serde_macros)]
extern crate serde;
extern crate "rustc-serialize" as rustc_serialize;
extern crate rustc_serialize;
extern crate test;
use std::fmt::Debug;
@@ -403,7 +403,7 @@ fn bench_decoder_000(b: &mut Bencher) {
fn bench_decoder_003(b: &mut Bencher) {
b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new();
for i in range(0, 3) {
for i in (0 .. 3) {
m.insert(i.to_string(), i);
}
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
@@ -414,7 +414,7 @@ fn bench_decoder_003(b: &mut Bencher) {
fn bench_decoder_100(b: &mut Bencher) {
b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new();
for i in range(0, 100) {
for i in (0 .. 100) {
m.insert(i.to_string(), i);
}
run_decoder(decoder::IsizeDecoder::new(m.clone()), m)
@@ -443,7 +443,7 @@ fn bench_deserializer_000(b: &mut Bencher) {
fn bench_deserializer_003(b: &mut Bencher) {
b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new();
for i in range(0, 3) {
for i in (0 .. 3) {
m.insert(i.to_string(), i);
}
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
@@ -454,7 +454,7 @@ fn bench_deserializer_003(b: &mut Bencher) {
fn bench_deserializer_100(b: &mut Bencher) {
b.iter(|| {
let mut m: HashMap<String, isize> = HashMap::new();
for i in range(0, 100) {
for i in (0 .. 100) {
m.insert(i.to_string(), i);
}
run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m)
+62 -45
View File
@@ -2,7 +2,7 @@
#![plugin(serde_macros)]
extern crate serde;
extern crate "rustc-serialize" as rustc_serialize;
extern crate rustc_serialize;
extern crate test;
use std::collections::HashMap;
@@ -14,9 +14,8 @@ use serde::de::{Deserializer, Deserialize};
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug, RustcDecodable)]
#[derive_deserialize]
struct Inner {
#[derive(Clone, PartialEq, Debug, RustcDecodable, Deserialize)]
pub struct Inner {
a: (),
b: usize,
c: HashMap<String, Option<char>>,
@@ -24,15 +23,14 @@ struct Inner {
//////////////////////////////////////////////////////////////////////////////
#[derive(Clone, PartialEq, Debug, RustcDecodable)]
#[derive_deserialize]
struct Outer {
#[derive(Clone, PartialEq, Debug, RustcDecodable, Deserialize)]
pub struct Outer {
inner: Vec<Inner>,
}
//////////////////////////////////////////////////////////////////////////////
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub enum Error {
EndOfStream,
SyntaxError,
@@ -368,30 +366,6 @@ mod deserializer {
where V: de::Visitor,
{
match self.stack.pop() {
Some(State::OuterState(Outer { inner })) => {
self.stack.push(State::VecState(inner));
self.stack.push(State::StrState("inner"));
visitor.visit_named_map("Outer", OuterMapVisitor {
de: self,
state: 0,
})
}
Some(State::InnerState(Inner { a: (), b, c })) => {
self.stack.push(State::MapState(c));
self.stack.push(State::StrState("c"));
self.stack.push(State::UsizeState(b));
self.stack.push(State::StrState("b"));
self.stack.push(State::NullState);
self.stack.push(State::StrState("a"));
visitor.visit_named_map("Inner", InnerMapVisitor {
de: self,
state: 0,
})
}
Some(State::VecState(value)) => {
visitor.visit_seq(OuterSeqVisitor {
de: self,
@@ -425,9 +399,52 @@ mod deserializer {
Some(State::OptionState(true)) => {
visitor.visit_some(self)
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStream),
}
}
fn visit_named_map<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.stack.pop() {
Some(State::OuterState(Outer { inner })) => {
if name != "Outer" {
return Err(Error::SyntaxError);
}
self.stack.push(State::VecState(inner));
self.stack.push(State::StrState("inner"));
visitor.visit_map(OuterMapVisitor {
de: self,
state: 0,
})
}
Some(State::InnerState(Inner { a: (), b, c })) => {
if name != "Inner" {
return Err(Error::SyntaxError);
}
self.stack.push(State::MapState(c));
self.stack.push(State::StrState("c"));
self.stack.push(State::UsizeState(b));
self.stack.push(State::StrState("b"));
self.stack.push(State::NullState);
self.stack.push(State::StrState("a"));
visitor.visit_map(InnerMapVisitor {
de: self,
state: 0,
})
}
_ => {
Err(Error::SyntaxError)
}
}
}
}
struct OuterMapVisitor<'a> {
@@ -535,7 +552,7 @@ mod deserializer {
}
fn end(&mut self) -> Result<(), Error> {
if self.state == 1 {
if self.state == 3 {
Ok(())
} else {
Err(Error::SyntaxError)
@@ -607,9 +624,9 @@ fn bench_decoder_0_0(b: &mut Bencher) {
};
let mut d = decoder::OuterDecoder::new(outer.clone());
let value: Outer = Decodable::decode(&mut d).unwrap();
let value: Result<Outer, Error> = Decodable::decode(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -629,9 +646,9 @@ fn bench_decoder_1_0(b: &mut Bencher) {
};
let mut d = decoder::OuterDecoder::new(outer.clone());
let value: Outer = Decodable::decode(&mut d).unwrap();
let value: Result<Outer, Error> = Decodable::decode(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -656,9 +673,9 @@ fn bench_decoder_1_5(b: &mut Bencher) {
};
let mut d = decoder::OuterDecoder::new(outer.clone());
let value: Outer = Decodable::decode(&mut d).unwrap();
let value: Result<Outer, Error> = Decodable::decode(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -670,9 +687,9 @@ fn bench_deserializer_0_0(b: &mut Bencher) {
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserialize::deserialize(&mut d).unwrap();
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -692,9 +709,9 @@ fn bench_deserializer_1_0(b: &mut Bencher) {
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserialize::deserialize(&mut d).unwrap();
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -719,8 +736,8 @@ fn bench_deserializer_1_5(b: &mut Bencher) {
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserialize::deserialize(&mut d).unwrap();
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
+6 -6
View File
@@ -1,8 +1,8 @@
#![feature(core, plugin, test)]
#![feature(plugin, test)]
#![plugin(serde_macros)]
extern crate serde;
extern crate "rustc-serialize" as rustc_serialize;
extern crate rustc_serialize;
extern crate test;
use std::fmt::Debug;
@@ -537,7 +537,7 @@ fn bench_decoder_usize_003(b: &mut Bencher) {
#[bench]
fn bench_decoder_usize_100(b: &mut Bencher) {
b.iter(|| {
let v: Vec<usize> = range(0, 100).collect();
let v: Vec<usize> = (0 .. 100).collect();
run_decoder(decoder::UsizeDecoder::new(v.clone()), v)
})
}
@@ -561,7 +561,7 @@ fn bench_decoder_u8_003(b: &mut Bencher) {
#[bench]
fn bench_decoder_u8_100(b: &mut Bencher) {
b.iter(|| {
let v: Vec<u8> = range(0u8, 100).collect();
let v: Vec<u8> = (0 .. 100).collect();
run_decoder(decoder::U8Decoder::new(v.clone()), v)
})
}
@@ -585,7 +585,7 @@ fn bench_deserializer_usize_003(b: &mut Bencher) {
#[bench]
fn bench_deserializer_usize_100(b: &mut Bencher) {
b.iter(|| {
let v: Vec<usize> = range(0, 100).collect();
let v: Vec<usize> = (0 .. 100).collect();
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
})
}
@@ -609,7 +609,7 @@ fn bench_deserializer_u8_003(b: &mut Bencher) {
#[bench]
fn bench_deserializer_u8_100(b: &mut Bencher) {
b.iter(|| {
let v: Vec<u8> = range(0u8, 100).collect();
let v: Vec<u8> = (0 .. 100).collect();
run_deserializer(deserializer::Deserializer::new(v.clone()), v)
})
}
+6 -6
View File
@@ -1,16 +1,16 @@
[package]
name = "serde_macros"
version = "0.2.0"
version = "0.3.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A quasi-quoting macro system"
repository = "https://github.com/erickt/rust-quasi"
description = "Macros to auto-generate implementations for the serde framework"
repository = "https://github.com/erickt/rust-serde"
[lib]
name = "serde_macros"
plugin = true
[dependencies]
quasi = "0.1.3"
quasi_macros = "0.1.3"
aster = "0.1.3"
aster = "*"
quasi = "*"
quasi_macros = "*"
+693
View File
@@ -0,0 +1,693 @@
use syntax::ast::{
Ident,
MetaItem,
Item,
Expr,
StructDef,
EnumDef,
};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::ExtCtxt;
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
use aster;
use field;
pub fn expand_derive_deserialize(
cx: &mut ExtCtxt,
span: Span,
_mitem: &MetaItem,
item: &Item,
push: &mut FnMut(P<ast::Item>)
) {
let builder = aster::AstBuilder::new().span(span);
let generics = match item.node {
ast::ItemStruct(_, ref generics) => generics,
ast::ItemEnum(_, ref generics) => generics,
_ => cx.bug("expected ItemStruct or ItemEnum in #[derive(Deserialize)]")
};
let impl_generics = builder.from_generics(generics.clone())
.add_ty_param_bound(
builder.path().global().ids(&["serde", "de", "Deserialize"]).build()
)
.build();
let ty = builder.ty().path()
.segment(item.ident).with_generics(impl_generics.clone()).build()
.build();
let body = deserialize_body(
cx,
&builder,
item,
&impl_generics,
ty.clone(),
);
let where_clause = &impl_generics.where_clause;
let impl_item = quote_item!(cx,
#[automatically_derived]
impl $impl_generics ::serde::de::Deserialize for $ty $where_clause {
fn deserialize<__D>(deserializer: &mut __D) -> ::std::result::Result<$ty, __D::Error>
where __D: ::serde::de::Deserializer,
{
$body
}
}
).unwrap();
push(impl_item)
}
fn deserialize_body(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &Item,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
) -> P<ast::Expr> {
match item.node {
ast::ItemStruct(ref struct_def, _) => {
deserialize_item_struct(
cx,
builder,
item,
impl_generics,
ty,
struct_def,
)
}
ast::ItemEnum(ref enum_def, _) => {
deserialize_item_enum(
cx,
builder,
item.ident,
impl_generics,
ty,
enum_def,
)
}
_ => cx.bug("expected ItemStruct or ItemEnum in #[derive(Deserialize)]")
}
}
fn deserialize_item_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &Item,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
struct_def: &ast::StructDef,
) -> P<ast::Expr> {
let mut named_fields = vec![];
let mut unnamed_fields = 0;
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) => {
deserialize_unit_struct(
cx,
&builder,
item.ident,
)
}
(true, false) => {
deserialize_tuple_struct(
cx,
&builder,
item.ident,
impl_generics,
ty,
unnamed_fields,
)
}
(false, true) => {
deserialize_struct(
cx,
&builder,
item.ident,
impl_generics,
ty,
struct_def,
)
}
(false, false) => {
cx.bug("struct has named and unnamed fields")
}
}
}
// Build `__Visitor<A, B, ...>(PhantomData<A>, PhantomData<B>, ...)`
fn deserialize_visitor(
builder: &aster::AstBuilder,
trait_generics: &ast::Generics,
) -> (P<ast::Item>, P<ast::Ty>, P<ast::Expr>) {
if trait_generics.ty_params.is_empty() {
(
builder.item().tuple_struct("__Visitor").build(),
builder.ty().id("__Visitor"),
builder.expr().id("__Visitor"),
)
} else {
(
builder.item().tuple_struct("__Visitor")
.generics().with(trait_generics.clone()).build()
.with_tys(
trait_generics.ty_params.iter().map(|ty_param| {
builder.ty().phantom_data().id(ty_param.ident)
})
)
.build(),
builder.ty().path()
.segment("__Visitor").with_generics(trait_generics.clone()).build()
.build(),
builder.expr().call().id("__Visitor")
.with_args(
trait_generics.ty_params.iter().map(|_| {
builder.expr().phantom_data()
})
)
.build(),
)
}
}
fn deserialize_unit_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
) -> P<ast::Expr> {
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, {
struct __Visitor;
impl ::serde::de::Visitor for __Visitor {
type Value = $type_ident;
#[inline]
fn visit_unit<E>(&mut self) -> ::std::result::Result<$type_ident, E>
where E: ::serde::de::Error,
{
Ok($type_ident)
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> ::std::result::Result<$type_ident, V::Error>
where V: ::serde::de::SeqVisitor,
{
try!(visitor.end());
self.visit_unit()
}
}
deserializer.visit_named_unit($type_name, __Visitor)
})
}
fn deserialize_tuple_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
fields: usize,
) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause;
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
builder,
impl_generics,
);
let visit_seq_expr = deserialize_seq(
cx,
builder,
builder.path().id(type_ident).build(),
fields,
);
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, {
$visitor_item
impl $impl_generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
fn visit_seq<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::SeqVisitor,
{
$visit_seq_expr
}
}
deserializer.visit_named_seq($type_name, $visitor_expr)
})
}
fn deserialize_seq(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
struct_path: ast::Path,
fields: usize,
) -> P<ast::Expr> {
let let_values: Vec<P<ast::Stmt>> = (0 .. fields)
.map(|i| {
let name = builder.id(format!("__field{}", i));
quote_stmt!(cx,
let $name = match try!(visitor.visit()) {
Some(value) => value,
None => {
return Err(::serde::de::Error::end_of_stream_error());
}
};
).unwrap()
})
.collect();
let result = builder.expr().call()
.build_path(struct_path)
.with_args((0 .. fields).map(|i| builder.expr().id(format!("__field{}", i))))
.build();
quote_expr!(cx, {
$let_values
try!(visitor.end());
Ok($result)
})
}
fn deserialize_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
struct_def: &StructDef,
) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause;
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
builder,
impl_generics,
);
let (field_visitor, visit_map_expr) = deserialize_struct_visitor(
cx,
builder,
struct_def,
builder.path().id(type_ident).build(),
);
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, {
$field_visitor
$visitor_item
impl $impl_generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
#[inline]
fn visit_map<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::MapVisitor,
{
$visit_map_expr
}
}
deserializer.visit_named_map($type_name, $visitor_expr)
})
}
fn deserialize_item_enum(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
enum_def: &EnumDef,
) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause;
let type_name = builder.expr().str(type_ident);
let variant_visitor = deserialize_field_visitor(
cx,
builder,
enum_def.variants.iter()
.map(|variant| builder.expr().str(variant.node.name))
.collect()
);
// Match arms to extract a variant from a string
let variant_arms: Vec<_> = enum_def.variants.iter()
.enumerate()
.map(|(i, variant)| {
let variant_name = builder.expr().path()
.id("__Field").id(format!("__field{}", i))
.build();
let expr = deserialize_variant(
cx,
builder,
type_ident,
impl_generics,
ty.clone(),
variant,
);
quote_arm!(cx, $variant_name => { $expr })
})
.collect();
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
builder,
impl_generics,
);
quote_expr!(cx, {
$variant_visitor
$visitor_item
impl $impl_generics ::serde::de::EnumVisitor for $visitor_ty $where_clause {
type Value = $ty;
fn visit<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::VariantVisitor,
{
match try!(visitor.visit_variant()) {
$variant_arms
}
}
}
deserializer.visit_enum($type_name, $visitor_expr)
})
}
fn deserialize_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
generics: &ast::Generics,
ty: P<ast::Ty>,
variant: &ast::Variant,
) -> P<ast::Expr> {
let variant_ident = variant.node.name;
match variant.node.kind {
ast::TupleVariantKind(ref args) if args.is_empty() => {
quote_expr!(cx, {
try!(visitor.visit_value(::serde::de::impls::UnitVisitor));
Ok($type_ident::$variant_ident)
})
}
ast::TupleVariantKind(ref args) => {
deserialize_tuple_variant(
cx,
builder,
type_ident,
variant_ident,
generics,
ty,
args.len(),
)
}
ast::StructVariantKind(ref struct_def) => {
deserialize_struct_variant(
cx,
builder,
type_ident,
variant_ident,
generics,
ty,
struct_def,
)
}
}
}
fn deserialize_tuple_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: ast::Ident,
variant_ident: ast::Ident,
generics: &ast::Generics,
ty: P<ast::Ty>,
fields: usize,
) -> P<ast::Expr> {
let where_clause = &generics.where_clause;
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
builder,
generics,
);
let visit_seq_expr = deserialize_seq(
cx,
builder,
builder.path().id(type_ident).id(variant_ident).build(),
fields,
);
quote_expr!(cx, {
$visitor_item
impl $generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
fn visit_seq<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::SeqVisitor,
{
$visit_seq_expr
}
}
visitor.visit_value($visitor_expr)
})
}
fn deserialize_struct_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: ast::Ident,
variant_ident: ast::Ident,
generics: &ast::Generics,
ty: P<ast::Ty>,
struct_def: &ast::StructDef,
) -> P<ast::Expr> {
let where_clause = &generics.where_clause;
let (field_visitor, field_expr) = deserialize_struct_visitor(
cx,
builder,
struct_def,
builder.path().id(type_ident).id(variant_ident).build(),
);
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
builder,
generics,
);
quote_expr!(cx, {
$field_visitor
$visitor_item
impl $generics ::serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty;
fn visit_map<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
where __V: ::serde::de::MapVisitor,
{
$field_expr
}
}
visitor.visit_value($visitor_expr)
})
}
fn deserialize_field_visitor(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
field_exprs: Vec<P<ast::Expr>>,
) -> Vec<P<ast::Item>> {
// Create the field names for the fields.
let field_idents: Vec<ast::Ident> = (0 .. field_exprs.len())
.map(|i| builder.id(format!("__field{}", i)))
.collect();
let field_enum = builder.item()
.attr().allow(&["non_camel_case_types"])
.enum_("__Field")
.with_variants(
field_idents.iter().map(|field_ident| {
builder.variant(field_ident).tuple().build()
})
)
.build();
// Match arms to extract a field from a string
let field_arms: Vec<_> = field_idents.iter()
.zip(field_exprs.into_iter())
.map(|(field_ident, field_expr)| {
quote_arm!(cx, $field_expr => { Ok(__Field::$field_ident) })
})
.collect();
vec![
field_enum,
quote_item!(cx,
impl ::serde::de::Deserialize for __Field {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> ::std::result::Result<__Field, D::Error>
where D: ::serde::de::Deserializer,
{
struct __FieldVisitor;
impl ::serde::de::Visitor for __FieldVisitor {
type Value = __Field;
fn visit_str<E>(&mut self, value: &str) -> ::std::result::Result<__Field, E>
where E: ::serde::de::Error,
{
match value {
$field_arms
_ => Err(::serde::de::Error::syntax_error()),
}
}
}
deserializer.visit(__FieldVisitor)
}
}
).unwrap(),
]
}
fn deserialize_struct_visitor(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
struct_def: &ast::StructDef,
struct_path: ast::Path,
) -> (Vec<P<ast::Item>>, P<ast::Expr>) {
let field_visitor = deserialize_field_visitor(
cx,
builder,
field::struct_field_strs(cx, builder, struct_def),
);
let visit_map_expr = deserialize_map(
cx,
builder,
struct_path,
struct_def,
);
(field_visitor, visit_map_expr)
}
fn deserialize_map(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
struct_path: ast::Path,
struct_def: &StructDef,
) -> P<ast::Expr> {
// Create the field names for the fields.
let field_names: Vec<ast::Ident> = (0 .. struct_def.fields.len())
.map(|i| builder.id(format!("__field{}", i)))
.collect();
// Declare each field.
let let_values: Vec<P<ast::Stmt>> = field_names.iter()
.map(|field_name| quote_stmt!(cx, let mut $field_name = None;).unwrap())
.collect();
// Match arms to extract a value for a field.
let value_arms: Vec<ast::Arm> = field_names.iter()
.map(|field_name| {
quote_arm!(cx,
__Field::$field_name => {
$field_name = Some(try!(visitor.visit_value()));
}
)
})
.collect();
let extract_values: Vec<P<ast::Stmt>> = field_names.iter()
.zip(struct_def.fields.iter())
.map(|(field_name, field)| {
let name_str = match field.node.kind {
ast::NamedField(name, _) => builder.expr().str(name),
ast::UnnamedField(_) => panic!("struct contains unnamed fields"),
};
let missing_expr = if field::default_value(field) {
quote_expr!(cx, ::std::default::Default::default())
} else {
quote_expr!(cx, try!(visitor.missing_field($name_str)))
};
quote_stmt!(cx,
let $field_name = match $field_name {
Some($field_name) => $field_name,
None => $missing_expr,
};
).unwrap()
})
.collect();
let result = builder.expr().struct_path(struct_path)
.with_id_exprs(
struct_def.fields.iter()
.zip(field_names.iter())
.map(|(field, field_name)| {
(
match field.node.kind {
ast::NamedField(name, _) => name.clone(),
ast::UnnamedField(_) => panic!("struct contains unnamed fields"),
},
builder.expr().id(field_name),
)
})
)
.build();
quote_expr!(cx, {
$let_values
while let Some(key) = try!(visitor.visit_key()) {
match key {
$value_arms
}
}
$extract_values
try!(visitor.end());
Ok($result)
})
}
+83
View File
@@ -0,0 +1,83 @@
use syntax::ast;
use syntax::attr;
use syntax::ext::base::ExtCtxt;
use syntax::ptr::P;
use aster;
fn field_alias(field: &ast::StructField) -> Option<&ast::Lit> {
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);
vals.iter().fold(None, |v, mi| {
if let ast::MetaNameValue(ref n, ref lit) = mi.node {
if n == &"alias" {
Some(lit)
} else {
v
}
} else {
v
}
})
} else {
None
}
})
}
pub fn struct_field_strs(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
struct_def: &ast::StructDef,
) -> Vec<P<ast::Expr>> {
struct_def.fields.iter()
.map(|field| {
match field_alias(field) {
Some(alias) => builder.expr().build_lit(P(alias.clone())),
None => {
match field.node.kind {
ast::NamedField(name, _) => {
builder.expr().str(name)
}
ast::UnnamedField(_) => {
cx.bug("struct has named and unnamed fields")
}
}
}
}
})
.collect()
}
pub fn default_value(field: &ast::StructField) -> bool {
field.node.attrs.iter()
.any(|sa| {
if let ast::MetaItem_::MetaList(ref n, ref vals) = sa.node.value.node {
if n == &"serde" {
attr::mark_used(&sa);
vals.iter()
.map(|mi|
if let ast::MetaItem_::MetaWord(ref n) = mi.node {
n == &"default"
} else {
false
})
.any(|x| x)
} else {
false
}
}
else {
false
}
})
}
+9 -1425
View File
File diff suppressed because it is too large Load Diff
+585
View File
@@ -0,0 +1,585 @@
use syntax::ast::{
Ident,
MetaItem,
Item,
Expr,
StructDef,
};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::ExtCtxt;
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
use aster;
use field::struct_field_strs;
pub fn expand_derive_serialize(
cx: &mut ExtCtxt,
span: Span,
_mitem: &MetaItem,
item: &Item,
push: &mut FnMut(P<ast::Item>)
) {
let builder = aster::AstBuilder::new().span(span);
let generics = match item.node {
ast::ItemStruct(_, ref generics) => generics,
ast::ItemEnum(_, ref generics) => generics,
_ => cx.bug("expected ItemStruct or ItemEnum in #[derive(Serialize)]")
};
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()
.segment(item.ident).with_generics(impl_generics.clone()).build()
.build();
let body = serialize_body(
cx,
&builder,
item,
&impl_generics,
ty.clone(),
);
let where_clause = &impl_generics.where_clause;
let impl_item = quote_item!(cx,
#[automatically_derived]
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();
push(impl_item)
}
fn serialize_body(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &Item,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
) -> P<ast::Expr> {
match item.node {
ast::ItemStruct(ref struct_def, _) => {
serialize_item_struct(
cx,
builder,
item,
impl_generics,
ty,
struct_def,
)
}
ast::ItemEnum(ref enum_def, _) => {
serialize_item_enum(
cx,
builder,
item.ident,
impl_generics,
enum_def,
)
}
_ => cx.bug("expected ItemStruct or ItemEnum in #[derive(Serialize)]")
}
}
fn serialize_item_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
item: &Item,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
struct_def: &ast::StructDef,
) -> P<ast::Expr> {
let mut named_fields = vec![];
let mut unnamed_fields = 0;
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(
cx,
&builder,
item.ident,
)
}
(true, false) => {
serialize_tuple_struct(
cx,
&builder,
item.ident,
impl_generics,
ty,
unnamed_fields,
)
}
(false, true) => {
serialize_struct(
cx,
&builder,
item.ident,
impl_generics,
ty,
struct_def,
named_fields,
)
}
(false, false) => {
cx.bug("struct has named and unnamed fields")
}
}
}
fn serialize_unit_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident
) -> P<ast::Expr> {
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, serializer.visit_named_unit($type_name))
}
fn serialize_tuple_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
fields: usize,
) -> P<ast::Expr> {
let value_ty = builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(ty);
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
cx,
builder,
value_ty,
fields,
impl_generics,
);
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_named_seq($type_name, Visitor {
value: self,
state: 0,
})
})
}
fn serialize_struct(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
ty: P<ast::Ty>,
struct_def: &StructDef,
fields: Vec<Ident>,
) -> P<ast::Expr> {
let value_ty = builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(ty.clone());
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
cx,
builder,
value_ty,
struct_def,
impl_generics,
fields.iter().map(|field| quote_expr!(cx, &self.value.$field)),
);
let type_name = builder.expr().str(type_ident);
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_named_map($type_name, Visitor {
value: self,
state: 0,
})
})
}
fn serialize_item_enum(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
impl_generics: &ast::Generics,
enum_def: &ast::EnumDef,
) -> P<ast::Expr> {
let arms: Vec<ast::Arm> = enum_def.variants.iter()
.map(|variant| {
serialize_variant(
cx,
builder,
type_ident,
impl_generics,
variant,
)
})
.collect();
quote_expr!(cx,
match *self {
$arms
}
)
}
fn serialize_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_ident: Ident,
generics: &ast::Generics,
variant: &ast::Variant,
) -> ast::Arm {
let type_name = builder.expr().str(type_ident);
let variant_ident = variant.node.name;
let variant_name = builder.expr().str(variant_ident);
match variant.node.kind {
ast::TupleVariantKind(ref args) if args.is_empty() => {
let pat = builder.pat().enum_()
.id(type_ident).id(variant_ident).build()
.build();
quote_arm!(cx,
$pat => {
::serde::ser::Serializer::visit_enum_unit(
serializer,
$type_name,
$variant_name,
)
},
)
}
ast::TupleVariantKind(ref args) => {
let fields: Vec<ast::Ident> = (0 .. args.len())
.map(|i| builder.id(format!("__field{}", i)))
.collect();
let pat = builder.pat().enum_()
.id(type_ident).id(variant_ident).build()
.with_pats(fields.iter().map(|field| builder.pat().ref_id(field)))
.build();
let expr = serialize_tuple_variant(
cx,
builder,
type_name,
variant_name,
generics,
args,
fields,
);
quote_arm!(cx, $pat => { $expr })
}
ast::StructVariantKind(ref struct_def) => {
let fields: Vec<_> = (0 .. struct_def.fields.len())
.map(|i| builder.id(format!("__field{}", i)))
.collect();
let pat = builder.pat().struct_()
.id(type_ident).id(variant_ident).build()
.with_pats(
fields.iter()
.zip(struct_def.fields.iter())
.map(|(id, field)| {
let name = match field.node.kind {
ast::NamedField(name, _) => name,
ast::UnnamedField(_) => {
cx.bug("struct variant has unnamed fields")
}
};
(name, builder.pat().ref_id(id))
})
)
.build();
let expr = serialize_struct_variant(
cx,
builder,
type_name,
variant_name,
generics,
struct_def,
fields,
);
quote_arm!(cx, $pat => { $expr })
}
}
}
fn serialize_tuple_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_name: P<ast::Expr>,
variant_name: P<ast::Expr>,
generics: &ast::Generics,
args: &[ast::VariantArg],
fields: Vec<Ident>,
) -> P<ast::Expr> {
let value_ty = builder.ty().tuple()
.with_tys(
args.iter().map(|arg| {
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(arg.ty.clone())
})
)
.build();
let value_expr = builder.expr().tuple()
.with_exprs(
fields.iter().map(|field| {
builder.expr()
.addr_of()
.id(field)
})
)
.build();
let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor(
cx,
builder,
value_ty,
args.len(),
generics,
);
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_enum_seq($type_name, $variant_name, Visitor {
value: $value_expr,
state: 0,
})
})
}
fn serialize_struct_variant(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
type_name: P<ast::Expr>,
variant_name: P<ast::Expr>,
generics: &ast::Generics,
struct_def: &ast::StructDef,
fields: Vec<Ident>,
) -> P<ast::Expr> {
let value_ty = builder.ty().tuple()
.with_tys(
struct_def.fields.iter().map(|field| {
builder.ty()
.ref_()
.lifetime("'__a")
.build_ty(field.node.ty.clone())
})
)
.build();
let value_expr = builder.expr().tuple()
.with_exprs(
fields.iter().map(|field| {
builder.expr()
.addr_of()
.id(field)
})
)
.build();
let (visitor_struct, visitor_impl) = serialize_struct_visitor(
cx,
builder,
value_ty,
struct_def,
generics,
(0 .. fields.len()).map(|i| {
builder.expr()
.tup_field(i)
.field("value").self_()
})
);
quote_expr!(cx, {
$visitor_struct
$visitor_impl
serializer.visit_enum_map($type_name, $variant_name, Visitor {
value: $value_expr,
state: 0,
})
})
}
fn serialize_tuple_struct_visitor(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
value_ty: P<ast::Ty>,
fields: usize,
generics: &ast::Generics
) -> (P<ast::Item>, P<ast::Item>) {
let arms: Vec<ast::Arm> = (0 .. fields)
.map(|i| {
let expr = builder.expr()
.tup_field(i)
.field("value").self_();
quote_arm!(cx,
$i => {
self.state += 1;
let v = try!(serializer.visit_seq_elt(&$expr));
Ok(Some(v))
}
)
})
.collect();
let visitor_impl_generics = builder.from_generics(generics.clone())
.add_lifetime_bound("'__a")
.lifetime_name("'__a")
.build();
let where_clause = &visitor_impl_generics.where_clause;
let visitor_generics = builder.from_generics(visitor_impl_generics.clone())
.strip_bounds()
.build();
(
quote_item!(cx,
struct Visitor $visitor_impl_generics $where_clause {
state: usize,
value: $value_ty,
}
).unwrap(),
quote_item!(cx,
impl $visitor_impl_generics ::serde::ser::SeqVisitor
for Visitor $visitor_generics
$where_clause {
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> ::std::result::Result<Option<()>, S::Error>
where S: ::serde::ser::Serializer,
{
match self.state {
$arms
_ => Ok(None),
}
}
#[inline]
fn len(&self) -> Option<usize> {
Some($fields)
}
}
).unwrap(),
)
}
fn serialize_struct_visitor<I>(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
value_ty: P<ast::Ty>,
struct_def: &StructDef,
generics: &ast::Generics,
value_exprs: I,
) -> (P<ast::Item>, P<ast::Item>)
where I: Iterator<Item=P<ast::Expr>>,
{
let len = struct_def.fields.len();
let key_exprs = struct_field_strs(cx, builder, struct_def);
let arms: Vec<ast::Arm> = key_exprs.iter()
.zip(value_exprs)
.enumerate()
.map(|(i, (key_expr, value_expr))| {
quote_arm!(cx,
$i => {
self.state += 1;
Ok(
Some(
try!(
serializer.visit_map_elt(
$key_expr,
$value_expr,
)
)
)
)
}
)
})
.collect();
let visitor_impl_generics = builder.from_generics(generics.clone())
.add_lifetime_bound("'__a")
.lifetime_name("'__a")
.build();
let where_clause = &visitor_impl_generics.where_clause;
let visitor_generics = builder.from_generics(visitor_impl_generics.clone())
.strip_bounds()
.build();
(
quote_item!(cx,
struct Visitor $visitor_impl_generics $where_clause {
state: usize,
value: $value_ty,
}
).unwrap(),
quote_item!(cx,
impl $visitor_impl_generics
::serde::ser::MapVisitor
for Visitor $visitor_generics
$where_clause {
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> ::std::result::Result<Option<()>, S::Error>
where S: ::serde::ser::Serializer,
{
match self.state {
$arms
_ => Ok(None),
}
}
#[inline]
fn len(&self) -> Option<usize> {
Some($len)
}
}
).unwrap(),
)
}
+170
View File
@@ -0,0 +1,170 @@
use std::ops;
use ser;
use de;
///////////////////////////////////////////////////////////////////////////////
/// `Bytes` wraps a `&[u8]` in order to serialize into a byte array.
pub struct Bytes<'a> {
bytes: &'a [u8],
}
impl<'a, T> From<T> for Bytes<'a> where T: Into<&'a [u8]> {
fn from(bytes: T) -> Self {
Bytes {
bytes: bytes.into(),
}
}
}
impl<'a> ops::Deref for Bytes<'a> {
type Target = [u8];
fn deref(&self) -> &[u8] { self.bytes }
}
impl<'a> ser::Serialize for Bytes<'a> {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer
{
serializer.visit_bytes(self.bytes)
}
}
///////////////////////////////////////////////////////////////////////////////
/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf {
bytes: Vec<u8>,
}
impl ByteBuf {
pub fn new() -> Self {
ByteBuf {
bytes: Vec::new(),
}
}
pub fn with_capacity(cap: usize) -> Self {
ByteBuf {
bytes: Vec::with_capacity(cap)
}
}
}
impl<T> From<T> for ByteBuf where T: Into<Vec<u8>> {
fn from(bytes: T) -> Self {
ByteBuf {
bytes: bytes.into(),
}
}
}
impl AsRef<Vec<u8>> for ByteBuf {
fn as_ref(&self) -> &Vec<u8> {
&self.bytes
}
}
impl AsRef<[u8]> for ByteBuf {
fn as_ref(&self) -> &[u8] {
&self.bytes
}
}
impl AsMut<Vec<u8>> for ByteBuf {
fn as_mut(&mut self) -> &mut Vec<u8> {
&mut self.bytes
}
}
impl AsMut<[u8]> for ByteBuf {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.bytes
}
}
impl Into<Vec<u8>> for ByteBuf {
fn into(self) -> Vec<u8> {
self.bytes
}
}
impl ops::Deref for ByteBuf {
type Target = [u8];
fn deref(&self) -> &[u8] { &self.bytes[..] }
}
impl ops::DerefMut for ByteBuf {
fn deref_mut(&mut self) -> &mut [u8] { &mut self.bytes[..] }
}
impl ser::Serialize for ByteBuf {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer
{
serializer.visit_bytes(&self)
}
}
pub struct ByteBufVisitor;
impl de::Visitor for ByteBufVisitor {
type Value = ByteBuf;
#[inline]
fn visit_unit<E>(&mut self) -> Result<ByteBuf, E>
where E: de::Error,
{
Ok(ByteBuf {
bytes: Vec::new(),
})
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<ByteBuf, V::Error>
where V: de::SeqVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = Vec::with_capacity(len);
while let Some(value) = try!(visitor.visit()) {
values.push(value);
}
try!(visitor.end());
Ok(ByteBuf {
bytes: values,
})
}
#[inline]
fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<ByteBuf, E>
where E: de::Error,
{
self.visit_byte_buf(v.to_vec())
}
#[inline]
fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<ByteBuf, E>
where E: de::Error,
{
Ok(ByteBuf {
bytes: v,
})
}
}
impl de::Deserialize for ByteBuf {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<ByteBuf, D::Error>
where D: de::Deserializer
{
deserializer.visit_bytes(ByteBufVisitor)
}
}
+254 -421
View File
@@ -1,377 +1,21 @@
use std::collections::{HashMap, BTreeMap};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecMap};
use std::hash::Hash;
use std::marker::PhantomData;
use std::num::FromPrimitive;
use std::path;
use std::str;
use de::{
Deserialize,
Deserializer,
Error,
MapVisitor,
SeqVisitor,
Visitor,
};
///////////////////////////////////////////////////////////////////////////////
pub trait Error {
fn syntax_error() -> Self;
fn end_of_stream_error() -> Self;
fn missing_field_error(&'static str) -> Self;
}
pub trait Deserialize {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer;
}
pub trait Deserializer {
type Error: Error;
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor;
/// The `visit_option` method allows a `Deserialize` type to inform the
/// `Deserializer` that it's expecting an optional value. This allows
/// deserializers that encode an optional value as a nullable value to
/// convert the null value into a `None`, and a regular value as
/// `Some(value)`.
#[inline]
fn visit_option<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// The `visit_enum` method allows a `Deserialize` type to inform the
/// `Deserializer` that it's expecting an enum value. This allows
/// deserializers that provide a custom enumeration serialization to
/// properly deserialize the type.
#[inline]
fn visit_enum<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
}
pub trait Visitor {
type Value;
fn visit_bool<E>(&mut self, _v: bool) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_isize<E>(&mut self, v: isize) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i8<E>(&mut self, v: i8) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i16<E>(&mut self, v: i16) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i32<E>(&mut self, v: i32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i64<E>(&mut self, _v: i64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_usize<E>(&mut self, v: usize) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u8<E>(&mut self, v: u8) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u16<E>(&mut self, v: u16) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u32<E>(&mut self, v: u32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u64<E>(&mut self, _v: u64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_f32<E>(&mut self, v: f32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_f64(v as f64)
}
fn visit_f64<E>(&mut self, _v: f64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_char<E>(&mut self, v: char) -> Result<Self::Value, E>
where E: Error,
{
// The unwraps in here should be safe.
let mut s = &mut [0; 4];
let len = v.encode_utf8(s).unwrap();
self.visit_str(str::from_utf8(&s[..len]).unwrap())
}
fn visit_str<E>(&mut self, _v: &str) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_string<E>(&mut self, v: String) -> Result<Self::Value, E>
where E: Error,
{
self.visit_str(&v)
}
fn visit_unit<E>(&mut self) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_named_unit<E>(&mut self, _name: &str) -> Result<Self::Value, E>
where E: Error,
{
self.visit_unit()
}
fn visit_none<E>(&mut self) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_some<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
where D: Deserializer,
{
Err(Error::syntax_error())
}
fn visit_seq<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_named_seq<V>(&mut self, _name: &str, visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor,
{
self.visit_seq(visitor)
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_named_map<V>(&mut self, _name: &str, visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor,
{
self.visit_map(visitor)
}
#[inline]
fn visit_enum<V>(&mut self,
_name: &str,
_variant: &str,
_visitor: V) -> Result<Self::Value, V::Error>
where V: EnumVisitor,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_variant<V>(&mut self, _name: &str, _visitor: V) -> Result<Self::Value, V::Error>
where V: EnumVisitor,
{
Err(Error::syntax_error())
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait SeqVisitor {
type Error: Error;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: Deserialize;
fn end(&mut self) -> Result<(), Self::Error>;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor {
type Error = V::Error;
#[inline]
fn visit<T>(&mut self) -> Result<Option<T>, V::Error>
where T: Deserialize
{
(**self).visit()
}
#[inline]
fn end(&mut self) -> Result<(), V::Error> {
(**self).end()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait MapVisitor {
type Error: Error;
#[inline]
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error>
where K: Deserialize,
V: Deserialize,
{
match try!(self.visit_key()) {
Some(key) => {
let value = try!(self.visit_value());
Ok(Some((key, value)))
}
None => Ok(None)
}
}
fn visit_key<K>(&mut self) -> Result<Option<K>, Self::Error>
where K: Deserialize;
fn visit_value<V>(&mut self) -> Result<V, Self::Error>
where V: Deserialize;
fn end(&mut self) -> Result<(), Self::Error>;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
type Error = V_::Error;
#[inline]
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, V_::Error>
where K: Deserialize,
V: Deserialize,
{
(**self).visit()
}
#[inline]
fn visit_key<K>(&mut self) -> Result<Option<K>, V_::Error>
where K: Deserialize
{
(**self).visit_key()
}
#[inline]
fn visit_value<V>(&mut self) -> Result<V, V_::Error>
where V: Deserialize
{
(**self).visit_value()
}
#[inline]
fn end(&mut self) -> Result<(), V_::Error> {
(**self).end()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait EnumVisitor {
type Error: Error;
fn visit_unit(&mut self) -> Result<(), Self::Error> {
Err(Error::syntax_error())
}
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: EnumSeqVisitor,
{
Err(Error::syntax_error())
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: EnumMapVisitor,
{
Err(Error::syntax_error())
}
}
///////////////////////////////////////////////////////////////////////////////
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;
}
///////////////////////////////////////////////////////////////////////////////
struct UnitVisitor;
pub struct UnitVisitor;
impl Visitor for UnitVisitor {
type Value = ();
@@ -450,7 +94,7 @@ impl<T> PrimitiveVisitor<T> {
impl<
T: Deserialize + FromPrimitive
> self::Visitor for PrimitiveVisitor<T> {
> Visitor for PrimitiveVisitor<T> {
type Value = T;
impl_deserialize_num_method!(isize, visit_isize, from_isize);
@@ -597,6 +241,111 @@ impl<T> Deserialize for Option<T> where T: Deserialize {
///////////////////////////////////////////////////////////////////////////////
pub struct BTreeSetVisitor<T> {
marker: PhantomData<T>,
}
impl<T> BTreeSetVisitor<T> {
pub fn new() -> Self {
BTreeSetVisitor {
marker: PhantomData,
}
}
}
impl<T> Visitor for BTreeSetVisitor<T>
where T: Deserialize + Eq + Ord,
{
type Value = BTreeSet<T>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<BTreeSet<T>, E>
where E: Error,
{
Ok(BTreeSet::new())
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<BTreeSet<T>, V::Error>
where V: SeqVisitor,
{
let mut values = BTreeSet::new();
while let Some(value) = try!(visitor.visit()) {
values.insert(value);
}
try!(visitor.end());
Ok(values)
}
}
impl<T> Deserialize for BTreeSet<T>
where T: Deserialize + Eq + Ord,
{
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeSet<T>, D::Error>
where D: Deserializer,
{
deserializer.visit(BTreeSetVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct HashSetVisitor<T> {
marker: PhantomData<T>,
}
impl<T> HashSetVisitor<T> {
pub fn new() -> Self {
HashSetVisitor {
marker: PhantomData,
}
}
}
impl<T> Visitor for HashSetVisitor<T>
where T: Deserialize + Eq + Hash,
{
type Value = HashSet<T>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<HashSet<T>, E>
where E: Error,
{
Ok(HashSet::new())
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<HashSet<T>, V::Error>
where V: SeqVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = HashSet::with_capacity(len);
while let Some(value) = try!(visitor.visit()) {
values.insert(value);
}
try!(visitor.end());
Ok(values)
}
}
impl<T> Deserialize for HashSet<T>
where T: Deserialize + Eq + Hash,
{
fn deserialize<D>(deserializer: &mut D) -> Result<HashSet<T>, D::Error>
where D: Deserializer,
{
deserializer.visit(HashSetVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct VecVisitor<T> {
marker: PhantomData<T>,
}
@@ -612,6 +361,13 @@ impl<T> VecVisitor<T> {
impl<T> Visitor for VecVisitor<T> where T: Deserialize {
type Value = Vec<T>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<Vec<T>, E>
where E: Error,
{
Ok(Vec::new())
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<Vec<T>, V::Error>
where V: SeqVisitor,
@@ -623,11 +379,15 @@ impl<T> Visitor for VecVisitor<T> where T: Deserialize {
values.push(value);
}
try!(visitor.end());
Ok(values)
}
}
impl<T: Deserialize> Deserialize for Vec<T> {
impl<T> Deserialize for Vec<T>
where T: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<Vec<T>, D::Error>
where D: Deserializer,
{
@@ -699,53 +459,6 @@ tuple_impls! {
///////////////////////////////////////////////////////////////////////////////
pub struct HashMapVisitor<K, V> {
marker: PhantomData<HashMap<K, V>>,
}
impl<K, V> HashMapVisitor<K, V> {
#[inline]
pub fn new() -> Self {
HashMapVisitor {
marker: PhantomData,
}
}
}
impl<K, V> Visitor for HashMapVisitor<K, V>
where K: Deserialize + Eq + Hash,
V: Deserialize,
{
type Value = HashMap<K, V>;
#[inline]
fn visit_map<V_>(&mut self, mut visitor: V_) -> Result<HashMap<K, V>, V_::Error>
where V_: MapVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = HashMap::with_capacity(len);
while let Some((key, value)) = try!(visitor.visit()) {
values.insert(key, value);
}
Ok(values)
}
}
impl<K, V> Deserialize for HashMap<K, V>
where K: Deserialize + Eq + Hash,
V: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<HashMap<K, V>, D::Error>
where D: Deserializer,
{
deserializer.visit(HashMapVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct BTreeMapVisitor<K, V> {
marker: PhantomData<BTreeMap<K, V>>,
}
@@ -765,6 +478,13 @@ impl<K, V> Visitor for BTreeMapVisitor<K, V>
{
type Value = BTreeMap<K, V>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<BTreeMap<K, V>, E>
where E: Error,
{
Ok(BTreeMap::new())
}
#[inline]
fn visit_map<Visitor>(&mut self, mut visitor: Visitor) -> Result<BTreeMap<K, V>, Visitor::Error>
where Visitor: MapVisitor,
@@ -775,14 +495,16 @@ impl<K, V> Visitor for BTreeMapVisitor<K, V>
values.insert(key, value);
}
try!(visitor.end());
Ok(values)
}
}
impl<
K: Deserialize + Eq + Ord,
V: Deserialize,
> Deserialize for BTreeMap<K, V> {
impl<K, V> Deserialize for BTreeMap<K, V>
where K: Deserialize + Eq + Ord,
V: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeMap<K, V>, D::Error>
where D: Deserializer,
{
@@ -792,6 +514,116 @@ impl<
///////////////////////////////////////////////////////////////////////////////
pub struct HashMapVisitor<K, V> {
marker: PhantomData<HashMap<K, V>>,
}
impl<K, V> HashMapVisitor<K, V> {
#[inline]
pub fn new() -> Self {
HashMapVisitor {
marker: PhantomData,
}
}
}
impl<K, V> Visitor for HashMapVisitor<K, V>
where K: Deserialize + Eq + Hash,
V: Deserialize,
{
type Value = HashMap<K, V>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<HashMap<K, V>, E>
where E: Error,
{
Ok(HashMap::new())
}
#[inline]
fn visit_map<V_>(&mut self, mut visitor: V_) -> Result<HashMap<K, V>, V_::Error>
where V_: MapVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = HashMap::with_capacity(len);
while let Some((key, value)) = try!(visitor.visit()) {
values.insert(key, value);
}
try!(visitor.end());
Ok(values)
}
}
impl<K, V> Deserialize for HashMap<K, V>
where K: Deserialize + Eq + Hash,
V: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<HashMap<K, V>, D::Error>
where D: Deserializer,
{
deserializer.visit(HashMapVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct VecMapVisitor<V> {
marker: PhantomData<VecMap<V>>,
}
impl<V> VecMapVisitor<V> {
#[inline]
pub fn new() -> Self {
VecMapVisitor {
marker: PhantomData,
}
}
}
impl<V> Visitor for VecMapVisitor<V>
where V: Deserialize,
{
type Value = VecMap<V>;
#[inline]
fn visit_unit<E>(&mut self) -> Result<VecMap<V>, E>
where E: Error,
{
Ok(VecMap::new())
}
#[inline]
fn visit_map<V_>(&mut self, mut visitor: V_) -> Result<VecMap<V>, V_::Error>
where V_: MapVisitor,
{
let (len, _) = visitor.size_hint();
let mut values = VecMap::with_capacity(len);
while let Some((key, value)) = try!(visitor.visit()) {
values.insert(key, value);
}
try!(visitor.end());
Ok(values)
}
}
impl<V> Deserialize for VecMap<V>
where V: Deserialize,
{
fn deserialize<D>(deserializer: &mut D) -> Result<VecMap<V>, D::Error>
where D: Deserializer,
{
deserializer.visit(VecMapVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
struct PathBufVisitor;
impl Visitor for PathBufVisitor {
@@ -800,7 +632,7 @@ impl Visitor for PathBufVisitor {
fn visit_str<E>(&mut self, v: &str) -> Result<path::PathBuf, E>
where E: Error,
{
Ok(path::PathBuf::new(&v))
Ok(From::from(v))
}
fn visit_string<E>(&mut self, v: String) -> Result<path::PathBuf, E>
@@ -817,3 +649,4 @@ impl Deserialize for path::PathBuf {
deserializer.visit(PathBufVisitor)
}
}
+437
View File
@@ -0,0 +1,437 @@
use std::str;
pub mod impls;
pub mod value;
///////////////////////////////////////////////////////////////////////////////
pub trait Error {
fn syntax_error() -> Self;
fn end_of_stream_error() -> Self;
fn missing_field_error(&'static str) -> Self;
}
///////////////////////////////////////////////////////////////////////////////
pub trait Deserialize {
/// Deserialize this value given this `Deserializer`.
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer;
}
///////////////////////////////////////////////////////////////////////////////
/// `Deserializer` is an abstract trait that can deserialize values into a `Visitor`.
pub trait Deserializer {
type Error: Error;
/// The `visit` method walks a visitor through a value as it is being deserialized.
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor;
/// The `visit_option` method allows a `Deserialize` type to inform the `Deserializer` that
/// it's expecting an optional value. This allows deserializers that encode an optional value
/// as a nullable value to convert the null value into a `None`, and a regular value as
/// `Some(value)`.
#[inline]
fn visit_option<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// The `visit_seq` method allows a `Deserialize` type to inform the `Deserializer` that it's
/// expecting a sequence of values. This allows deserializers to parse sequences that aren't
/// tagged as sequences.
#[inline]
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// The `visit_map` method allows a `Deserialize` type to inform the `Deserializer` that it's
/// expecting a map of values. This allows deserializers to parse sequences that aren't tagged
/// as maps.
#[inline]
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// The `visit_named_unit` method allows a `Deserialize` type to inform the `Deserializer` that
/// it's expecting a named unit. This allows deserializers to a named unit that aren't tagged
/// as a named unit.
#[inline]
fn visit_named_unit<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
/// The `visit_named_seq` method allows a `Deserialize` type to inform the `Deserializer` that
/// it's expecting a named sequence of values. This allows deserializers to parse sequences
/// that aren't tagged as sequences.
#[inline]
fn visit_named_seq<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_seq(visitor)
}
/// The `visit_named_map` method allows a `Deserialize` type to inform the `Deserializer` that
/// it's expecting a map of values. This allows deserializers to parse sequences that aren't
/// tagged as maps.
#[inline]
fn visit_named_map<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit_map(visitor)
}
/// The `visit_enum` method allows a `Deserialize` type to inform the `Deserializer` that it's
/// expecting an enum value. This allows deserializers that provide a custom enumeration
/// serialization to properly deserialize the type.
#[inline]
fn visit_enum<V>(&mut self, _enum: &str, _visitor: V) -> Result<V::Value, Self::Error>
where V: EnumVisitor,
{
Err(Error::syntax_error())
}
/// The `visit_bytes` method allows a `Deserialize` type to inform the `Deserializer` that it's
/// expecting a `Vec<u8>`. This allows deserializers that provide a custom byte vector
/// serialization to properly deserialize the type.
#[inline]
fn visit_bytes<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor,
{
self.visit(visitor)
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait Visitor {
type Value;
fn visit_bool<E>(&mut self, _v: bool) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_isize<E>(&mut self, v: isize) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i8<E>(&mut self, v: i8) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i16<E>(&mut self, v: i16) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i32<E>(&mut self, v: i32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_i64(v as i64)
}
fn visit_i64<E>(&mut self, _v: i64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_usize<E>(&mut self, v: usize) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u8<E>(&mut self, v: u8) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u16<E>(&mut self, v: u16) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u32<E>(&mut self, v: u32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_u64(v as u64)
}
fn visit_u64<E>(&mut self, _v: u64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_f32<E>(&mut self, v: f32) -> Result<Self::Value, E>
where E: Error,
{
self.visit_f64(v as f64)
}
fn visit_f64<E>(&mut self, _v: f64) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_char<E>(&mut self, v: char) -> Result<Self::Value, E>
where E: Error,
{
// The unwraps in here should be safe.
let mut s = &mut [0; 4];
let len = v.encode_utf8(s).unwrap();
self.visit_str(str::from_utf8(&s[..len]).unwrap())
}
fn visit_str<E>(&mut self, _v: &str) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_string<E>(&mut self, v: String) -> Result<Self::Value, E>
where E: Error,
{
self.visit_str(&v)
}
fn visit_unit<E>(&mut self) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
#[inline]
fn visit_named_unit<E>(&mut self, _name: &str) -> Result<Self::Value, E>
where E: Error,
{
self.visit_unit()
}
fn visit_none<E>(&mut self) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_some<D>(&mut self, _deserializer: &mut D) -> Result<Self::Value, D::Error>
where D: Deserializer,
{
Err(Error::syntax_error())
}
fn visit_seq<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: SeqVisitor,
{
Err(Error::syntax_error())
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<Self::Value, V::Error>
where V: MapVisitor,
{
Err(Error::syntax_error())
}
fn visit_bytes<E>(&mut self, _v: &[u8]) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
fn visit_byte_buf<E>(&mut self, _v: Vec<u8>) -> Result<Self::Value, E>
where E: Error,
{
Err(Error::syntax_error())
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait SeqVisitor {
type Error: Error;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: Deserialize;
fn end(&mut self) -> Result<(), Self::Error>;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor {
type Error = V::Error;
#[inline]
fn visit<T>(&mut self) -> Result<Option<T>, V::Error>
where T: Deserialize
{
(**self).visit()
}
#[inline]
fn end(&mut self) -> Result<(), V::Error> {
(**self).end()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait MapVisitor {
type Error: Error;
#[inline]
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error>
where K: Deserialize,
V: Deserialize,
{
match try!(self.visit_key()) {
Some(key) => {
let value = try!(self.visit_value());
Ok(Some((key, value)))
}
None => Ok(None)
}
}
fn visit_key<K>(&mut self) -> Result<Option<K>, Self::Error>
where K: Deserialize;
fn visit_value<V>(&mut self) -> Result<V, Self::Error>
where V: Deserialize;
fn end(&mut self) -> Result<(), Self::Error>;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
fn missing_field<V>(&mut self, field: &'static str) -> Result<V, Self::Error>
where V: Deserialize,
{
Err(Error::missing_field_error(field))
}
}
impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
type Error = V_::Error;
#[inline]
fn visit<K, V>(&mut self) -> Result<Option<(K, V)>, V_::Error>
where K: Deserialize,
V: Deserialize,
{
(**self).visit()
}
#[inline]
fn visit_key<K>(&mut self) -> Result<Option<K>, V_::Error>
where K: Deserialize
{
(**self).visit_key()
}
#[inline]
fn visit_value<V>(&mut self) -> Result<V, V_::Error>
where V: Deserialize
{
(**self).visit_value()
}
#[inline]
fn end(&mut self) -> Result<(), V_::Error> {
(**self).end()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(**self).size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
pub trait EnumVisitor {
type Value;
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
where V: VariantVisitor;
}
///////////////////////////////////////////////////////////////////////////////
pub trait VariantVisitor {
type Error: Error;
fn visit_variant<V>(&mut self) -> Result<V, Self::Error>
where V: Deserialize;
fn visit_value<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor;
}
impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor {
type Error = T::Error;
fn visit_variant<V>(&mut self) -> Result<V, T::Error>
where V: Deserialize
{
(**self).visit_variant()
}
fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{
(**self).visit_value(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;
}
+413
View File
@@ -0,0 +1,413 @@
use std::collections::{
BTreeMap,
BTreeSet,
HashMap,
HashSet,
btree_map,
btree_set,
hash_map,
hash_set,
};
use std::hash::Hash;
use std::vec;
use de;
///////////////////////////////////////////////////////////////////////////////
pub enum Error {
SyntaxError,
EndOfStreamError,
MissingFieldError(&'static str),
}
impl de::Error for Error {
fn syntax_error() -> Self { Error::SyntaxError }
fn end_of_stream_error() -> Self { Error::EndOfStreamError }
fn missing_field_error(field: &'static str) -> Self { Error::MissingFieldError(field) }
}
///////////////////////////////////////////////////////////////////////////////
pub trait ValueDeserializer {
type Deserializer: de::Deserializer<Error=Error>;
fn deserializer(self) -> Self::Deserializer;
}
///////////////////////////////////////////////////////////////////////////////
impl ValueDeserializer for () {
type Deserializer = UnitDeserializer;
fn deserializer(self) -> UnitDeserializer {
UnitDeserializer
}
}
/// A helper deserializer that deserializes a `()`.
pub 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()
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! primitive_deserializer {
($ty:ty, $name:ident, $method:ident) => {
pub struct $name(Option<$ty>);
impl ValueDeserializer for $ty {
type Deserializer = $name;
fn deserializer(self) -> $name {
$name(Some(self))
}
}
impl de::Deserializer for $name {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.0.take() {
Some(v) => visitor.$method(v),
None => Err(de::Error::end_of_stream_error()),
}
}
}
}
}
primitive_deserializer!(bool, BoolDeserializer, visit_bool);
primitive_deserializer!(i8, I8Deserializer, visit_i8);
primitive_deserializer!(i16, I16Deserializer, visit_i16);
primitive_deserializer!(i32, I32Deserializer, visit_i32);
primitive_deserializer!(i64, I64Deserializer, visit_i64);
primitive_deserializer!(isize, IsizeDeserializer, visit_isize);
primitive_deserializer!(u8, U8Deserializer, visit_u8);
primitive_deserializer!(u16, U16Deserializer, visit_u16);
primitive_deserializer!(u32, U32Deserializer, visit_u32);
primitive_deserializer!(u64, U64Deserializer, visit_u64);
primitive_deserializer!(usize, UsizeDeserializer, visit_usize);
primitive_deserializer!(f32, F32Deserializer, visit_f32);
primitive_deserializer!(f64, F64Deserializer, visit_f64);
primitive_deserializer!(char, CharDeserializer, visit_char);
///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a `&str`.
pub struct StrDeserializer<'a>(Option<&'a str>);
impl<'a> ValueDeserializer for &'a str {
type Deserializer = StrDeserializer<'a>;
fn deserializer(self) -> StrDeserializer<'a> {
StrDeserializer(Some(self))
}
}
impl<'a> de::Deserializer for StrDeserializer<'a> {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.0.take() {
Some(v) => visitor.visit_str(v),
None => Err(de::Error::end_of_stream_error()),
}
}
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
visitor.visit(self)
}
}
impl<'a> de::VariantVisitor for StrDeserializer<'a> {
type Error = Error;
fn visit_variant<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize,
{
de::Deserialize::deserialize(self)
}
fn visit_value<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_unit()
}
}
///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a `String`.
pub struct StringDeserializer(Option<String>);
impl ValueDeserializer for String {
type Deserializer = StringDeserializer;
fn deserializer(self) -> StringDeserializer {
StringDeserializer(Some(self))
}
}
impl de::Deserializer for StringDeserializer {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.0.take() {
Some(string) => visitor.visit_string(string),
None => Err(de::Error::end_of_stream_error()),
}
}
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
visitor.visit(self)
}
}
impl<'a> de::VariantVisitor for StringDeserializer {
type Error = Error;
fn visit_variant<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize,
{
de::Deserialize::deserialize(self)
}
fn visit_value<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_unit()
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct SeqDeserializer<I> {
iter: I,
len: usize,
}
impl<I> SeqDeserializer<I> {
pub fn new(iter: I, len: usize) -> Self {
SeqDeserializer {
iter: iter,
len: len,
}
}
}
impl<I, T> de::Deserializer for SeqDeserializer<I>
where I: Iterator<Item=T>,
T: ValueDeserializer,
{
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_seq(self)
}
}
impl<I, T> de::SeqVisitor for SeqDeserializer<I>
where I: Iterator<Item=T>,
T: ValueDeserializer,
{
type Error = Error;
fn visit<V>(&mut self) -> Result<Option<V>, Error>
where V: de::Deserialize
{
match self.iter.next() {
Some(value) => {
self.len -= 1;
let mut de = value.deserializer();
Ok(Some(try!(de::Deserialize::deserialize(&mut 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<T> ValueDeserializer for Vec<T>
where T: ValueDeserializer,
{
type Deserializer = SeqDeserializer<vec::IntoIter<T>>;
fn deserializer(self) -> SeqDeserializer<vec::IntoIter<T>> {
let len = self.len();
SeqDeserializer::new(self.into_iter(), len)
}
}
impl<T> ValueDeserializer for BTreeSet<T>
where T: ValueDeserializer + Eq + Ord,
{
type Deserializer = SeqDeserializer<btree_set::IntoIter<T>>;
fn deserializer(self) -> SeqDeserializer<btree_set::IntoIter<T>> {
let len = self.len();
SeqDeserializer::new(self.into_iter(), len)
}
}
impl<T> ValueDeserializer for HashSet<T>
where T: ValueDeserializer + Eq + Hash,
{
type Deserializer = SeqDeserializer<hash_set::IntoIter<T>>;
fn deserializer(self) -> SeqDeserializer<hash_set::IntoIter<T>> {
let len = self.len();
SeqDeserializer::new(self.into_iter(), len)
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct MapDeserializer<I, K, V>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer,
V: ValueDeserializer,
{
iter: I,
value: Option<V>,
len: usize,
}
impl<I, K, V> MapDeserializer<I, K, V>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer,
V: ValueDeserializer,
{
pub fn new(iter: I, len: usize) -> Self {
MapDeserializer {
iter: iter,
value: None,
len: len,
}
}
}
impl<I, K, V> de::Deserializer for MapDeserializer<I, K, V>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer,
V: ValueDeserializer,
{
type Error = Error;
fn visit<V_>(&mut self, mut visitor: V_) -> Result<V_::Value, Error>
where V_: de::Visitor,
{
visitor.visit_map(self)
}
}
impl<I, K, V> de::MapVisitor for MapDeserializer<I, K, V>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer,
V: ValueDeserializer,
{
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);
let mut de = key.deserializer();
Ok(Some(try!(de::Deserialize::deserialize(&mut de))))
}
None => Ok(None),
}
}
fn visit_value<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize,
{
match self.value.take() {
Some(value) => {
let mut de = value.deserializer();
de::Deserialize::deserialize(&mut de)
}
None => Err(de::Error::syntax_error())
}
}
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<K, V> ValueDeserializer for BTreeMap<K, V>
where K: ValueDeserializer + Eq + Ord,
V: ValueDeserializer,
{
type Deserializer = MapDeserializer<btree_map::IntoIter<K, V>, K, V>;
fn deserializer(self) -> MapDeserializer<btree_map::IntoIter<K, V>, K, V> {
let len = self.len();
MapDeserializer::new(self.into_iter(), len)
}
}
impl<K, V> ValueDeserializer for HashMap<K, V>
where K: ValueDeserializer + Eq + Hash,
V: ValueDeserializer,
{
type Deserializer = MapDeserializer<hash_map::IntoIter<K, V>, K, V>;
fn deserializer(self) -> MapDeserializer<hash_map::IntoIter<K, V>, K, V> {
let len = self.len();
MapDeserializer::new(self.into_iter(), len)
}
}
+161 -133
View File
@@ -1,8 +1,10 @@
use std::char;
use std::io;
use std::num::Float;
use unicode::str::Utf16Item;
use std::str;
use unicode::str::Utf16Item;
use de;
use super::error::{Error, ErrorCode};
@@ -11,29 +13,31 @@ pub struct Deserializer<Iter> {
ch: Option<u8>,
line: usize,
col: usize,
buf: Vec<u8>,
str_buf: Vec<u8>,
}
impl<Iter> Deserializer<Iter>
where Iter: Iterator<Item=u8>,
where Iter: Iterator<Item=io::Result<u8>>,
{
/// Creates the JSON parser.
/// Creates the JSON parser from an `std::iter::Iterator`.
#[inline]
pub fn new(rdr: Iter) -> Deserializer<Iter> {
let mut p = Deserializer {
pub fn new(rdr: Iter) -> Result<Deserializer<Iter>, Error> {
let mut deserializer = Deserializer {
rdr: rdr,
ch: Some(b'\x00'),
ch: None,
line: 1,
col: 0,
buf: Vec::with_capacity(128),
str_buf: Vec::with_capacity(128),
};
p.bump();
return p;
try!(deserializer.bump());
Ok(deserializer)
}
#[inline]
pub fn end(&mut self) -> Result<(), Error> {
self.parse_whitespace();
try!(self.parse_whitespace());
if self.eof() {
Ok(())
} else {
@@ -45,8 +49,12 @@ impl<Iter> Deserializer<Iter>
fn ch_or_null(&self) -> u8 { self.ch.unwrap_or(b'\x00') }
fn bump(&mut self) {
self.ch = self.rdr.next();
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,
};
if self.ch_is(b'\n') {
self.line += 1;
@@ -54,11 +62,13 @@ impl<Iter> Deserializer<Iter>
} else {
self.col += 1;
}
Ok(())
}
fn next_char(&mut self) -> Option<u8> {
self.bump();
self.ch
fn next_char(&mut self) -> Result<Option<u8>, Error> {
try!(self.bump());
Ok(self.ch)
}
fn ch_is(&self, c: u8) -> bool {
@@ -69,23 +79,25 @@ impl<Iter> Deserializer<Iter>
Error::SyntaxError(reason, self.line, self.col)
}
fn parse_whitespace(&mut self) {
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') { self.bump(); }
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,
{
self.parse_whitespace();
try!(self.parse_whitespace());
if self.eof() {
return Err(self.error(ErrorCode::EOFWhileParsingValue));
}
match self.ch_or_null() {
let value = match self.ch_or_null() {
b'n' => {
try!(self.parse_ident(b"ull"));
visitor.visit_unit()
@@ -101,46 +113,53 @@ impl<Iter> Deserializer<Iter>
b'0' ... b'9' | b'-' => self.parse_number(visitor),
b'"' => {
try!(self.parse_string());
let s = str::from_utf8(&self.buf).unwrap();
let s = str::from_utf8(&self.str_buf).unwrap();
visitor.visit_str(s)
}
b'[' => {
self.bump();
try!(self.bump());
visitor.visit_seq(SeqVisitor::new(self))
}
b'{' => {
self.bump();
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> {
if ident.iter().all(|c| Some(*c) == self.next_char()) {
self.bump();
Ok(())
} else {
Err(self.error(ErrorCode::ExpectedSomeIdent))
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 = 1;
let mut neg = false;
if self.ch_is(b'-') {
self.bump();
neg = -1;
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 neg = neg as f64;
let mut res = res as f64;
if self.ch_is(b'.') {
@@ -151,18 +170,33 @@ impl<Iter> Deserializer<Iter>
res = try!(self.parse_exponent(res));
}
visitor.visit_f64(neg * res)
if neg {
visitor.visit_f64(-res)
} else {
visitor.visit_f64(res)
}
} else {
visitor.visit_i64(neg * res)
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<i64, Error> {
fn parse_integer(&mut self) -> Result<u64, Error> {
let mut res = 0;
match self.ch_or_null() {
b'0' => {
self.bump();
try!(self.bump());
// There can be only one leading '0'.
match self.ch_or_null() {
@@ -177,8 +211,8 @@ impl<Iter> Deserializer<Iter>
match self.ch_or_null() {
c @ b'0' ... b'9' => {
res *= 10;
res += (c as i64) - (b'0' as i64);
self.bump();
res += (c as u64) - (b'0' as u64);
try!(self.bump());
}
_ => break,
}
@@ -191,7 +225,7 @@ impl<Iter> Deserializer<Iter>
}
fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> {
self.bump();
try!(self.bump());
// Make sure a digit follows the decimal place.
match self.ch_or_null() {
@@ -206,7 +240,7 @@ impl<Iter> Deserializer<Iter>
c @ b'0' ... b'9' => {
dec /= 10.0;
res += (((c as u64) - (b'0' as u64)) as f64) * dec;
self.bump();
try!(self.bump());
}
_ => break,
}
@@ -216,15 +250,15 @@ impl<Iter> Deserializer<Iter>
}
fn parse_exponent(&mut self, mut res: f64) -> Result<f64, Error> {
self.bump();
try!(self.bump());
let mut exp = 0;
let mut neg_exp = false;
if self.ch_is(b'+') {
self.bump();
try!(self.bump());
} else if self.ch_is(b'-') {
self.bump();
try!(self.bump());
neg_exp = true;
}
@@ -239,7 +273,7 @@ impl<Iter> Deserializer<Iter>
exp *= 10;
exp += (c as i32) - (b'0' as i32);
self.bump();
try!(self.bump());
}
_ => break
}
@@ -259,7 +293,7 @@ impl<Iter> Deserializer<Iter>
let mut i = 0;
let mut n = 0u16;
while i < 4 && !self.eof() {
self.bump();
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,
@@ -283,26 +317,26 @@ impl<Iter> Deserializer<Iter>
}
fn parse_string(&mut self) -> Result<(), Error> {
self.buf.clear();
self.str_buf.clear();
let mut escape = false;
loop {
let ch = match self.next_char() {
let ch = match try!(self.next_char()) {
Some(ch) => ch,
None => { return Err(self.error(ErrorCode::EOFWhileParsingString)); }
};
if escape {
match ch {
b'"' => self.buf.push(b'"'),
b'\\' => self.buf.push(b'\\'),
b'/' => self.buf.push(b'/'),
b'b' => self.buf.push(b'\x08'),
b'f' => self.buf.push(b'\x0c'),
b'n' => self.buf.push(b'\n'),
b'r' => self.buf.push(b'\r'),
b't' => self.buf.push(b'\t'),
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 => {
@@ -312,8 +346,8 @@ impl<Iter> Deserializer<Iter>
// Non-BMP characters are encoded as a sequence of
// two hex escapes, representing UTF-16 surrogates.
n1 @ 0xD800 ... 0xDBFF => {
let c1 = self.next_char();
let c2 = self.next_char();
let c1 = try!(self.next_char());
let c2 = try!(self.next_char());
match (c1, c2) {
(Some(b'\\'), Some(b'u')) => (),
_ => {
@@ -340,7 +374,7 @@ impl<Iter> Deserializer<Iter>
let buf = &mut [0; 4];
let len = c.encode_utf8(buf).unwrap_or(0);
self.buf.extend(buf[..len].iter().map(|b| *b));
self.str_buf.extend(buf[..len].iter().map(|b| *b));
}
_ => {
return Err(self.error(ErrorCode::InvalidEscape));
@@ -350,14 +384,14 @@ impl<Iter> Deserializer<Iter>
} else {
match ch {
b'"' => {
self.bump();
try!(self.bump());
return Ok(());
}
b'\\' => {
escape = true;
}
ch => {
self.buf.push(ch);
self.str_buf.push(ch);
}
}
}
@@ -365,10 +399,10 @@ impl<Iter> Deserializer<Iter>
}
fn parse_object_colon(&mut self) -> Result<(), Error> {
self.parse_whitespace();
try!(self.parse_whitespace());
if self.ch_is(b':') {
self.bump();
try!(self.bump());
Ok(())
} else if self.eof() {
Err(self.error(ErrorCode::EOFWhileParsingObject))
@@ -379,7 +413,7 @@ impl<Iter> Deserializer<Iter>
}
impl<Iter> de::Deserializer for Deserializer<Iter>
where Iter: Iterator<Item=u8>,
where Iter: Iterator<Item=io::Result<u8>>,
{
type Error = Error;
@@ -394,7 +428,7 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
self.parse_whitespace();
try!(self.parse_whitespace());
if self.eof() {
return Err(self.error(ErrorCode::EOFWhileParsingValue));
@@ -409,31 +443,26 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
}
#[inline]
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
self.parse_whitespace();
try!(self.parse_whitespace());
if self.ch_is(b'{') {
self.bump();
self.parse_whitespace();
try!(self.bump());
try!(self.parse_whitespace());
try!(self.parse_string());
try!(self.parse_object_colon());
let value = {
try!(visitor.visit(&mut *self))
};
let variant = str::from_utf8(&self.buf).unwrap().to_string();
let value = try!(visitor.visit_variant(&variant, EnumVisitor {
de: self,
}));
self.parse_whitespace();
try!(self.parse_whitespace());
if self.ch_is(b'}') {
self.bump();
try!(self.bump());
Ok(value)
} else {
return Err(self.error(ErrorCode::ExpectedSomeValue));
Err(self.error(ErrorCode::ExpectedSomeValue))
}
} else {
Err(self.error(ErrorCode::ExpectedSomeValue))
@@ -456,17 +485,16 @@ impl<'a, Iter> SeqVisitor<'a, Iter> {
}
impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
where Iter: Iterator<Item=u8>
where Iter: Iterator<Item=io::Result<u8>>,
{
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: de::Deserialize,
{
self.de.parse_whitespace();
try!(self.de.parse_whitespace());
if self.de.ch_is(b']') {
self.de.bump();
return Ok(None);
}
@@ -474,7 +502,7 @@ impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
self.first = false;
} else {
if self.de.ch_is(b',') {
self.de.bump();
try!(self.de.bump());
} else if self.de.eof() {
return Err(self.de.error(ErrorCode::EOFWhileParsingList));
} else {
@@ -487,11 +515,10 @@ impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
}
fn end(&mut self) -> Result<(), Error> {
self.de.parse_whitespace();
try!(self.de.parse_whitespace());
if self.de.ch_is(b']') {
self.de.bump();
Ok(())
self.de.bump()
} else if self.de.eof() {
Err(self.de.error(ErrorCode::EOFWhileParsingList))
} else {
@@ -515,17 +542,16 @@ impl<'a, Iter> MapVisitor<'a, Iter> {
}
impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
where Iter: Iterator<Item=u8>
where Iter: Iterator<Item=io::Result<u8>>
{
type Error = Error;
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
where K: de::Deserialize,
{
self.de.parse_whitespace();
try!(self.de.parse_whitespace());
if self.de.ch_is(b'}') {
self.de.bump();
return Ok(None);
}
@@ -533,8 +559,8 @@ impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
self.first = false;
} else {
if self.de.ch_is(b',') {
self.de.bump();
self.de.parse_whitespace();
try!(self.de.bump());
try!(self.de.parse_whitespace());
} else if self.de.eof() {
return Err(self.de.error(ErrorCode::EOFWhileParsingObject));
} else {
@@ -562,65 +588,52 @@ impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
}
fn end(&mut self) -> Result<(), Error> {
self.de.parse_whitespace();
try!(self.de.parse_whitespace());
if self.de.ch_is(b']') {
self.de.bump();
if self.de.ch_is(b'}') {
try!(self.de.bump());
Ok(())
} else if self.de.eof() {
Err(self.de.error(ErrorCode::EOFWhileParsingList))
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::deserializer(());
Ok(try!(de::Deserialize::deserialize(&mut de)))
}
}
struct EnumVisitor<'a, Iter: 'a> {
de: &'a mut Deserializer<Iter>,
}
impl<'a, Iter> de::EnumVisitor for EnumVisitor<'a, Iter>
where Iter: Iterator<Item=u8>,
impl<Iter> de::VariantVisitor for Deserializer<Iter>
where Iter: Iterator<Item=io::Result<u8>>,
{
type Error = Error;
fn visit_unit(&mut self) -> Result<(), Error> {
de::Deserialize::deserialize(self.de)
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize
{
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
self.de.parse_whitespace();
try!(self.parse_object_colon());
if self.de.ch_is(b'[') {
self.de.bump();
visitor.visit(SeqVisitor::new(self.de))
} else {
Err(self.de.error(ErrorCode::ExpectedSomeValue))
}
}
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor,
{
self.de.parse_whitespace();
if self.de.ch_is(b'{') {
self.de.bump();
visitor.visit(MapVisitor::new(self.de))
} else {
Err(self.de.error(ErrorCode::ExpectedSomeValue))
}
de::Deserializer::visit(self, visitor)
}
}
/// Decodes a json value from an `Iterator<u8>`.
/// Decodes a json value from a `std::io::Read`.
pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
where I: Iterator<Item=u8>,
T: de::Deserialize
where I: Iterator<Item=io::Result<u8>>,
T: de::Deserialize,
{
let mut de = Deserializer::new(iter);
let mut de = try!(Deserializer::new(iter));
let value = try!(de::Deserialize::deserialize(&mut de));
// Make sure the whole stream has been consumed.
@@ -628,9 +641,24 @@ pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
Ok(value)
}
/// Decodes a json value from a string
pub fn from_str<'a, T>(s: &'a str) -> Result<T, Error>
/// 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(s.bytes())
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())
}
+17 -1
View File
@@ -95,7 +95,7 @@ impl error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::SyntaxError(..) => "syntax error",
Error::IoError(ref error) => error.description(),
Error::IoError(ref error) => error::Error::description(error),
/*
Error::ExpectedError(ref expected, _) => &expected,
*/
@@ -145,6 +145,22 @@ impl error::FromError<io::Error> for Error {
}
}
impl error::FromError<de::value::Error> for Error {
fn from_error(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::MissingFieldError(field) => {
de::Error::missing_field_error(field)
}
}
}
}
impl de::Error for Error {
fn syntax_error() -> Error {
Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)
+131
View File
@@ -1,3 +1,134 @@
//! 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::Encoder` object, which implements the
//! `Encoder` trait.
//!
//! # Examples of use
//!
//! ## Using Autoserialization
//!
//! Create a struct called `TestStruct` and serialize and deserialize it to and from JSON using the
//! serialization API, using the derived serialization code.
//!
//! ```rust
//! // Required to use the annotations.
//! #![feature(custom_derive, plugin)]
//! #![plugin(serde_macros)]
//!
//! extern crate serde;
//!
//! use serde::json;
//!
//! // Automatically generate `Serialize` and `Deserialize` trait implementations
//! #[derive(Serialize, Deserialize)]
//! pub struct TestStruct {
//! data_int: u8,
//! data_str: String,
//! data_vector: Vec<u8>,
//! }
//!
//! fn main() {
//! let object = TestStruct {
//! data_int: 1,
//! data_str: "homura".to_string(),
//! data_vector: vec![2,3,4,5],
//! };
//!
//! // Serialize using `json::to_string`
//! let serialized = json::to_string(&object).unwrap();
//!
//! // Deserialize using `json::from_str`
//! let deserialized: TestStruct = json::from_str(&serialized).unwrap();
//! }
//! ```
//!
//! ## 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::{
+178 -140
View File
@@ -6,41 +6,38 @@ use std::string::FromUtf8Error;
use ser;
/// A structure for implementing serialization to JSON.
pub struct Serializer<W> {
pub struct Serializer<W, F=CompactFormatter> {
writer: W,
format: Format,
current_indent: usize,
indent: usize,
formatter: F,
/// `first` is used to signify if we should print a comma when we are walking through a
/// sequence.
first: bool,
}
#[derive(Copy, PartialEq)]
enum Format {
Compact,
Pretty,
}
impl<W: io::Write> Serializer<W> {
impl<W> Serializer<W>
where W: io::Write,
{
/// Creates a new JSON visitr whose output will be written to the writer
/// specified.
#[inline]
pub fn new(writer: W) -> Serializer<W> {
Serializer {
writer: writer,
format: Format::Compact,
current_indent: 0,
indent: 0,
}
Serializer::new_with_formatter(writer, CompactFormatter)
}
}
impl<W, F> Serializer<W, F>
where W: io::Write,
F: Formatter,
{
/// Creates a new JSON visitr whose output will be written to the writer
/// specified.
#[inline]
pub fn new_pretty(writer: W) -> Serializer<W> {
pub fn new_with_formatter(writer: W, formatter: F) -> Serializer<W, F> {
Serializer {
writer: writer,
format: Format::Pretty,
current_indent: 0,
indent: 2,
formatter: formatter,
first: false,
}
}
@@ -51,73 +48,10 @@ impl<W: io::Write> Serializer<W> {
}
}
impl<W: io::Write> ser::Serializer for Serializer<W> {
type Value = ();
type Error = io::Error;
#[inline]
fn visit<T>(&mut self, value: &T) -> io::Result<()>
where T: ser::Serialize,
{
value.visit(&mut Visitor {
writer: &mut self.writer,
format: self.format,
current_indent: self.current_indent,
indent: self.indent,
})
}
}
struct Visitor<'a, W: 'a> {
writer: &'a mut W,
format: Format,
current_indent: usize,
indent: usize,
}
impl<'a, W> Visitor<'a, W> where W: io::Write, {
fn serialize_sep(&mut self, first: bool) -> io::Result<()> {
match self.format {
Format::Compact => {
if first {
Ok(())
} else {
self.writer.write_all(b",")
}
}
Format::Pretty => {
if first {
self.current_indent += self.indent;
try!(self.writer.write_all(b"\n"));
} else {
try!(self.writer.write_all(b",\n"));
}
spaces(&mut self.writer, self.current_indent)
}
}
}
fn serialize_colon(&mut self) -> io::Result<()> {
match self.format {
Format::Compact => self.writer.write_all(b":"),
Format::Pretty => self.writer.write_all(b": "),
}
}
fn serialize_end(&mut self, current_indent: usize, s: &[u8]) -> io::Result<()> {
if self.format == Format::Pretty && current_indent != self.current_indent {
self.current_indent -= self.indent;
try!(self.writer.write(b"\n"));
try!(spaces(&mut self.writer, self.current_indent));
}
self.writer.write_all(s)
}
}
impl<'a, W> ser::Visitor for Visitor<'a, W> where W: io::Write, {
type Value = ();
impl<W, F> ser::Serializer for Serializer<W, F>
where W: io::Write,
F: Formatter,
{
type Error = io::Error;
#[inline]
@@ -131,72 +65,72 @@ impl<'a, W> ser::Visitor for Visitor<'a, W> where W: io::Write, {
#[inline]
fn visit_isize(&mut self, value: isize) -> io::Result<()> {
write!(self.writer, "{}", value)
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i8(&mut self, value: i8) -> io::Result<()> {
write!(self.writer, "{}", value)
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i16(&mut self, value: i16) -> io::Result<()> {
write!(self.writer, "{}", value)
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i32(&mut self, value: i32) -> io::Result<()> {
write!(self.writer, "{}", value)
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_i64(&mut self, value: i64) -> io::Result<()> {
write!(self.writer, "{}", value)
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_usize(&mut self, value: usize) -> io::Result<()> {
write!(self.writer, "{}", value)
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u8(&mut self, value: u8) -> io::Result<()> {
write!(self.writer, "{}", value)
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u16(&mut self, value: u16) -> io::Result<()> {
write!(self.writer, "{}", value)
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u32(&mut self, value: u32) -> io::Result<()> {
write!(self.writer, "{}", value)
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_u64(&mut self, value: u64) -> io::Result<()> {
write!(self.writer, "{}", value)
write!(&mut self.writer, "{}", value)
}
#[inline]
fn visit_f32(&mut self, value: f32) -> io::Result<()> {
fmt_f32_or_null(self.writer, value)
fmt_f32_or_null(&mut self.writer, value)
}
#[inline]
fn visit_f64(&mut self, value: f64) -> io::Result<()> {
fmt_f64_or_null(self.writer, value)
fmt_f64_or_null(&mut self.writer, value)
}
#[inline]
fn visit_char(&mut self, value: char) -> io::Result<()> {
escape_char(self.writer, value)
escape_char(&mut self.writer, value)
}
#[inline]
fn visit_str(&mut self, value: &str) -> io::Result<()> {
escape_str(self.writer, value)
escape_str(&mut self.writer, value)
}
#[inline]
@@ -208,7 +142,7 @@ impl<'a, W> ser::Visitor for Visitor<'a, W> where W: io::Write, {
fn visit_some<V>(&mut self, value: V) -> io::Result<()>
where V: ser::Serialize
{
value.visit(self)
value.serialize(self)
}
#[inline]
@@ -218,88 +152,189 @@ impl<'a, W> ser::Visitor for Visitor<'a, W> where W: io::Write, {
#[inline]
fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> io::Result<()> {
let current_indent = self.current_indent;
try!(self.writer.write_all(b"{"));
try!(self.serialize_sep(true));
try!(self.formatter.open(&mut self.writer, b'{'));
try!(self.formatter.comma(&mut self.writer, true));
try!(self.visit_str(variant));
try!(self.serialize_colon());
try!(self.formatter.colon(&mut self.writer));
try!(self.writer.write_all(b"[]"));
self.serialize_end(current_indent, b"}")
self.formatter.close(&mut self.writer, b'}')
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> io::Result<()>
where V: ser::SeqVisitor,
{
let current_indent = self.current_indent;
match visitor.len() {
Some(len) if len == 0 => {
self.writer.write_all(b"[]")
}
_ => {
try!(self.formatter.open(&mut self.writer, b'['));
try!(self.writer.write_all(b"["));
self.first = true;
while let Some(()) = try!(visitor.visit(self)) { }
while let Some(()) = try!(visitor.visit(self)) { }
self.formatter.close(&mut self.writer, b']')
}
}
self.serialize_end(current_indent, b"]")
}
#[inline]
fn visit_enum_seq<V>(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()>
where V: ser::SeqVisitor,
{
let current_indent = self.current_indent;
try!(self.writer.write_all(b"{"));
try!(self.serialize_sep(true));
try!(self.formatter.open(&mut self.writer, b'{'));
try!(self.formatter.comma(&mut self.writer, true));
try!(self.visit_str(variant));
try!(self.serialize_colon());
try!(self.formatter.colon(&mut self.writer));
try!(self.visit_seq(visitor));
self.serialize_end(current_indent, b"}")
self.formatter.close(&mut self.writer, b'}')
}
#[inline]
fn visit_seq_elt<T>(&mut self, first: bool, value: T) -> io::Result<()>
fn visit_seq_elt<T>(&mut self, value: T) -> io::Result<()>
where T: ser::Serialize,
{
try!(self.serialize_sep(first));
try!(self.formatter.comma(&mut self.writer, self.first));
self.first = false;
value.visit(self)
value.serialize(self)
}
#[inline]
fn visit_map<V>(&mut self, mut visitor: V) -> io::Result<()>
where V: ser::MapVisitor,
{
let current_indent = self.current_indent;
match visitor.len() {
Some(len) if len == 0 => {
self.writer.write_all(b"{}")
}
_ => {
try!(self.formatter.open(&mut self.writer, b'{'));
try!(self.writer.write_all(b"{"));
self.first = true;
while let Some(()) = try!(visitor.visit(self)) { }
while let Some(()) = try!(visitor.visit(self)) { }
self.serialize_end(current_indent, b"}")
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,
{
let current_indent = self.current_indent;
try!(self.writer.write_all(b"{"));
try!(self.serialize_sep(true));
try!(self.formatter.open(&mut self.writer, b'{'));
try!(self.formatter.comma(&mut self.writer, true));
try!(self.visit_str(variant));
try!(self.serialize_colon());
try!(self.formatter.colon(&mut self.writer));
try!(self.visit_map(visitor));
self.serialize_end(current_indent, b"}")
self.formatter.close(&mut self.writer, b'}')
}
#[inline]
fn visit_map_elt<K, V>(&mut self, first: bool, key: K, value: V) -> io::Result<()>
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> io::Result<()>
where K: ser::Serialize,
V: ser::Serialize,
{
try!(self.serialize_sep(first));
try!(key.visit(self));
try!(self.serialize_colon());
value.visit(self)
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)
}
}
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 {
current_indent: usize,
indent: usize,
}
impl Formatter for PrettyFormatter {
fn open<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
where W: io::Write,
{
self.current_indent += self.indent;
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"));
}
spaces(writer, self.current_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 -= self.indent;
try!(writer.write(b"\n"));
try!(spaces(writer, self.current_indent));
writer.write_all(&[ch])
}
}
@@ -381,7 +416,7 @@ pub fn to_writer<W, T>(writer: &mut W, value: &T) -> io::Result<()>
T: ser::Serialize,
{
let mut ser = Serializer::new(writer);
try!(ser::Serializer::visit(&mut ser, value));
try!(value.serialize(&mut ser));
Ok(())
}
@@ -391,8 +426,11 @@ 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::new_pretty(writer);
try!(ser::Serializer::visit(&mut ser, value));
let mut ser = Serializer::new_with_formatter(writer, PrettyFormatter {
current_indent: 0,
indent: 2,
});
try!(value.serialize(&mut ser));
Ok(())
}
+316 -59
View File
@@ -1,6 +1,7 @@
use std::collections::{BTreeMap, btree_map};
use std::fmt;
use std::io;
use std::num;
use std::str;
use std::vec;
@@ -13,25 +14,226 @@ 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.iter() {
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) => num::cast(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) => num::cast(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) => num::cast(n),
Value::U64(n) => num::cast(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 visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: ser::Visitor,
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: ser::Serializer,
{
match *self {
Value::Null => visitor.visit_unit(),
Value::Bool(v) => visitor.visit_bool(v),
Value::I64(v) => visitor.visit_i64(v),
Value::F64(v) => visitor.visit_f64(v),
Value::String(ref v) => visitor.visit_str(&v),
Value::Array(ref v) => v.visit(visitor),
Value::Object(ref v) => v.visit(visitor),
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),
}
}
}
@@ -53,7 +255,16 @@ impl de::Deserialize for Value {
#[inline]
fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
Ok(Value::I64(value))
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]
@@ -94,7 +305,7 @@ impl de::Deserialize for Value {
fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
where V: de::SeqVisitor,
{
let values = try!(de::VecVisitor::new().visit_seq(visitor));
let values = try!(de::impls::VecVisitor::new().visit_seq(visitor));
Ok(Value::Array(values))
}
@@ -102,7 +313,7 @@ impl de::Deserialize for Value {
fn visit_map<V>(&mut self, visitor: V) -> Result<Value, V::Error>
where V: de::MapVisitor,
{
let values = try!(de::BTreeMapVisitor::new().visit_map(visitor));
let values = try!(de::impls::BTreeMapVisitor::new().visit_map(visitor));
Ok(Value::Object(values))
}
}
@@ -163,20 +374,6 @@ impl Serializer {
}
impl ser::Serializer for Serializer {
type Value = ();
type Error = ();
#[inline]
fn visit<T>(&mut self, value: &T) -> Result<(), ()>
where T: ser::Serialize,
{
try!(value.visit(self));
Ok(())
}
}
impl ser::Visitor for Serializer {
type Value = ();
type Error = ();
#[inline]
@@ -187,13 +384,17 @@ impl ser::Visitor for Serializer {
#[inline]
fn visit_i64(&mut self, value: i64) -> Result<(), ()> {
self.state.push(State::Value(Value::I64(value)));
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::I64(value as i64)));
self.state.push(State::Value(Value::U64(value)));
Ok(())
}
@@ -224,7 +425,7 @@ impl ser::Visitor for Serializer {
fn visit_some<V>(&mut self, value: V) -> Result<(), ()>
where V: ser::Serialize,
{
value.visit(self)
value.serialize(self)
}
#[inline]
@@ -247,11 +448,7 @@ impl ser::Visitor for Serializer {
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<(), ()>
where V: ser::SeqVisitor,
{
let len = match visitor.size_hint() {
(_, Some(len)) => len,
(len, None) => len,
};
let len = visitor.len().unwrap_or(0);
let values = Vec::with_capacity(len);
self.state.push(State::Array(values));
@@ -289,10 +486,10 @@ impl ser::Visitor for Serializer {
}
#[inline]
fn visit_seq_elt<T>(&mut self, _first: bool, value: T) -> Result<(), ()>
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), ()>
where T: ser::Serialize,
{
try!(value.visit(self));
try!(value.serialize(self));
let value = match self.state.pop().unwrap() {
State::Value(value) => value,
@@ -348,18 +545,18 @@ impl ser::Visitor for Serializer {
}
#[inline]
fn visit_map_elt<K, V>(&mut self, _first: bool, key: K, value: V) -> Result<(), ()>
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), ()>
where K: ser::Serialize,
V: ser::Serialize,
{
try!(key.visit(self));
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.visit(self));
try!(value.serialize(self));
let value = match self.state.pop().unwrap() {
State::Value(value) => value,
@@ -404,6 +601,7 @@ impl de::Deserializer for Deserializer {
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) => {
@@ -438,8 +636,8 @@ impl de::Deserializer for Deserializer {
}
#[inline]
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
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,
@@ -451,8 +649,10 @@ impl de::Deserializer for Deserializer {
let value = match iter.next() {
Some((variant, Value::Array(fields))) => {
self.value = Some(Value::String(variant));
let len = fields.len();
try!(visitor.visit_variant(&variant, SeqDeserializer {
try!(visitor.visit(SeqDeserializer {
de: self,
iter: fields.into_iter(),
len: len,
@@ -460,10 +660,10 @@ impl de::Deserializer for Deserializer {
}
Some((variant, Value::Object(fields))) => {
let len = fields.len();
try!(visitor.visit_variant(&variant, MapDeserializer {
try!(visitor.visit(MapDeserializer {
de: self,
iter: fields.into_iter(),
value: None,
value: Some(Value::String(variant)),
len: len,
}))
}
@@ -484,6 +684,21 @@ struct SeqDeserializer<'a> {
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;
@@ -513,21 +728,19 @@ impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
}
}
impl<'a> de::EnumVisitor for SeqDeserializer<'a> {
impl<'a> de::VariantVisitor for SeqDeserializer<'a> {
type Error = Error;
fn visit_unit(&mut self) -> Result<(), Error> {
if self.len == 0 {
Ok(())
} else {
Err(de::Error::syntax_error())
}
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
de::Deserialize::deserialize(self.de)
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit(self)
de::Deserializer::visit(self, visitor)
}
}
@@ -571,18 +784,62 @@ impl<'a> de::MapVisitor for MapDeserializer<'a> {
}
}
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::EnumVisitor for MapDeserializer<'a> {
impl<'a> de::Deserializer for MapDeserializer<'a> {
type Error = Error;
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor,
#[inline]
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit(self)
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_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
}
@@ -591,7 +848,7 @@ pub fn to_value<T>(value: &T) -> Value
where T: ser::Serialize
{
let mut ser = Serializer::new();
ser::Serializer::visit(&mut ser, value).ok().unwrap();
value.serialize(&mut ser).ok().unwrap();
ser.unwrap()
}
+2 -1
View File
@@ -1,4 +1,4 @@
#![feature(core, io, path, std_misc, unicode)]
#![feature(collections, convert, core, std_misc, unicode)]
extern crate unicode;
@@ -8,3 +8,4 @@ pub use de::{Deserialize, Deserializer, Error};
pub mod ser;
pub mod de;
pub mod json;
pub mod bytes;
-660
View File
@@ -1,660 +0,0 @@
use std::collections::hash_state::HashState;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::hash::Hash;
use std::path;
use std::rc::Rc;
use std::str;
use std::sync::Arc;
///////////////////////////////////////////////////////////////////////////////
pub trait Serialize {
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor;
}
///////////////////////////////////////////////////////////////////////////////
pub trait Serializer {
type Value;
type Error;
fn visit<T>(&mut self, value: &T) -> Result<Self::Value, Self::Error>
where T: Serialize;
}
///////////////////////////////////////////////////////////////////////////////
pub trait Visitor {
type Value;
type Error;
fn visit_bool(&mut self, v: bool) -> Result<Self::Value, Self::Error>;
#[inline]
fn visit_isize(&mut self, v: isize) -> Result<Self::Value, Self::Error> {
self.visit_i64(v as i64)
}
#[inline]
fn visit_i8(&mut self, v: i8) -> Result<Self::Value, Self::Error> {
self.visit_i64(v as i64)
}
#[inline]
fn visit_i16(&mut self, v: i16) -> Result<Self::Value, Self::Error> {
self.visit_i64(v as i64)
}
#[inline]
fn visit_i32(&mut self, v: i32) -> Result<Self::Value, Self::Error> {
self.visit_i64(v as i64)
}
#[inline]
fn visit_i64(&mut self, v: i64) -> Result<Self::Value, Self::Error>;
#[inline]
fn visit_usize(&mut self, v: usize) -> Result<Self::Value, Self::Error> {
self.visit_u64(v as u64)
}
#[inline]
fn visit_u8(&mut self, v: u8) -> Result<Self::Value, Self::Error> {
self.visit_u64(v as u64)
}
#[inline]
fn visit_u16(&mut self, v: u16) -> Result<Self::Value, Self::Error> {
self.visit_u64(v as u64)
}
#[inline]
fn visit_u32(&mut self, v: u32) -> Result<Self::Value, Self::Error> {
self.visit_u64(v as u64)
}
#[inline]
fn visit_u64(&mut self, v: u64) -> Result<Self::Value, Self::Error>;
#[inline]
fn visit_f32(&mut self, v: f32) -> Result<Self::Value, Self::Error> {
self.visit_f64(v as f64)
}
fn visit_f64(&mut self, v: f64) -> Result<Self::Value, Self::Error>;
#[inline]
fn visit_char(&mut self, v: char) -> Result<Self::Value, Self::Error> {
// The unwraps in here should be safe.
let mut s = &mut [0; 4];
let len = v.encode_utf8(s).unwrap();
self.visit_str(str::from_utf8(&s[..len]).unwrap())
}
fn visit_str(&mut self, value: &str) -> Result<Self::Value, Self::Error>;
fn visit_unit(&mut self) -> Result<Self::Value, Self::Error>;
#[inline]
fn visit_named_unit(&mut self, _name: &str) -> Result<Self::Value, Self::Error> {
self.visit_unit()
}
#[inline]
fn visit_enum_unit(&mut self,
_name: &str,
_variant: &str) -> Result<Self::Value, Self::Error> {
self.visit_unit()
}
fn visit_none(&mut self) -> Result<Self::Value, Self::Error>;
fn visit_some<V>(&mut self, value: V) -> Result<Self::Value, Self::Error>
where V: Serialize;
fn visit_seq<V>(&mut self, visitor: V) -> Result<Self::Value, Self::Error>
where V: SeqVisitor;
#[inline]
fn visit_named_seq<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<Self::Value, 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::Value, Self::Error>
where V: SeqVisitor,
{
self.visit_seq(visitor)
}
fn visit_seq_elt<T>(&mut self,
first: bool,
value: T) -> Result<Self::Value, Self::Error>
where T: Serialize;
fn visit_map<V>(&mut self, visitor: V) -> Result<Self::Value, Self::Error>
where V: MapVisitor;
#[inline]
fn visit_named_map<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<Self::Value, 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::Value, Self::Error>
where V: MapVisitor,
{
self.visit_map(visitor)
}
fn visit_map_elt<K, V>(&mut self,
first: bool,
key: K,
value: V) -> Result<Self::Value, Self::Error>
where K: Serialize,
V: Serialize;
}
pub trait SeqVisitor {
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
where V: Visitor;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
pub trait MapVisitor {
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
where V: Visitor;
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(0, None)
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_visit {
($ty:ty, $method:ident) => {
impl Serialize for $ty {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
visitor.$method(*self)
}
}
}
}
impl_visit!(bool, visit_bool);
impl_visit!(isize, visit_isize);
impl_visit!(i8, visit_i8);
impl_visit!(i16, visit_i16);
impl_visit!(i32, visit_i32);
impl_visit!(i64, visit_i64);
impl_visit!(usize, visit_usize);
impl_visit!(u8, visit_u8);
impl_visit!(u16, visit_u16);
impl_visit!(u32, visit_u32);
impl_visit!(u64, visit_u64);
impl_visit!(f32, visit_f32);
impl_visit!(f64, visit_f64);
impl_visit!(char, visit_char);
///////////////////////////////////////////////////////////////////////////////
impl<'a> Serialize for &'a str {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
visitor.visit_str(*self)
}
}
impl Serialize for String {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(&self[..]).visit(visitor)
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for Option<T> where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
match *self {
Some(ref value) => visitor.visit_some(value),
None => visitor.visit_none(),
}
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct SeqIteratorVisitor<Iter> {
iter: Iter,
first: bool,
}
impl<T, Iter> SeqIteratorVisitor<Iter>
where Iter: Iterator<Item=T>
{
#[inline]
pub fn new(iter: Iter) -> SeqIteratorVisitor<Iter> {
SeqIteratorVisitor {
iter: iter,
first: true,
}
}
}
impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
where T: Serialize,
Iter: Iterator<Item=T>,
{
#[inline]
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
where V: Visitor,
{
let first = self.first;
self.first = false;
match self.iter.next() {
Some(value) => {
let value = try!(visitor.visit_seq_elt(first, value));
Ok(Some(value))
}
None => Ok(None),
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
impl<'a, T> Serialize for &'a [T]
where T: Serialize,
{
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
}
}
impl<T> Serialize for Vec<T> where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(&self[..]).visit(visitor)
}
}
impl<T> Serialize for BTreeSet<T> where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
}
}
impl<T, S> Serialize for HashSet<T, S>
where T: Serialize + Eq + Hash,
S: HashState,
{
#[inline]
fn visit<V: Visitor>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_seq(SeqIteratorVisitor::new(self.iter()))
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for () {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
visitor.visit_unit()
}
}
///////////////////////////////////////////////////////////////////////////////
// FIXME(rust #19630) Remove this work-around
macro_rules! e {
($e:expr) => { $e }
}
macro_rules! tuple_impls {
($(
$TupleVisitor:ident ($len:expr, $($T:ident),+) {
$($state:pat => $idx:tt,)+
}
)+) => {
$(
pub struct $TupleVisitor<'a, $($T: 'a),+> {
tuple: &'a ($($T,)+),
state: u8,
first: bool,
}
impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> {
pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> {
$TupleVisitor {
tuple: tuple,
state: 0,
first: true,
}
}
}
impl<'a, $($T),+> SeqVisitor for $TupleVisitor<'a, $($T),+>
where $($T: Serialize),+
{
fn visit<V>(&mut self, visitor: &mut V) -> Result<Option<V::Value>, V::Error>
where V: Visitor,
{
let first = self.first;
self.first = false;
match self.state {
$(
$state => {
self.state += 1;
Ok(Some(try!(visitor.visit_seq_elt(first, &e!(self.tuple.$idx)))))
}
)+
_ => {
Ok(None)
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
($len, Some($len))
}
}
impl<$($T),+> Serialize for ($($T,)+)
where $($T: Serialize),+
{
#[inline]
fn visit<V: Visitor>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
visitor.visit_seq($TupleVisitor::new(self))
}
}
)+
}
}
tuple_impls! {
TupleVisitor1 (1, T0) {
0 => 0,
}
TupleVisitor2 (2, T0, T1) {
0 => 0,
1 => 1,
}
TupleVisitor3 (3, T0, T1, T2) {
0 => 0,
1 => 1,
2 => 2,
}
TupleVisitor4 (4, T0, T1, T2, T3) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
}
TupleVisitor5 (5, T0, T1, T2, T3, T4) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
}
TupleVisitor6 (6, T0, T1, T2, T3, T4, T5) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
}
TupleVisitor7 (7, T0, T1, T2, T3, T4, T5, T6) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
}
TupleVisitor8 (8, T0, T1, T2, T3, T4, T5, T6, T7) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
}
TupleVisitor9 (9, T0, T1, T2, T3, T4, T5, T6, T7, T8) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
}
TupleVisitor10 (10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
}
TupleVisitor11 (11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
}
TupleVisitor12 (12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct MapIteratorVisitor<Iter> {
iter: Iter,
first: bool,
}
impl<K, V, Iter> MapIteratorVisitor<Iter>
where Iter: Iterator<Item=(K, V)>
{
#[inline]
pub fn new(iter: Iter) -> MapIteratorVisitor<Iter> {
MapIteratorVisitor {
iter: iter,
first: true,
}
}
}
impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
where K: Serialize,
V: Serialize,
I: Iterator<Item=(K, V)>,
{
#[inline]
fn visit<V_>(&mut self, visitor: &mut V_) -> Result<Option<V_::Value>, V_::Error>
where V_: Visitor,
{
let first = self.first;
self.first = false;
match self.iter.next() {
Some((key, value)) => {
let value = try!(visitor.visit_map_elt(first, key, value));
Ok(Some(value))
}
None => Ok(None)
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
///////////////////////////////////////////////////////////////////////////////
impl<K, V> Serialize for BTreeMap<K, V>
where K: Serialize + Ord,
V: Serialize,
{
#[inline]
fn visit<V_: Visitor>(&self, visitor: &mut V_) -> Result<V_::Value, V_::Error> {
visitor.visit_map(MapIteratorVisitor::new(self.iter()))
}
}
impl<K, V, S> Serialize for HashMap<K, V, S>
where K: Serialize + Eq + Hash,
V: Serialize,
S: HashState,
{
#[inline]
fn visit<V_: Visitor>(&self, visitor: &mut V_) -> Result<V_::Value, V_::Error> {
visitor.visit_map(MapIteratorVisitor::new(self.iter()))
}
}
///////////////////////////////////////////////////////////////////////////////
impl<'a, T> Serialize for &'a T where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(**self).visit(visitor)
}
}
impl<'a, T> Serialize for &'a mut T where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(**self).visit(visitor)
}
}
impl<T> Serialize for Box<T> where T: Serialize {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(**self).visit(visitor)
}
}
impl<T> Serialize for Rc<T> where T: Serialize, {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(**self).visit(visitor)
}
}
impl<T> Serialize for Arc<T> where T: Serialize, {
#[inline]
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
(**self).visit(visitor)
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for path::Path {
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
self.to_str().unwrap().visit(visitor)
}
}
impl Serialize for path::PathBuf {
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
where V: Visitor,
{
self.to_str().unwrap().visit(visitor)
}
}
+490
View File
@@ -0,0 +1,490 @@
use std::collections::hash_state::HashState;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecMap};
use std::hash::Hash;
use std::path;
use std::rc::Rc;
use std::sync::Arc;
use super::{
Serialize,
Serializer,
SeqVisitor,
MapVisitor,
};
///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_visit {
($ty:ty, $method:ident) => {
impl Serialize for $ty {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.$method(*self)
}
}
}
}
impl_visit!(bool, visit_bool);
impl_visit!(isize, visit_isize);
impl_visit!(i8, visit_i8);
impl_visit!(i16, visit_i16);
impl_visit!(i32, visit_i32);
impl_visit!(i64, visit_i64);
impl_visit!(usize, visit_usize);
impl_visit!(u8, visit_u8);
impl_visit!(u16, visit_u16);
impl_visit!(u32, visit_u32);
impl_visit!(u64, visit_u64);
impl_visit!(f32, visit_f32);
impl_visit!(f64, visit_f64);
impl_visit!(char, visit_char);
///////////////////////////////////////////////////////////////////////////////
impl<'a> Serialize for &'a str {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_str(*self)
}
}
impl Serialize for String {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(&self[..]).serialize(serializer)
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for Option<T> where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
match *self {
Some(ref value) => serializer.visit_some(value),
None => serializer.visit_none(),
}
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct SeqIteratorVisitor<Iter> {
iter: Iter,
len: Option<usize>,
}
impl<T, Iter> SeqIteratorVisitor<Iter>
where Iter: Iterator<Item=T>
{
#[inline]
pub fn new(iter: Iter, len: Option<usize>) -> SeqIteratorVisitor<Iter> {
SeqIteratorVisitor {
iter: iter,
len: len,
}
}
}
impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
where T: Serialize,
Iter: Iterator<Item=T>,
{
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.iter.next() {
Some(value) => {
let value = try!(serializer.visit_seq_elt(value));
Ok(Some(value))
}
None => Ok(None),
}
}
#[inline]
fn len(&self) -> Option<usize> {
self.len
}
}
///////////////////////////////////////////////////////////////////////////////
impl<'a, T> Serialize for &'a [T]
where T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
impl<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 BTreeSet<T>
where T: Serialize + Ord,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
impl<T, H> Serialize for HashSet<T, H>
where T: Serialize + Eq + Hash,
H: HashState,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for () {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_unit()
}
}
///////////////////////////////////////////////////////////////////////////////
// FIXME(rust #19630) Remove this work-around
macro_rules! e {
($e:expr) => { $e }
}
macro_rules! tuple_impls {
($(
$TupleVisitor:ident ($len:expr, $($T:ident),+) {
$($state:pat => $idx:tt,)+
}
)+) => {
$(
pub struct $TupleVisitor<'a, $($T: 'a),+> {
tuple: &'a ($($T,)+),
state: u8,
}
impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> {
pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> {
$TupleVisitor {
tuple: tuple,
state: 0,
}
}
}
impl<'a, $($T),+> SeqVisitor for $TupleVisitor<'a, $($T),+>
where $($T: Serialize),+
{
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.state {
$(
$state => {
self.state += 1;
Ok(Some(try!(serializer.visit_seq_elt(&e!(self.tuple.$idx)))))
}
)+
_ => {
Ok(None)
}
}
}
fn len(&self) -> Option<usize> {
Some($len)
}
}
impl<$($T),+> Serialize for ($($T,)+)
where $($T: Serialize),+
{
#[inline]
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
serializer.visit_seq($TupleVisitor::new(self))
}
}
)+
}
}
tuple_impls! {
TupleVisitor1 (1, T0) {
0 => 0,
}
TupleVisitor2 (2, T0, T1) {
0 => 0,
1 => 1,
}
TupleVisitor3 (3, T0, T1, T2) {
0 => 0,
1 => 1,
2 => 2,
}
TupleVisitor4 (4, T0, T1, T2, T3) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
}
TupleVisitor5 (5, T0, T1, T2, T3, T4) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
}
TupleVisitor6 (6, T0, T1, T2, T3, T4, T5) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
}
TupleVisitor7 (7, T0, T1, T2, T3, T4, T5, T6) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
}
TupleVisitor8 (8, T0, T1, T2, T3, T4, T5, T6, T7) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
}
TupleVisitor9 (9, T0, T1, T2, T3, T4, T5, T6, T7, T8) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
}
TupleVisitor10 (10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
}
TupleVisitor11 (11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
}
TupleVisitor12 (12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct MapIteratorVisitor<Iter> {
iter: Iter,
len: Option<usize>,
}
impl<K, V, Iter> MapIteratorVisitor<Iter>
where Iter: Iterator<Item=(K, V)>
{
#[inline]
pub fn new(iter: Iter, len: Option<usize>) -> MapIteratorVisitor<Iter> {
MapIteratorVisitor {
iter: iter,
len: len,
}
}
}
impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
where K: Serialize,
V: Serialize,
I: Iterator<Item=(K, V)>,
{
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
match self.iter.next() {
Some((key, value)) => {
let value = try!(serializer.visit_map_elt(key, value));
Ok(Some(value))
}
None => Ok(None)
}
}
#[inline]
fn len(&self) -> Option<usize> {
self.len
}
}
///////////////////////////////////////////////////////////////////////////////
impl<K, V> Serialize for BTreeMap<K, V>
where K: Serialize + Ord,
V: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len())))
}
}
impl<K, V, H> Serialize for HashMap<K, V, H>
where K: Serialize + Eq + Hash,
V: Serialize,
H: HashState,
{
#[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<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> Serialize for &'a T where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(**self).serialize(serializer)
}
}
impl<'a, T> Serialize for &'a mut 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 Box<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 Rc<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 Arc<T> where T: Serialize, {
#[inline]
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
(**self).serialize(serializer)
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for path::Path {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
self.to_str().unwrap().serialize(serializer)
}
}
impl Serialize for path::PathBuf {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer,
{
self.to_str().unwrap().serialize(serializer)
}
}
+205
View File
@@ -0,0 +1,205 @@
use std::str;
pub mod impls;
///////////////////////////////////////////////////////////////////////////////
pub trait Serialize {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: Serializer;
}
///////////////////////////////////////////////////////////////////////////////
pub trait Serializer {
type Error;
/// `visit_bool` serializes a `bool` value.
fn visit_bool(&mut self, v: bool) -> Result<(), Self::Error>;
/// `visit_isize` serializes a `isize` value. By default it casts the value to a `i64` and
/// passes it to the `visit_i64` method.
#[inline]
fn visit_isize(&mut self, v: isize) -> Result<(), Self::Error> {
self.visit_i64(v as i64)
}
/// `visit_i8` serializes a `i8` value. By default it casts the value to a `i64` and
/// passes it to the `visit_i64` method.
#[inline]
fn visit_i8(&mut self, v: i8) -> Result<(), Self::Error> {
self.visit_i64(v as i64)
}
/// `visit_i16` serializes a `i16` value. By default it casts the value to a `i64` and
/// passes it to the `visit_i64` method.
#[inline]
fn visit_i16(&mut self, v: i16) -> Result<(), Self::Error> {
self.visit_i64(v as i64)
}
/// `visit_i32` serializes a `i32` value. By default it casts the value to a `i64` and
/// passes it to the `visit_i64` method.
#[inline]
fn visit_i32(&mut self, v: i32) -> Result<(), Self::Error> {
self.visit_i64(v as i64)
}
/// `visit_i64` serializes a `i64` value.
#[inline]
fn visit_i64(&mut self, v: i64) -> Result<(), Self::Error>;
/// `visit_usize` serializes a `usize` value. By default it casts the value to a `u64` and
/// passes it to the `visit_u64` method.
#[inline]
fn visit_usize(&mut self, v: usize) -> Result<(), Self::Error> {
self.visit_u64(v as u64)
}
/// `visit_u8` serializes a `u8` value. By default it casts the value to a `u64` and passes
/// it to the `visit_u64` method.
#[inline]
fn visit_u8(&mut self, v: u8) -> Result<(), Self::Error> {
self.visit_u64(v as u64)
}
/// `visit_u32` serializes a `u32` value. By default it casts the value to a `u64` and passes
/// it to the `visit_u64` method.
#[inline]
fn visit_u16(&mut self, v: u16) -> Result<(), Self::Error> {
self.visit_u64(v as u64)
}
/// `visit_u32` serializes a `u32` value. By default it casts the value to a `u64` and passes
/// it to the `visit_u64` method.
#[inline]
fn visit_u32(&mut self, v: u32) -> Result<(), Self::Error> {
self.visit_u64(v as u64)
}
/// `visit_u64` serializes a `u64` value.
#[inline]
fn visit_u64(&mut self, v: u64) -> Result<(), Self::Error>;
/// `visit_f32` serializes a `f32` value. By default it casts the value to a `f64` and passes
/// it to the `visit_f64` method.
#[inline]
fn visit_f32(&mut self, v: f32) -> Result<(), Self::Error> {
self.visit_f64(v as f64)
}
/// `visit_f64` serializes a `f64` value.
fn visit_f64(&mut self, v: f64) -> Result<(), Self::Error>;
/// `visit_char` serializes a character. By default it serializes it as a `&str` containing a
/// single character.
#[inline]
fn visit_char(&mut self, v: char) -> Result<(), Self::Error> {
// The unwraps in here should be safe.
let mut s = &mut [0; 4];
let len = v.encode_utf8(s).unwrap();
self.visit_str(str::from_utf8(&s[..len]).unwrap())
}
/// `visit_str` serializes a `&str`.
fn visit_str(&mut self, value: &str) -> Result<(), Self::Error>;
/// `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.
#[inline]
fn visit_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> {
self.visit_seq(impls::SeqIteratorVisitor::new(value.iter(), Some(value.len())))
}
fn visit_unit(&mut self) -> Result<(), Self::Error>;
#[inline]
fn visit_named_unit(&mut self, _name: &str) -> Result<(), Self::Error> {
self.visit_unit()
}
#[inline]
fn visit_enum_unit(&mut self,
_name: &str,
_variant: &str) -> Result<(), Self::Error> {
self.visit_unit()
}
fn visit_none(&mut self) -> Result<(), Self::Error>;
fn visit_some<V>(&mut self, value: V) -> Result<(), Self::Error>
where V: Serialize;
fn visit_seq<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor;
#[inline]
fn visit_named_seq<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.visit_seq(visitor)
}
#[inline]
fn visit_enum_seq<V>(&mut self,
_name: &'static str,
_variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor,
{
self.visit_seq(visitor)
}
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize;
fn visit_map<V>(&mut self, visitor: V) -> Result<(), Self::Error>
where V: MapVisitor;
#[inline]
fn visit_named_map<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.visit_map(visitor)
}
#[inline]
fn visit_enum_map<V>(&mut self,
_name: &'static str,
_variant: &'static str,
visitor: V) -> Result<(), Self::Error>
where V: MapVisitor,
{
self.visit_map(visitor)
}
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
where K: Serialize,
V: Serialize;
}
pub trait SeqVisitor {
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer;
/// Return the length of the sequence if known.
#[inline]
fn len(&self) -> Option<usize> {
None
}
}
pub trait MapVisitor {
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer;
/// Return the length of the map if known.
#[inline]
fn len(&self) -> Option<usize> {
None
}
}
+210
View File
@@ -0,0 +1,210 @@
#![feature(convert, custom_derive, plugin, test)]
#![plugin(serde_macros)]
extern crate test;
extern crate serde;
use serde::Serialize;
use serde::bytes::{ByteBuf, Bytes};
use serde::json;
///////////////////////////////////////////////////////////////////////////////
#[derive(Debug, PartialEq)]
struct Error;
impl serde::de::Error for Error {
fn syntax_error() -> Error { Error }
fn end_of_stream_error() -> Error { Error }
fn missing_field_error(_field: &'static str) -> Error { Error }
}
///////////////////////////////////////////////////////////////////////////////
struct BytesSerializer {
bytes: Vec<u8>,
}
impl BytesSerializer {
fn new(bytes: Vec<u8>) -> Self {
BytesSerializer {
bytes: bytes,
}
}
}
impl serde::Serializer for BytesSerializer {
type Error = Error;
fn visit_unit(&mut self) -> Result<(), Error> {
Err(Error)
}
fn visit_bool(&mut self, _v: bool) -> Result<(), Error> {
Err(Error)
}
fn visit_i64(&mut self, _v: i64) -> Result<(), Error> {
Err(Error)
}
fn visit_u64(&mut self, _v: u64) -> Result<(), Error> {
Err(Error)
}
fn visit_f32(&mut self, _v: f32) -> Result<(), Error> {
Err(Error)
}
fn visit_f64(&mut self, _v: f64) -> Result<(), Error> {
Err(Error)
}
fn visit_char(&mut self, _v: char) -> Result<(), Error> {
Err(Error)
}
fn visit_str(&mut self, _v: &str) -> Result<(), Error> {
Err(Error)
}
fn visit_none(&mut self) -> Result<(), Error> {
Err(Error)
}
fn visit_some<V>(&mut self, _value: V) -> Result<(), Error>
where V: serde::Serialize,
{
Err(Error)
}
fn visit_seq<V>(&mut self, _visitor: V) -> Result<(), Error>
where V: serde::ser::SeqVisitor,
{
Err(Error)
}
fn visit_seq_elt<T>(&mut self, _value: T) -> Result<(), Error>
where T: serde::Serialize
{
Err(Error)
}
fn visit_map<V>(&mut self, _visitor: V) -> Result<(), Error>
where V: serde::ser::MapVisitor,
{
Err(Error)
}
fn visit_map_elt<K, V>(&mut self, _key: K, _value: V) -> Result<(), Error>
where K: serde::Serialize,
V: serde::Serialize,
{
Err(Error)
}
fn visit_bytes(&mut self, bytes: &[u8]) -> Result<(), Error> {
assert_eq!(self.bytes, bytes);
Ok(())
}
}
///////////////////////////////////////////////////////////////////////////////
struct BytesDeserializer {
bytes: Option<Vec<u8>>,
}
impl BytesDeserializer {
fn new(bytes: Vec<u8>) -> Self {
BytesDeserializer {
bytes: Some(bytes),
}
}
}
impl serde::Deserializer for BytesDeserializer {
type Error = Error;
fn visit<V>(&mut self, _visitor: V) -> Result<V::Value, Error>
where V: serde::de::Visitor,
{
Err(Error)
}
fn visit_bytes<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: serde::de::Visitor,
{
visitor.visit_byte_buf(self.bytes.take().unwrap())
}
}
///////////////////////////////////////////////////////////////////////////////
#[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]
fn test_bytes_ser_bytes() {
let buf = vec![];
let bytes = Bytes::from(&buf);
let mut ser = BytesSerializer::new(vec![]);
bytes.serialize(&mut ser).unwrap();
let buf = vec![1, 2, 3];
let bytes = Bytes::from(&buf);
let mut ser = BytesSerializer::new(vec![1, 2, 3]);
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();
assert_eq!(json::from_str("[]").unwrap(), bytes);
let bytes = ByteBuf::from(vec![1, 2, 3]);
assert_eq!(json::from_str("[1, 2, 3]").unwrap(), bytes);
}
#[test]
fn test_byte_buf_de_bytes() {
let mut de = BytesDeserializer::new(vec![]);
let bytes = serde::Deserialize::deserialize(&mut de);
assert_eq!(bytes, Ok(ByteBuf::new()));
let mut de = BytesDeserializer::new(vec![1, 2, 3]);
let bytes = serde::Deserialize::deserialize(&mut de);
assert_eq!(bytes, Ok(ByteBuf::from(vec![1, 2, 3])));
}
+360 -161
View File
@@ -4,14 +4,14 @@
extern crate test;
extern crate serde;
use std::collections::BTreeMap;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::iter;
use std::vec;
use serde::de::{self, Deserialize, Deserializer, Visitor};
#[derive(Debug)]
enum Token<'a> {
enum Token {
Bool(bool),
Isize(isize),
I8(i8),
@@ -26,34 +26,33 @@ enum Token<'a> {
F32(f32),
F64(f64),
Char(char),
Str(&'a str),
Str(&'static str),
String(String),
Option(bool),
Name(&'static str),
Unit,
NamedUnit(&'a str),
SeqStart(usize),
NamedSeqStart(&'a str, usize),
SeqSep(bool),
SeqSep,
SeqEnd,
MapStart(usize),
NamedMapStart(&'a str, usize),
MapSep(bool),
MapSep,
MapEnd,
EnumStart(&'a str, &'a str),
EnumStart(&'static str),
EnumEnd,
}
struct TokenDeserializer<'a> {
tokens: iter::Peekable<vec::IntoIter<Token<'a>>>,
struct TokenDeserializer {
tokens: iter::Peekable<vec::IntoIter<Token>>,
}
impl<'a> TokenDeserializer<'a> {
fn new(tokens: Vec<Token<'a>>) -> TokenDeserializer<'a> {
impl<'a> TokenDeserializer {
fn new(tokens: Vec<Token>) -> TokenDeserializer {
TokenDeserializer {
tokens: tokens.into_iter().peekable(),
}
@@ -65,6 +64,7 @@ enum Error {
SyntaxError,
EndOfStreamError,
MissingFieldError(&'static str),
InvalidName(&'static str),
}
impl de::Error for Error {
@@ -77,7 +77,7 @@ impl de::Error for Error {
}
}
impl<'a> Deserializer for TokenDeserializer<'a> {
impl Deserializer for TokenDeserializer {
type Error = Error;
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
@@ -103,40 +103,19 @@ impl<'a> Deserializer for TokenDeserializer<'a> {
Some(Token::Option(false)) => visitor.visit_none(),
Some(Token::Option(true)) => visitor.visit_some(self),
Some(Token::Unit) => visitor.visit_unit(),
Some(Token::NamedUnit(name)) => visitor.visit_named_unit(name),
Some(Token::SeqStart(len)) => {
visitor.visit_seq(TokenDeserializerSeqVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::NamedSeqStart(name, len)) => {
visitor.visit_named_seq(name, TokenDeserializerSeqVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::MapStart(len)) => {
visitor.visit_map(TokenDeserializerMapVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::NamedMapStart(name, len)) => {
visitor.visit_named_map(name, TokenDeserializerMapVisitor {
de: self,
len: len,
first: true,
})
}
Some(Token::EnumStart(name, variant)) => {
visitor.visit_enum(name, variant, TokenDeserializerEnumVisitor {
de: self,
})
}
Some(Token::Name(_)) => self.visit(visitor),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
@@ -144,7 +123,6 @@ impl<'a> Deserializer for TokenDeserializer<'a> {
/// Hook into `Option` deserializing so we can treat `Unit` as a
/// `None`, or a regular value as `Some(value)`.
#[inline]
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: Visitor,
{
@@ -165,31 +143,97 @@ impl<'a> Deserializer for TokenDeserializer<'a> {
None => Err(Error::EndOfStreamError),
}
}
fn visit_enum<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
match self.tokens.next() {
Some(Token::EnumStart(n)) => {
if name == n {
visitor.visit(TokenDeserializerVariantVisitor {
de: self,
})
} else {
Err(Error::SyntaxError)
}
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn visit_named_unit<V>(&mut self, name: &str, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.tokens.peek() {
Some(&Token::Name(n)) => {
if name == n {
self.tokens.next();
self.visit_seq(visitor)
} else {
Err(Error::InvalidName(n))
}
}
Some(_) => self.visit(visitor),
None => Err(Error::EndOfStreamError),
}
}
fn visit_named_seq<V>(&mut self, name: &str, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.tokens.peek() {
Some(&Token::Name(n)) => {
if name == n {
self.tokens.next();
self.visit_seq(visitor)
} else {
Err(Error::InvalidName(n))
}
}
Some(_) => self.visit_seq(visitor),
None => Err(Error::EndOfStreamError),
}
}
fn visit_named_map<V>(&mut self, name: &str, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.tokens.peek() {
Some(&Token::Name(n)) => {
if name == n {
self.tokens.next();
self.visit_map(visitor)
} else {
Err(Error::InvalidName(n))
}
}
Some(_) => self.visit_map(visitor),
None => Err(Error::EndOfStreamError),
}
}
}
//////////////////////////////////////////////////////////////////////////
struct TokenDeserializerSeqVisitor<'a, 'b: 'a> {
de: &'a mut TokenDeserializer<'b>,
struct TokenDeserializerSeqVisitor<'a> {
de: &'a mut TokenDeserializer,
len: usize,
first: bool,
}
impl<'a, 'b> de::SeqVisitor for TokenDeserializerSeqVisitor<'a, 'b> {
impl<'a> de::SeqVisitor for TokenDeserializerSeqVisitor<'a> {
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: Deserialize,
{
let first = self.first;
self.first = false;
match self.de.tokens.next() {
Some(Token::SeqSep(first_)) if first_ == first => {
match self.de.tokens.peek() {
Some(&Token::SeqSep) => {
self.len -= 1;
self.de.tokens.next();
Ok(Some(try!(Deserialize::deserialize(self.de))))
}
Some(Token::SeqEnd) => Ok(None),
Some(&Token::SeqEnd) => Ok(None),
Some(_) => {
Err(Error::SyntaxError)
}
@@ -198,6 +242,7 @@ impl<'a, 'b> de::SeqVisitor for TokenDeserializerSeqVisitor<'a, 'b> {
}
fn end(&mut self) -> Result<(), Error> {
assert_eq!(self.len, 0);
match self.de.tokens.next() {
Some(Token::SeqEnd) => Ok(()),
Some(_) => Err(Error::SyntaxError),
@@ -212,26 +257,24 @@ impl<'a, 'b> de::SeqVisitor for TokenDeserializerSeqVisitor<'a, 'b> {
//////////////////////////////////////////////////////////////////////////
struct TokenDeserializerMapVisitor<'a, 'b: 'a> {
de: &'a mut TokenDeserializer<'b>,
struct TokenDeserializerMapVisitor<'a> {
de: &'a mut TokenDeserializer,
len: usize,
first: bool,
}
impl<'a, 'b> de::MapVisitor for TokenDeserializerMapVisitor<'a, 'b> {
impl<'a> de::MapVisitor for TokenDeserializerMapVisitor<'a> {
type Error = Error;
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
where K: Deserialize,
{
let first = self.first;
self.first = false;
match self.de.tokens.next() {
Some(Token::MapSep(first_)) if first_ == first => {
match self.de.tokens.peek() {
Some(&Token::MapSep) => {
self.de.tokens.next();
self.len -= 1;
Ok(Some(try!(Deserialize::deserialize(self.de))))
}
Some(Token::MapEnd) => Ok(None),
Some(&Token::MapEnd) => Ok(None),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
@@ -244,6 +287,7 @@ impl<'a, 'b> de::MapVisitor for TokenDeserializerMapVisitor<'a, 'b> {
}
fn end(&mut self) -> Result<(), Error> {
assert_eq!(self.len, 0);
match self.de.tokens.next() {
Some(Token::MapEnd) => Ok(()),
Some(_) => Err(Error::SyntaxError),
@@ -258,89 +302,42 @@ impl<'a, 'b> de::MapVisitor for TokenDeserializerMapVisitor<'a, 'b> {
//////////////////////////////////////////////////////////////////////////
struct TokenDeserializerEnumVisitor<'a, 'b: 'a> {
de: &'a mut TokenDeserializer<'b>,
struct TokenDeserializerVariantVisitor<'a> {
de: &'a mut TokenDeserializer,
}
impl<'a, 'b> de::EnumVisitor for TokenDeserializerEnumVisitor<'a, 'b> {
impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> {
type Error = Error;
fn visit_unit(&mut self) -> Result<(), Error> {
let value = try!(Deserialize::deserialize(self.de));
match self.de.tokens.next() {
Some(Token::EnumEnd) => Ok(value),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
fn visit_variant<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
de::Deserialize::deserialize(self.de)
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
let token = self.de.tokens.next();
match token {
Some(Token::SeqStart(len)) => {
let value = try!(visitor.visit(TokenDeserializerSeqVisitor {
de: self.de,
len: len,
first: true,
}));
match self.de.tokens.next() {
Some(Token::EnumEnd) => Ok(value),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor,
{
match self.de.tokens.next() {
Some(Token::MapStart(len)) => {
let value = try!(visitor.visit(TokenDeserializerMapVisitor {
de: self.de,
len: len,
first: true,
}));
match self.de.tokens.next() {
Some(Token::EnumEnd) => Ok(value),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
de::Deserializer::visit(self.de, visitor)
}
}
//////////////////////////////////////////////////////////////////////////
#[derive(Copy, PartialEq, Debug)]
#[derive_deserialize]
#[derive(Copy, PartialEq, Debug, Deserialize)]
struct NamedUnit;
#[derive(PartialEq, Debug)]
#[derive_deserialize]
#[derive(PartialEq, Debug, Deserialize)]
struct NamedSeq(i32, i32, i32);
#[derive(PartialEq, Debug)]
#[derive_deserialize]
#[derive(PartialEq, Debug, Deserialize)]
struct NamedMap {
a: i32,
b: i32,
c: i32,
}
#[derive(PartialEq, Debug)]
#[derive_deserialize]
#[derive(PartialEq, Debug, Deserialize)]
enum Enum {
Unit,
Seq(i32, i32, i32),
@@ -349,6 +346,19 @@ enum Enum {
//////////////////////////////////////////////////////////////////////////
macro_rules! btreeset {
() => {
BTreeSet::new()
};
($($value:expr),+) => {
{
let mut set = BTreeSet::new();
$(set.insert($value);)+
set
}
}
}
macro_rules! btreemap {
() => {
BTreeMap::new()
@@ -362,6 +372,32 @@ macro_rules! btreemap {
}
}
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
}
}
}
macro_rules! declare_test {
($name:ident { $($value:expr => $tokens:expr,)+ }) => {
#[test]
@@ -448,13 +484,17 @@ declare_tests! {
Token::SeqEnd,
],
() => vec![
Token::NamedSeqStart("Anything", 0),
Token::Name("Anything"),
Token::SeqStart(0),
Token::SeqEnd,
],
}
test_named_unit {
NamedUnit => vec![Token::Unit],
NamedUnit => vec![Token::NamedUnit("NamedUnit")],
NamedUnit => vec![
Token::Name("NamedUnit"),
Token::Unit,
],
NamedUnit => vec![
Token::SeqStart(0),
Token::SeqEnd,
@@ -463,167 +503,325 @@ declare_tests! {
test_named_seq {
NamedSeq(1, 2, 3) => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
NamedSeq(1, 2, 3) => vec![
Token::NamedSeqStart("NamedSeq", 3),
Token::SeqSep(true),
Token::Name("NamedSeq"),
Token::SeqStart(3),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
}
test_btreeset {
BTreeSet::<isize>::new() => vec![
Token::Unit,
],
BTreeSet::<isize>::new() => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
btreeset![btreeset![], btreeset![1], btreeset![2, 3]] => vec![
Token::SeqStart(3),
Token::SeqSep,
Token::SeqStart(0),
Token::SeqEnd,
Token::SeqSep,
Token::SeqStart(1),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
Token::SeqSep,
Token::SeqStart(2),
Token::SeqSep,
Token::I32(2),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
Token::SeqEnd,
],
BTreeSet::<isize>::new() => vec![
Token::Name("Anything"),
Token::Unit,
],
BTreeSet::<isize>::new() => vec![
Token::Name("Anything"),
Token::SeqStart(0),
Token::SeqEnd,
],
}
test_hashset {
HashSet::<isize>::new() => vec![
Token::Unit,
],
HashSet::<isize>::new() => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
hashset![1, 2, 3] => vec![
Token::SeqStart(3),
Token::SeqSep,
Token::I32(1),
Token::SeqSep,
Token::I32(2),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
HashSet::<isize>::new() => vec![
Token::Name("Anything"),
Token::Unit,
],
HashSet::<isize>::new() => vec![
Token::Name("Anything"),
Token::SeqStart(0),
Token::SeqEnd,
],
}
test_vec {
Vec::<isize>::new() => vec![
Token::Unit,
],
Vec::<isize>::new() => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
vec![vec![], vec![1], vec![2, 3]] => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqSep,
Token::SeqStart(0),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqSep,
Token::SeqStart(1),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqSep,
Token::SeqStart(2),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
Token::SeqEnd,
],
Vec::<isize>::new() => vec![
Token::Name("Anything"),
Token::Unit,
],
Vec::<isize>::new() => vec![
Token::Name("Anything"),
Token::SeqStart(0),
Token::SeqEnd,
],
}
test_tuple {
(1,) => vec![
Token::SeqStart(1),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
],
(1, 2, 3) => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
}
test_btreemap {
BTreeMap::<isize, isize>::new() => vec![
Token::Unit,
],
BTreeMap::<isize, isize>::new() => vec![
Token::MapStart(0),
Token::MapEnd,
],
btreemap![1 => 2] => vec![
Token::MapStart(1),
Token::MapSep(true),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapEnd,
],
btreemap![1 => 2, 3 => 4] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapEnd,
],
btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::MapSep,
Token::I32(1),
Token::MapStart(0),
Token::MapEnd,
Token::MapSep(false),
Token::MapSep,
Token::I32(2),
Token::MapStart(2),
Token::MapSep(true),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapSep(false),
Token::MapSep,
Token::I32(5),
Token::I32(6),
Token::MapEnd,
Token::MapEnd,
],
BTreeMap::<isize, isize>::new() => vec![
Token::Name("Anything"),
Token::Unit,
],
BTreeMap::<isize, isize>::new() => vec![
Token::Name("Anything"),
Token::MapStart(0),
Token::MapEnd,
],
}
test_hashmap {
HashMap::<isize, isize>::new() => vec![
Token::Unit,
],
HashMap::<isize, isize>::new() => vec![
Token::MapStart(0),
Token::MapEnd,
],
hashmap![1 => 2] => vec![
Token::MapStart(1),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapEnd,
],
hashmap![1 => 2, 3 => 4] => vec![
Token::MapStart(2),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapEnd,
],
hashmap![1 => hashmap![], 2 => hashmap![3 => 4, 5 => 6]] => vec![
Token::MapStart(2),
Token::MapSep,
Token::I32(1),
Token::MapStart(0),
Token::MapEnd,
Token::MapSep,
Token::I32(2),
Token::MapStart(2),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapSep,
Token::I32(5),
Token::I32(6),
Token::MapEnd,
Token::MapEnd,
],
HashMap::<isize, isize>::new() => vec![
Token::Name("Anything"),
Token::Unit,
],
HashMap::<isize, isize>::new() => vec![
Token::Name("Anything"),
Token::MapStart(0),
Token::MapEnd,
],
}
test_named_map {
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::MapStart(3),
Token::MapSep(true),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
],
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::NamedMapStart("NamedMap", 3),
Token::MapSep(true),
Token::Name("NamedMap"),
Token::MapStart(3),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
],
}
test_enum {
test_enum_unit {
Enum::Unit => vec![
Token::EnumStart("Enum", "Unit"),
Token::EnumStart("Enum"),
Token::Str("Unit"),
Token::Unit,
Token::EnumEnd,
],
}
test_enum_seq {
Enum::Seq(1, 2, 3) => vec![
Token::EnumStart("Enum", "Seq"),
Token::EnumStart("Enum"),
Token::Str("Seq"),
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
Token::EnumEnd,
@@ -631,17 +829,18 @@ declare_tests! {
}
test_enum_map {
Enum::Map { a: 1, b: 2, c: 3 } => vec![
Token::EnumStart("Enum", "Map"),
Token::EnumStart("Enum"),
Token::Str("Map"),
Token::MapStart(3),
Token::MapSep(true),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
+327 -78
View File
@@ -28,9 +28,7 @@ macro_rules! treemap {
})
}
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
enum Animal {
Dog,
Frog(String, Vec<isize>),
@@ -38,18 +36,14 @@ enum Animal {
}
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct Inner {
a: (),
b: usize,
c: Vec<String>,
}
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct Outer {
inner: Vec<Inner>,
}
@@ -144,6 +138,68 @@ fn test_write_list() {
(vec![true, false], "[true,false]"),
]);
test_encode_ok(&[
(vec![vec![], vec![], vec![]], "[[],[],[]]"),
(vec![vec![1, 2, 3], vec![], vec![]], "[[1,2,3],[],[]]"),
(vec![vec![], vec![1, 2, 3], vec![]], "[[],[1,2,3],[]]"),
(vec![vec![], vec![], vec![1, 2, 3]], "[[],[],[1,2,3]]"),
]);
test_pretty_encode_ok(&[
(
vec![vec![], vec![], vec![]],
concat!(
"[\n",
" [],\n",
" [],\n",
" []\n",
"]"
),
),
(
vec![vec![1, 2, 3], vec![], vec![]],
concat!(
"[\n",
" [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ],\n",
" [],\n",
" []\n",
"]"
),
),
(
vec![vec![], vec![1, 2, 3], vec![]],
concat!(
"[\n",
" [],\n",
" [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ],\n",
" []\n",
"]"
),
),
(
vec![vec![], vec![], vec![1, 2, 3]],
concat!(
"[\n",
" [],\n",
" [],\n",
" [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
"]"
),
),
]);
test_pretty_encode_ok(&[
(vec![], "[]"),
(
@@ -207,6 +263,154 @@ fn test_write_object() {
"{\"a\":true,\"b\":false}"),
]);
test_encode_ok(&[
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"{\"a\":{},\"b\":{},\"c\":{}}",
),
(
treemap![
"a".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"{\"a\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"b\":{},\"c\":{}}",
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"c".to_string() => treemap![]
],
"{\"a\":{},\"b\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"c\":{}}",
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
]
],
"{\"a\":{},\"b\":{},\"c\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}}}",
),
]);
test_pretty_encode_ok(&[
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
concat!(
"{\n",
" \"a\": {},\n",
" \"b\": {},\n",
" \"c\": {}\n",
"}",
),
),
(
treemap![
"a".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
concat!(
"{\n",
" \"a\": {\n",
" \"a\": {\n",
" \"a\": [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
"}"
),
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"c".to_string() => treemap![]
],
concat!(
"{\n",
" \"a\": {},\n",
" \"b\": {\n",
" \"a\": {\n",
" \"a\": [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
" },\n",
" \"c\": {}\n",
"}"
),
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
]
],
concat!(
"{\n",
" \"a\": {},\n",
" \"b\": {},\n",
" \"c\": {\n",
" \"a\": {\n",
" \"a\": [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
" }\n",
"}"
),
),
]);
test_pretty_encode_ok(&[
(treemap!(), "{}"),
(
@@ -418,53 +622,56 @@ fn test_write_option() {
]);
}
fn test_parse_ok<'a, T>(errors: &[(&'a str, T)])
where T: PartialEq + Debug + ser::Serialize + de::Deserialize,
fn test_parse_ok<T>(errors: Vec<(&'static str, T)>)
where T: Clone + Debug + PartialEq + ser::Serialize + de::Deserialize,
{
for &(s, ref value) in errors {
let v: T = from_str(s).unwrap();
assert_eq!(v, *value);
for (s, value) in errors {
let v: Result<T, Error> = from_str(s);
assert_eq!(v, Ok(value.clone()));
// Make sure we can deserialize into a `Value`.
let json_value: Value = from_str(s).unwrap();
assert_eq!(json_value, to_value(&value));
let json_value: Result<Value, Error> = from_str(s);
assert_eq!(json_value, Ok(to_value(&value)));
let json_value = json_value.unwrap();
// Make sure we can deserialize from a `Value`.
let v: T = from_value(json_value.clone()).unwrap();
assert_eq!(v, *value);
let v: Result<T, Error> = from_value(json_value.clone());
assert_eq!(v, Ok(value));
// Make sure we can round trip back to `Value`.
let json_value2: Value = from_value(json_value.clone()).unwrap();
assert_eq!(json_value, json_value2);
let json_value2: Result<Value, Error> = from_value(json_value.clone());
assert_eq!(json_value2, Ok(json_value));
}
}
// FIXME (#5527): these could be merged once UFCS is finished.
fn test_parse_err<'a, T>(errors: &[(&'a str, Error)])
where T: Debug + de::Deserialize,
fn test_parse_err<T>(errors: Vec<(&'static str, Error)>)
where T: Debug + PartialEq + de::Deserialize,
{
for &(s, ref err) in errors {
for (s, err) in errors {
let v: Result<T, Error> = from_str(s);
assert_eq!(v.unwrap_err(), *err);
assert_eq!(v, Err(err));
}
}
#[test]
fn test_parse_null() {
test_parse_err::<()>(&[
test_parse_err::<()>(vec![
("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
]);
test_parse_ok(&[
test_parse_ok(vec![
("null", ()),
]);
}
#[test]
fn test_parse_bool() {
test_parse_err::<bool>(&[
test_parse_err::<bool>(vec![
("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
@@ -473,7 +680,7 @@ fn test_parse_bool() {
("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
]);
test_parse_ok(&[
test_parse_ok(vec![
("true", true),
(" true ", true),
("false", false),
@@ -483,7 +690,7 @@ fn test_parse_bool() {
#[test]
fn test_parse_number_errors() {
test_parse_err::<f64>(&[
test_parse_err::<f64>(vec![
("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
(".", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
@@ -497,17 +704,24 @@ fn test_parse_number_errors() {
#[test]
fn test_parse_i64() {
test_parse_ok(&[
("3", 3),
test_parse_ok(vec![
("-2", -2),
("-1234", -1234),
(" -1234 ", -1234),
]);
}
#[test]
fn test_parse_u64() {
test_parse_ok(vec![
("3", 3u64),
("1234", 1234),
]);
}
#[test]
fn test_parse_f64() {
test_parse_ok(&[
test_parse_ok(vec![
("3.0", 3.0f64),
("3.1", 3.1),
("-1.2", -1.2),
@@ -521,13 +735,13 @@ fn test_parse_f64() {
#[test]
fn test_parse_string() {
test_parse_err::<String>(&[
test_parse_err::<String>(vec![
("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 2)),
("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 5)),
("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
]);
test_parse_ok(&[
test_parse_ok(vec![
("\"\"", "".to_string()),
("\"foo\"", "foo".to_string()),
(" \"foo\" ", "foo".to_string()),
@@ -543,7 +757,7 @@ fn test_parse_string() {
#[test]
fn test_parse_list() {
test_parse_err::<Vec<f64>>(&[
test_parse_err::<Vec<f64>>(vec![
("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 3)),
@@ -553,40 +767,40 @@ fn test_parse_list() {
("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
]);
test_parse_ok(&[
test_parse_ok(vec![
("[]", vec![]),
("[ ]", vec![]),
("[null]", vec![()]),
(" [ null ] ", vec![()]),
]);
test_parse_ok(&[
test_parse_ok(vec![
("[true]", vec![true]),
]);
test_parse_ok(&[
("[3,1]", vec![3, 1]),
test_parse_ok(vec![
("[3,1]", vec![3u64, 1]),
(" [ 3 , 1 ] ", vec![3, 1]),
]);
test_parse_ok(&[
("[[3], [1, 2]]", vec![vec![3], vec![1, 2]]),
test_parse_ok(vec![
("[[3], [1, 2]]", vec![vec![3u64], vec![1, 2]]),
]);
test_parse_ok(&[
("[1]", (1,)),
test_parse_ok(vec![
("[1]", (1u64,)),
]);
test_parse_ok(&[
("[1, 2]", (1, 2)),
test_parse_ok(vec![
("[1, 2]", (1u64, 2u64)),
]);
test_parse_ok(&[
("[1, 2, 3]", (1, 2, 3)),
test_parse_ok(vec![
("[1, 2, 3]", (1u64, 2u64, 3u64)),
]);
test_parse_ok(&[
("[1, [2, 3]]", (1, (2, 3))),
test_parse_ok(vec![
("[1, [2, 3]]", (1u64, (2u64, 3u64))),
]);
let v: () = from_str("[]").unwrap();
@@ -595,7 +809,7 @@ fn test_parse_list() {
#[test]
fn test_parse_object() {
test_parse_err::<BTreeMap<String, u32>>(&[
test_parse_err::<BTreeMap<String, u32>>(vec![
("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)),
@@ -610,12 +824,12 @@ fn test_parse_object() {
("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
]);
test_parse_ok(&[
test_parse_ok(vec![
("{}", treemap!()),
("{ }", treemap!()),
(
"{\"a\":3}",
treemap!("a".to_string() => 3)
treemap!("a".to_string() => 3u64)
),
(
"{ \"a\" : 3 }",
@@ -631,23 +845,28 @@ fn test_parse_object() {
),
]);
test_parse_ok(&[
test_parse_ok(vec![
(
"{\"a\": {\"b\": 3, \"c\": 4}}",
treemap!("a".to_string() => treemap!("b".to_string() => 3, "c".to_string() => 4)),
treemap!(
"a".to_string() => treemap!(
"b".to_string() => 3u64,
"c".to_string() => 4
)
),
),
]);
}
#[test]
fn test_parse_struct() {
test_parse_err::<Outer>(&[
("[]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{}", Error::MissingFieldError("inner")),
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
test_parse_err::<Outer>(vec![
("5", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)),
("\"hello\"", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 15)),
]);
test_parse_ok(&[
test_parse_ok(vec![
(
"{
\"inner\": []
@@ -669,44 +888,52 @@ fn test_parse_struct() {
},
)
]);
assert_eq!(
from_str("{}"),
Ok(Outer {
inner: vec![],
})
);
}
#[test]
fn test_parse_option() {
test_parse_ok(&[
test_parse_ok(vec![
("null", None::<String>),
("\"jodhpurs\"", Some("jodhpurs".to_string())),
]);
#[derive(PartialEq, Debug)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
struct Foo {
x: Option<isize>,
}
/*
let value: Foo = from_str("{}").unwrap();
assert_eq!(value, Foo { x: None });
*/
test_parse_ok(&[
test_parse_ok(vec![
("{\"x\": null}", Foo { x: None }),
("{\"x\": 5}", Foo { x: Some(5) }),
]);
}
#[test]
fn test_parse_enum() {
test_parse_err::<Animal>(&[
("{}", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 3)),
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)),
("{\"Frog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
("{\"Cat\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
fn test_parse_enum_errors() {
test_parse_err::<Animal>(vec![
("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)),
("{\"Dog\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 8)),
("{\"Dog\":}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 11)),
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
("{\"Frog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 10)),
("{\"Cat\":[]}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
]);
}
test_parse_ok(&[
#[test]
fn test_parse_enum() {
test_parse_ok(vec![
("{\"Dog\":[]}", Animal::Dog),
(" { \"Dog\" : [ ] } ", Animal::Dog),
(
@@ -727,7 +954,7 @@ fn test_parse_enum() {
),
]);
test_parse_ok(&[
test_parse_ok(vec![
(
concat!(
"{",
@@ -745,8 +972,8 @@ fn test_parse_enum() {
#[test]
fn test_parse_trailing_whitespace() {
test_parse_ok(&[
("[1, 2] ", vec![1, 2]),
test_parse_ok(vec![
("[1, 2] ", vec![1u64, 2]),
("[1, 2]\n", vec![1, 2]),
("[1, 2]\t", vec![1, 2]),
("[1, 2]\t \n", vec![1, 2]),
@@ -755,7 +982,29 @@ fn test_parse_trailing_whitespace() {
#[test]
fn test_multiline_errors() {
test_parse_err::<BTreeMap<String, String>>(&[
test_parse_err::<BTreeMap<String, String>>(vec![
("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 8)),
]);
}
#[test]
fn test_missing_field() {
#[derive(Debug, PartialEq, Deserialize)]
struct Foo {
x: Option<u32>,
}
let value: Foo = from_str("{}").unwrap();
assert_eq!(value, Foo { x: None });
let value: Foo = from_str("{\"x\": 5}").unwrap();
assert_eq!(value, Foo { x: Some(5) });
let value: Foo = from_value(Value::Object(treemap!())).unwrap();
assert_eq!(value, Foo { x: None });
let value: Foo = from_value(Value::Object(treemap!(
"x".to_string() => Value::I64(5)
))).unwrap();
assert_eq!(value, Foo { x: Some(5) });
}
+6 -6
View File
@@ -15,12 +15,12 @@ fn test_array_builder() {
.push(2)
.push(3)
.unwrap();
assert_eq!(value, Value::Array(vec!(Value::I64(1), Value::I64(2), Value::I64(3))));
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::I64(1), Value::I64(2), Value::I64(3))))));
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|
@@ -30,8 +30,8 @@ fn test_array_builder() {
.unwrap();
let mut map = BTreeMap::new();
map.insert("a".to_string(), Value::I64(1));
map.insert("b".to_string(), Value::I64(2));
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))));
}
@@ -46,7 +46,7 @@ fn test_object_builder() {
.unwrap();
let mut map = BTreeMap::new();
map.insert("a".to_string(), Value::I64(1));
map.insert("b".to_string(), Value::I64(2));
map.insert("a".to_string(), Value::U64(1));
map.insert("b".to_string(), Value::U64(2));
assert_eq!(value, Value::Object(map));
}
+99 -69
View File
@@ -25,13 +25,30 @@ trait Trait {
}
*/
#[derive(Debug, PartialEq)]
#[derive_serialize]
#[derive_deserialize]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct NamedUnit;
#[derive(Debug, PartialEq)]
#[derive_serialize]
#[derive(Debug, PartialEq, Serialize)]
struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
#[derive(Debug, PartialEq, Deserialize)]
struct DeNamedTuple<A, B, C>(A, B, C);
#[derive(Debug, PartialEq, Serialize)]
struct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> {
a: &'a A,
b: &'b mut B,
c: C,
}
#[derive(Debug, PartialEq, Deserialize)]
struct DeNamedMap<A, B, C> {
a: A,
b: B,
c: C,
}
#[derive(Debug, PartialEq, Serialize)]
enum SerEnum<'a, B: 'a, C: /* Trait + */ 'a, D> where D: /* Trait + */ 'a {
Unit,
Seq(
@@ -50,10 +67,28 @@ enum SerEnum<'a, B: 'a, C: /* Trait + */ 'a, D> where D: /* Trait + */ 'a {
e: &'a mut D,
//f: <D as Trait>::Type,
},
// Make sure we can support more than one variant.
_Unit2,
_Seq2(
i8,
B,
&'a C,
//C::Type,
&'a mut D,
//<D as Trait>::Type,
),
_Map2 {
a: i8,
b: B,
c: &'a C,
//d: C::Type,
e: &'a mut D,
//f: <D as Trait>::Type,
},
}
#[derive(Debug, PartialEq)]
#[derive_deserialize]
#[derive(Debug, PartialEq, Deserialize)]
enum DeEnum<B, C: /* Trait */, D> /* where D: Trait */ {
Unit,
Seq(
@@ -72,6 +107,25 @@ enum DeEnum<B, C: /* Trait */, D> /* where D: Trait */ {
e: D,
//f: <D as Trait>::Type,
},
// Make sure we can support more than one variant.
_Unit2,
_Seq2(
i8,
B,
C,
//C::Type,
D,
//<D as Trait>::Type,
),
_Map2 {
a: i8,
b: B,
c: C,
//d: C::Type,
e: D,
//f: <D as Trait>::Type,
},
}
#[test]
@@ -97,14 +151,10 @@ fn test_named_unit() {
#[test]
fn test_ser_named_tuple() {
#[derive(Debug, PartialEq)]
#[derive_serialize]
struct NamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
let a = 5;
let mut b = 6;
let c = 7;
let named_tuple = NamedTuple(&a, &mut b, c);
let named_tuple = SerNamedTuple(&a, &mut b, c);
assert_eq!(
json::to_string(&named_tuple).unwrap(),
@@ -113,45 +163,33 @@ fn test_ser_named_tuple() {
assert_eq!(
json::to_value(&named_tuple),
Value::Array(vec![Value::I64(5), Value::I64(6), Value::I64(7)])
Value::Array(vec![Value::U64(5), Value::U64(6), Value::U64(7)])
);
}
#[test]
fn test_de_named_tuple() {
#[derive(Debug, PartialEq)]
#[derive_deserialize]
struct NamedTuple<A, B, C>(A, B, C);
assert_eq!(
json::from_str("[1,2,3]").unwrap(),
NamedTuple(1, 2, 3)
DeNamedTuple(1, 2, 3)
);
assert_eq!(
json::from_str("[1,2,3]").unwrap(),
Value::Array(vec![
Value::I64(1),
Value::I64(2),
Value::I64(3),
Value::U64(1),
Value::U64(2),
Value::U64(3),
])
);
}
#[test]
fn test_ser_named_map() {
#[derive(Debug, PartialEq)]
#[derive_serialize]
struct NamedMap<'a, 'b, A: 'a, B: 'b, C> {
a: &'a A,
b: &'b mut B,
c: C,
}
let a = 5;
let mut b = 6;
let c = 7;
let named_map = NamedMap {
let named_map = SerNamedMap {
a: &a,
b: &mut b,
c: c,
@@ -165,24 +203,16 @@ fn test_ser_named_map() {
assert_eq!(
json::to_value(&named_map),
Value::Object(btreemap![
"a".to_string() => Value::I64(5),
"b".to_string() => Value::I64(6),
"c".to_string() => Value::I64(7)
"a".to_string() => Value::U64(5),
"b".to_string() => Value::U64(6),
"c".to_string() => Value::U64(7)
])
);
}
#[test]
fn test_de_named_map() {
#[derive(Debug, PartialEq)]
#[derive_deserialize]
struct NamedMap<A, B, C> {
a: A,
b: B,
c: C,
}
let v = NamedMap {
let v = DeNamedMap {
a: 5,
b: 6,
c: 7,
@@ -195,9 +225,9 @@ fn test_de_named_map() {
assert_eq!(
json::from_value(Value::Object(btreemap![
"a".to_string() => Value::I64(5),
"b".to_string() => Value::I64(6),
"c".to_string() => Value::I64(7)
"a".to_string() => Value::U64(5),
"b".to_string() => Value::U64(6),
"c".to_string() => Value::U64(7)
])).unwrap(),
v
);
@@ -250,12 +280,12 @@ fn test_ser_enum_seq() {
)),
Value::Object(btreemap!(
"Seq".to_string() => Value::Array(vec![
Value::I64(1),
Value::I64(2),
Value::I64(3),
//Value::I64(4),
Value::I64(5),
//Value::I64(6),
Value::U64(1),
Value::U64(2),
Value::U64(3),
//Value::U64(4),
Value::U64(5),
//Value::U64(6),
])
))
);
@@ -293,12 +323,12 @@ fn test_ser_enum_map() {
}),
Value::Object(btreemap!(
"Map".to_string() => Value::Object(btreemap![
"a".to_string() => Value::I64(1),
"b".to_string() => Value::I64(2),
"c".to_string() => Value::I64(3),
//"d".to_string() => Value::I64(4)
"e".to_string() => Value::I64(5)
//"f".to_string() => Value::I64(6)
"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)
])
))
);
@@ -343,12 +373,12 @@ fn test_de_enum_seq() {
assert_eq!(
json::from_value(Value::Object(btreemap!(
"Seq".to_string() => Value::Array(vec![
Value::I64(1),
Value::I64(2),
Value::I64(3),
//Value::I64(4),
Value::I64(5),
//Value::I64(6),
Value::U64(1),
Value::U64(2),
Value::U64(3),
//Value::U64(4),
Value::U64(5),
//Value::U64(6),
])
))).unwrap(),
DeEnum::Seq(
@@ -386,12 +416,12 @@ fn test_de_enum_map() {
assert_eq!(
json::from_value(Value::Object(btreemap!(
"Map".to_string() => Value::Object(btreemap![
"a".to_string() => Value::I64(1),
"b".to_string() => Value::I64(2),
"c".to_string() => Value::I64(3),
//"d".to_string() => Value::I64(4)
"e".to_string() => Value::I64(5)
//"f".to_string() => Value::I64(6)
"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(),
DeEnum::Map {
+77 -93
View File
@@ -7,7 +7,7 @@ extern crate serde;
use std::vec;
use std::collections::BTreeMap;
use serde::ser::{Serialize, Serializer, Visitor, SeqVisitor, MapVisitor};
use serde::ser::{Serialize, Serializer, SeqVisitor, MapVisitor};
#[derive(Clone, PartialEq, Debug)]
pub enum Token<'a> {
@@ -33,16 +33,16 @@ pub enum Token<'a> {
NamedUnit(&'a str),
EnumUnit(&'a str, &'a str),
SeqStart(usize),
NamedSeqStart(&'a str, usize),
EnumSeqStart(&'a str, &'a str, usize),
SeqSep(bool),
SeqStart(Option<usize>),
NamedSeqStart(&'a str, Option<usize>),
EnumSeqStart(&'a str, &'a str, Option<usize>),
SeqSep,
SeqEnd,
MapStart(usize),
NamedMapStart(&'a str, usize),
EnumMapStart(&'a str, &'a str, usize),
MapSep(bool),
MapStart(Option<usize>),
NamedMapStart(&'a str, Option<usize>),
EnumMapStart(&'a str, &'a str, Option<usize>),
MapSep,
MapEnd,
}
@@ -79,16 +79,6 @@ impl<'a> AssertSerializer<'a> {
}
impl<'a> Serializer for AssertSerializer<'a> {
type Value = ();
type Error = ();
fn visit<T: Serialize>(&mut self, value: &T) -> Result<(), ()> {
value.visit(self)
}
}
impl<'a> Visitor for AssertSerializer<'a> {
type Value = ();
type Error = ();
fn visit_unit(&mut self) -> Result<(), ()> {
@@ -190,14 +180,14 @@ impl<'a> Visitor for AssertSerializer<'a> {
where V: Serialize,
{
assert_eq!(self.iter.next(), Some(Token::Option(true)));
value.visit(self)
value.serialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let (len, _) = visitor.size_hint();
let len = visitor.len();
assert_eq!(self.iter.next(), Some(Token::SeqStart(len)));
@@ -207,7 +197,7 @@ impl<'a> Visitor for AssertSerializer<'a> {
fn visit_named_seq<V>(&mut self, name: &str, visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let (len, _) = visitor.size_hint();
let len = visitor.len();
assert_eq!(self.iter.next().unwrap(), Token::NamedSeqStart(name, len));
@@ -220,24 +210,24 @@ impl<'a> Visitor for AssertSerializer<'a> {
visitor: V) -> Result<(), ()>
where V: SeqVisitor
{
let (len, _) = visitor.size_hint();
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, first: bool, value: T) -> Result<(), ()>
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), ()>
where T: Serialize
{
assert_eq!(self.iter.next(), Some(Token::SeqSep(first)));
value.visit(self)
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.size_hint();
let len = visitor.len();
assert_eq!(self.iter.next(), Some(Token::MapStart(len)));
@@ -247,56 +237,50 @@ impl<'a> Visitor for AssertSerializer<'a> {
fn visit_named_map<V>(&mut self, name: &str, visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let (len, _) = visitor.size_hint();
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<(), ()>
fn visit_enum_map<V>(&mut self, name: &str, variant: &str, visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let (len, _) = visitor.size_hint();
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,
first: bool,
key: K,
value: V) -> Result<(), ()>
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(first)));
assert_eq!(self.iter.next(), Some(Token::MapSep));
try!(key.visit(self));
value.visit(self)
try!(key.serialize(self));
value.serialize(self)
}
}
//////////////////////////////////////////////////////////////////////////
#[derive_serialize]
#[derive(Serialize)]
struct NamedUnit;
#[derive_serialize]
#[derive(Serialize)]
struct NamedSeq(i32, i32, i32);
#[derive_serialize]
#[derive(Serialize)]
struct NamedMap {
a: i32,
b: i32,
c: i32,
}
#[derive_serialize]
#[derive(Serialize)]
enum Enum {
Unit,
Seq(i32, i32),
@@ -324,7 +308,7 @@ macro_rules! declare_test {
fn $name() {
$(
let mut ser = AssertSerializer::new($tokens);
assert_eq!(ser.visit(&$value), Ok(()));
assert_eq!($value.serialize(&mut ser), Ok(()));
)+
}
}
@@ -380,45 +364,45 @@ declare_tests! {
}
test_slice {
&[0][..0] => vec![
Token::SeqStart(0),
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
&[1, 2, 3][..] => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
}
test_vec {
Vec::<isize>::new() => vec![
Token::SeqStart(0),
Token::SeqStart(Some(0)),
Token::SeqEnd,
],
vec![vec![], vec![1], vec![2, 3]] => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqStart(0),
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::SeqStart(Some(0)),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqStart(1),
Token::SeqSep(true),
Token::SeqSep,
Token::SeqStart(Some(1)),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqStart(2),
Token::SeqSep(true),
Token::SeqSep,
Token::SeqStart(Some(2)),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
Token::SeqEnd,
@@ -426,58 +410,58 @@ declare_tests! {
}
test_tuple {
(1,) => vec![
Token::SeqStart(1),
Token::SeqSep(true),
Token::SeqStart(Some(1)),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
],
(1, 2, 3) => vec![
Token::SeqStart(3),
Token::SeqSep(true),
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
}
test_btreemap {
btreemap![1 => 2] => vec![
Token::MapStart(1),
Token::MapSep(true),
Token::MapStart(Some(1)),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapEnd,
],
btreemap![1 => 2, 3 => 4] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::MapStart(Some(2)),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapEnd,
],
btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![
Token::MapStart(2),
Token::MapSep(true),
Token::MapStart(Some(2)),
Token::MapSep,
Token::I32(1),
Token::MapStart(0),
Token::MapStart(Some(0)),
Token::MapEnd,
Token::MapSep(false),
Token::MapSep,
Token::I32(2),
Token::MapStart(2),
Token::MapSep(true),
Token::MapStart(Some(2)),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapSep(false),
Token::MapSep,
Token::I32(5),
Token::I32(6),
Token::MapEnd,
@@ -489,30 +473,30 @@ declare_tests! {
}
test_named_seq {
NamedSeq(1, 2, 3) => vec![
Token::NamedSeqStart("NamedSeq", 3),
Token::SeqSep(true),
Token::NamedSeqStart("NamedSeq", Some(3)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
}
test_named_map {
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::NamedMapStart("NamedMap", 3),
Token::MapSep(true),
Token::NamedMapStart("NamedMap", Some(3)),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
@@ -521,21 +505,21 @@ declare_tests! {
test_enum {
Enum::Unit => vec![Token::EnumUnit("Enum", "Unit")],
Enum::Seq(1, 2) => vec![
Token::EnumSeqStart("Enum", "Seq", 2),
Token::SeqSep(true),
Token::EnumSeqStart("Enum", "Seq", Some(2)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqEnd,
],
Enum::Map { a: 1, b: 2 } => vec![
Token::EnumMapStart("Enum", "Map", 2),
Token::MapSep(true),
Token::EnumMapStart("Enum", "Map", Some(2)),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapEnd,