mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-26 10:57:55 +00:00
Fix #[derive_serialize] for enums
This commit is contained in:
+59
-54
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user