mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-23 01:18:02 +00:00
Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 45bd239202 | |||
| 54009e0991 | |||
| bfe7a04c4d | |||
| 3167da72d8 | |||
| 0d725a63b0 | |||
| ee0cd4aba9 | |||
| 1b1c605102 | |||
| 44edfa5974 | |||
| aa8d13456a | |||
| 4beb86ab7e | |||
| c369010d3d | |||
| 1618faed63 | |||
| 9059b734aa | |||
| 89f463111e | |||
| 2962287703 | |||
| aa3c55fd98 | |||
| 17c295680e | |||
| 09de237033 | |||
| d17846eff1 | |||
| 5378d22708 | |||
| c8b2ad01b5 | |||
| e778c7e25c | |||
| f0d0dd2982 | |||
| 3e63d34c00 | |||
| 8821421357 | |||
| eb4af09456 | |||
| 78137ee3a4 | |||
| b40d8f7bac | |||
| a6ba251ef9 | |||
| c6cc2340c8 | |||
| a212ef11a9 | |||
| 7bd4c6963b | |||
| f21cbb71e2 | |||
| f4f8194f46 | |||
| 90e02206fe | |||
| 9fc9d1b33a | |||
| b9f5d22630 | |||
| cbafc83af4 | |||
| b628446768 | |||
| aacc14ad7b | |||
| 35eb234c41 | |||
| 989c8ff809 | |||
| 49c2585a20 | |||
| 9972478066 | |||
| 00287bd055 | |||
| 11f47bd51f | |||
| 5e98a83717 | |||
| ec8b7c9b89 | |||
| 008ce75ae5 | |||
| 5c62b7ed06 | |||
| 99f4efd313 | |||
| 87ff636c10 | |||
| d2bd361d9c | |||
| 5a32d420cd | |||
| a3b2f00c92 | |||
| 13fcf1ad5b | |||
| 8cb2ff6e2e | |||
| c917941ec3 | |||
| f699d29fb3 | |||
| 6723097a3f | |||
| 80e27344f1 | |||
| f244e0f522 | |||
| 61317f5935 | |||
| 9ca1e2a8f7 | |||
| aedd5f57cf | |||
| dc87288f48 | |||
| 5dd53e7ea3 | |||
| 9e454a243a | |||
| 3f62b6d2bf | |||
| fbd6d1974a |
+14
-11
@@ -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=
|
||||
|
||||
+5
-7
@@ -1,16 +1,14 @@
|
||||
[package]
|
||||
name = "serde"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A serialization/deserialization framework"
|
||||
repository = "https://github.com/erickt/rust-serde"
|
||||
|
||||
[lib]
|
||||
name = "serde"
|
||||
|
||||
[dependencies]
|
||||
[dev-dependencies]
|
||||
rustc-serialize = "*"
|
||||
|
||||
[dev-dependencies]
|
||||
serde_macros = "0.2.1"
|
||||
[dev-dependencies.serde_macros]
|
||||
path = "serde_macros/"
|
||||
version = "0.3.0"
|
||||
|
||||
+61
-24
@@ -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
@@ -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();
|
||||
|
||||
@@ -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
@@ -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));
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_macros"
|
||||
version = "0.2.1"
|
||||
version = "0.3.0"
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "Macros to auto-generate implementations for the serde framework"
|
||||
@@ -11,6 +11,6 @@ name = "serde_macros"
|
||||
plugin = true
|
||||
|
||||
[dependencies]
|
||||
quasi = "0.1.3"
|
||||
quasi_macros = "0.1.3"
|
||||
aster = "0.1.3"
|
||||
aster = "*"
|
||||
quasi = "*"
|
||||
quasi_macros = "*"
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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) });
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user