Fix #[derive_serialize] for enums

This commit is contained in:
Erick Tryzelaar
2015-02-18 22:59:16 -08:00
parent 65cfcd03f8
commit 3fac47e01c
10 changed files with 527 additions and 786 deletions
+59 -54
View File
@@ -4,10 +4,9 @@ use unicode::str::Utf16Item;
use std::str;
use de;
use de::Deserializer;
use super::error::{Error, ErrorCode};
pub struct Parser<Iter> {
pub struct Deserializer<Iter> {
rdr: Iter,
ch: Option<u8>,
line: usize,
@@ -15,11 +14,11 @@ pub struct Parser<Iter> {
buf: Vec<u8>,
}
impl<Iter: Iterator<Item=u8>> Parser<Iter> {
impl<Iter: Iterator<Item=u8>> Deserializer<Iter> {
/// Creates the JSON parser.
#[inline]
pub fn new(rdr: Iter) -> Parser<Iter> {
let mut p = Parser {
pub fn new(rdr: Iter) -> Deserializer<Iter> {
let mut p = Deserializer {
rdr: rdr,
ch: Some(b'\x00'),
line: 1,
@@ -111,11 +110,17 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
}
b'[' => {
self.bump();
visitor.visit_seq(SeqVisitor { parser: self, first: true })
visitor.visit_seq(SeqVisitor {
de: self,
first: true,
})
}
b'{' => {
self.bump();
visitor.visit_map(MapVisitor { parser: self, first: true })
visitor.visit_map(MapVisitor {
de: self,
first: true,
})
}
_ => {
Err(self.error(ErrorCode::ExpectedSomeValue))
@@ -377,7 +382,7 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
}
}
impl<Iter: Iterator<Item=u8>> Deserializer for Parser<Iter> {
impl<Iter: Iterator<Item=u8>> de::Deserializer for Deserializer<Iter> {
type Error = Error;
#[inline]
@@ -389,7 +394,7 @@ impl<Iter: Iterator<Item=u8>> Deserializer for Parser<Iter> {
}
struct SeqVisitor<'a, Iter: 'a> {
parser: &'a mut Parser<Iter>,
de: &'a mut Deserializer<Iter>,
first: bool,
}
@@ -399,43 +404,43 @@ impl<'a, Iter: Iterator<Item=u8>> de::SeqVisitor for SeqVisitor<'a, Iter> {
fn visit<
T: de::Deserialize,
>(&mut self) -> Result<Option<T>, Error> {
self.parser.parse_whitespace();
self.de.parse_whitespace();
if self.parser.ch_is(b']') {
self.parser.bump();
if self.de.ch_is(b']') {
self.de.bump();
return Ok(None);
}
if self.first {
self.first = false;
} else {
if self.parser.ch_is(b',') {
self.parser.bump();
} else if self.parser.eof() {
return Err(self.parser.error(ErrorCode::EOFWhileParsingList));
if self.de.ch_is(b',') {
self.de.bump();
} else if self.de.eof() {
return Err(self.de.error(ErrorCode::EOFWhileParsingList));
} else {
return Err(self.parser.error(ErrorCode::ExpectedListCommaOrEnd));
return Err(self.de.error(ErrorCode::ExpectedListCommaOrEnd));
}
}
let value = try!(de::Deserialize::deserialize(self.parser));
let value = try!(de::Deserialize::deserialize(self.de));
Ok(Some(value))
}
fn end(&mut self) -> Result<(), Error> {
if self.parser.ch_is(b']') {
self.parser.bump();
if self.de.ch_is(b']') {
self.de.bump();
Ok(())
} else if self.parser.eof() {
Err(self.parser.error(ErrorCode::EOFWhileParsingList))
} else if self.de.eof() {
Err(self.de.error(ErrorCode::EOFWhileParsingList))
} else {
Err(self.parser.error(ErrorCode::TrailingCharacters))
Err(self.de.error(ErrorCode::TrailingCharacters))
}
}
}
struct MapVisitor<'a, Iter: 'a> {
parser: &'a mut Parser<Iter>,
de: &'a mut Deserializer<Iter>,
first: bool,
}
@@ -445,63 +450,63 @@ impl<'a, Iter: Iterator<Item=u8>> de::MapVisitor for MapVisitor<'a, Iter> {
fn visit_key<
K: de::Deserialize,
>(&mut self) -> Result<Option<K>, Error> {
self.parser.parse_whitespace();
self.de.parse_whitespace();
if self.parser.ch_is(b'}') {
self.parser.bump();
if self.de.ch_is(b'}') {
self.de.bump();
return Ok(None);
}
if self.first {
self.first = false;
} else {
if self.parser.ch_is(b',') {
self.parser.bump();
self.parser.parse_whitespace();
} else if self.parser.eof() {
return Err(self.parser.error(ErrorCode::EOFWhileParsingObject));
if self.de.ch_is(b',') {
self.de.bump();
self.de.parse_whitespace();
} else if self.de.eof() {
return Err(self.de.error(ErrorCode::EOFWhileParsingObject));
} else {
return Err(self.parser.error(ErrorCode::ExpectedObjectCommaOrEnd));
return Err(self.de.error(ErrorCode::ExpectedObjectCommaOrEnd));
}
}
if self.parser.eof() {
return Err(self.parser.error(ErrorCode::EOFWhileParsingValue));
if self.de.eof() {
return Err(self.de.error(ErrorCode::EOFWhileParsingValue));
}
if !self.parser.ch_is(b'"') {
return Err(self.parser.error(ErrorCode::KeyMustBeAString));
if !self.de.ch_is(b'"') {
return Err(self.de.error(ErrorCode::KeyMustBeAString));
}
Ok(Some(try!(de::Deserialize::deserialize(self.parser))))
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
}
fn visit_value<
V: de::Deserialize,
>(&mut self) -> Result<V, Error> {
self.parser.parse_whitespace();
self.de.parse_whitespace();
if self.parser.ch_is(b':') {
self.parser.bump();
} else if self.parser.eof() {
return Err(self.parser.error(ErrorCode::EOFWhileParsingObject));
if self.de.ch_is(b':') {
self.de.bump();
} else if self.de.eof() {
return Err(self.de.error(ErrorCode::EOFWhileParsingObject));
} else {
return Err(self.parser.error(ErrorCode::ExpectedColon));
return Err(self.de.error(ErrorCode::ExpectedColon));
}
self.parser.parse_whitespace();
self.de.parse_whitespace();
Ok(try!(de::Deserialize::deserialize(self.parser)))
Ok(try!(de::Deserialize::deserialize(self.de)))
}
fn end(&mut self) -> Result<(), Error> {
if self.parser.ch_is(b']') {
self.parser.bump();
if self.de.ch_is(b']') {
self.de.bump();
Ok(())
} else if self.parser.eof() {
Err(self.parser.error(ErrorCode::EOFWhileParsingList))
} else if self.de.eof() {
Err(self.de.error(ErrorCode::EOFWhileParsingList))
} else {
Err(self.parser.error(ErrorCode::TrailingCharacters))
Err(self.de.error(ErrorCode::TrailingCharacters))
}
}
}
@@ -511,11 +516,11 @@ pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
where I: Iterator<Item=u8>,
T: de::Deserialize
{
let mut parser = Parser::new(iter);
let value = try!(de::Deserialize::deserialize(&mut parser));
let mut de = Deserializer::new(iter);
let value = try!(de::Deserialize::deserialize(&mut de));
// Make sure the whole stream has been consumed.
try!(parser.end());
try!(de.end());
Ok(value)
}
+4 -5
View File
@@ -1,8 +1,7 @@
pub use self::ser::Writer;
pub use self::ser::{to_vec, to_string};
pub use self::ser::escape_str;
pub use self::de::from_str;
pub use self::de::{Deserializer, from_str};
pub use self::error::{Error, ErrorCode};
pub use self::ser::{Serializer, to_vec, to_string, escape_str};
pub use self::value::{Value, to_value, from_value};
pub mod builder;
pub mod de;
+9 -9
View File
@@ -3,31 +3,31 @@ use std::io;
use std::num::{Float, FpCategory};
use std::string::FromUtf8Error;
use ser::{self, Serializer};
use ser;
/// A structure for implementing serialization to JSON.
pub struct Writer<W> {
pub struct Serializer<W> {
writer: W,
}
impl<W: io::Write> Writer<W> {
impl<W: io::Write> Serializer<W> {
/// Creates a new JSON visitr whose output will be written to the writer
/// specified.
#[inline]
pub fn new(writer: W) -> Writer<W> {
Writer {
pub fn new(writer: W) -> Serializer<W> {
Serializer {
writer: writer,
}
}
/// Unwrap the Writer from the Serializer.
/// Unwrap the `Writer` from the `Serializer`.
#[inline]
pub fn into_inner(self) -> W {
self.writer
}
}
impl<W: io::Write> ser::Serializer for Writer<W> {
impl<W: io::Write> ser::Serializer for Serializer<W> {
type Value = ();
type Error = io::Error;
@@ -278,8 +278,8 @@ pub fn to_writer<W, T>(writer: &mut W, value: &T) -> io::Result<()>
where W: io::Write,
T: ser::Serialize,
{
let mut writer = Writer::new(writer);
try!(writer.visit(value));
let mut ser = Serializer::new(writer);
try!(ser::Serializer::visit(&mut ser, value));
Ok(())
}
+178 -35
View File
@@ -1,9 +1,12 @@
use std::collections::BTreeMap;
use std::collections::{BTreeMap, btree_map};
use std::fmt;
use std::io;
use std::str;
use std::vec;
use ser::{self, Serializer};
use de;
use ser;
use super::error::Error;
#[derive(PartialEq)]
pub enum Value {
@@ -22,27 +25,13 @@ impl ser::Serialize for Value {
V: ser::Visitor,
>(&self, visitor: &mut V) -> Result<V::Value, V::Error> {
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 => 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),
}
}
}
@@ -72,25 +61,19 @@ impl fmt::Debug for Value {
}
}
pub fn to_value<T>(value: &T) -> Value where T: ser::Serialize {
let mut writer = Writer::new();
writer.visit(value).ok().unwrap();
writer.unwrap()
}
enum State {
Value(Value),
Array(Vec<Value>),
Object(BTreeMap<String, Value>),
}
pub struct Writer {
pub struct Serializer {
state: Vec<State>,
}
impl Writer {
pub fn new() -> Writer {
Writer {
impl Serializer {
pub fn new() -> Serializer {
Serializer {
state: Vec::with_capacity(4),
}
}
@@ -103,7 +86,7 @@ impl Writer {
}
}
impl ser::Serializer for Writer {
impl ser::Serializer for Serializer {
type Value = ();
type Error = ();
@@ -116,7 +99,7 @@ impl ser::Serializer for Writer {
}
}
impl ser::Visitor for Writer {
impl ser::Visitor for Serializer {
type Value = ();
type Error = ();
@@ -264,3 +247,163 @@ impl ser::Visitor for Writer {
Ok(())
}
}
pub struct Deserializer {
value: Option<Value>,
}
impl Deserializer {
/// Creates a new deserializer instance for deserializing the specified JSON value.
pub fn new(value: Value) -> Deserializer {
Deserializer {
value: Some(value),
}
}
}
impl de::Deserializer for Deserializer {
type Error = Error;
#[inline]
fn visit<
V: de::Visitor,
>(&mut self, visitor: &mut V) -> Result<V::Value, Error> {
let value = match self.value.take() {
Some(value) => value,
None => { return Err(de::Error::end_of_stream_error()); }
};
match value {
Value::Null => visitor.visit_unit(),
Value::Bool(v) => visitor.visit_bool(v),
Value::I64(v) => visitor.visit_i64(v),
Value::F64(v) => visitor.visit_f64(v),
Value::String(v) => visitor.visit_string(v),
Value::Array(v) => {
let len = v.len();
visitor.visit_seq(SeqDeserializer {
de: self,
iter: v.into_iter(),
len: len,
})
}
Value::Object(v) => {
let len = v.len();
visitor.visit_map(MapDeserializer {
de: self,
iter: v.into_iter(),
value: None,
len: len,
})
}
}
}
#[inline]
fn visit_option<
V: de::Visitor,
>(&mut self, visitor: &mut V) -> Result<V::Value, Error> {
match self.value {
Some(Value::Null) => visitor.visit_none(),
Some(_) => visitor.visit_some(self),
None => Err(de::Error::end_of_stream_error()),
}
}
}
struct SeqDeserializer<'a> {
de: &'a mut Deserializer,
iter: vec::IntoIter<Value>,
len: usize,
}
impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: de::Deserialize
{
match self.iter.next() {
Some(value) => {
self.len -= 1;
self.de.value = Some(value);
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
}
None => Ok(None),
}
}
fn end(&mut self) -> Result<(), Error> {
if self.len == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream_error())
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
struct MapDeserializer<'a> {
de: &'a mut Deserializer,
iter: btree_map::IntoIter<String, Value>,
value: Option<Value>,
len: usize,
}
impl<'a> de::MapVisitor for MapDeserializer<'a> {
type Error = Error;
fn visit_key<T>(&mut self) -> Result<Option<T>, Error>
where T: de::Deserialize
{
match self.iter.next() {
Some((key, value)) => {
self.len -= 1;
self.value = Some(value);
self.de.value = Some(Value::String(key));
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
}
None => Ok(None),
}
}
fn visit_value<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize
{
let value = self.value.take().unwrap();
self.de.value = Some(value);
Ok(try!(de::Deserialize::deserialize(self.de)))
}
fn end(&mut self) -> Result<(), Error> {
if self.len == 0 {
Ok(())
} else {
Err(de::Error::end_of_stream_error())
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
/// Shortcut function to encode a `T` into a JSON `Value`
pub fn to_value<T>(value: &T) -> Value
where T: ser::Serialize
{
let mut ser = Serializer::new();
ser::Serializer::visit(&mut ser, value).ok().unwrap();
ser.unwrap()
}
/// Shortcut function to decode a JSON `Value` into a `T`
pub fn from_value<T>(value: Value) -> Result<T, Error>
where T: de::Deserialize
{
let mut de = Deserializer::new(value);
de::Deserialize::deserialize(&mut de)
}