mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-22 22:58:02 +00:00
805a3435cf
Closes #26!
605 lines
16 KiB
Rust
605 lines
16 KiB
Rust
use std::collections::{BTreeMap, btree_map};
|
|
use std::fmt;
|
|
use std::io;
|
|
use std::str;
|
|
use std::vec;
|
|
|
|
use de;
|
|
use ser;
|
|
use super::error::Error;
|
|
|
|
#[derive(Clone, PartialEq)]
|
|
pub enum Value {
|
|
Null,
|
|
Bool(bool),
|
|
I64(i64),
|
|
F64(f64),
|
|
String(String),
|
|
Array(Vec<Value>),
|
|
Object(BTreeMap<String, Value>),
|
|
}
|
|
|
|
impl ser::Serialize for Value {
|
|
#[inline]
|
|
fn visit<V>(&self, visitor: &mut V) -> Result<V::Value, V::Error>
|
|
where V: ser::Visitor,
|
|
{
|
|
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),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl de::Deserialize for Value {
|
|
#[inline]
|
|
fn deserialize<D>(deserializer: &mut D) -> Result<Value, D::Error>
|
|
where D: de::Deserializer,
|
|
{
|
|
struct ValueVisitor;
|
|
|
|
impl de::Visitor for ValueVisitor {
|
|
type Value = Value;
|
|
|
|
#[inline]
|
|
fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
|
|
Ok(Value::Bool(value))
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
|
|
Ok(Value::I64(value))
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_f64<E>(&mut self, value: f64) -> Result<Value, E> {
|
|
Ok(Value::F64(value))
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_str<E>(&mut self, value: &str) -> Result<Value, E>
|
|
where E: de::Error,
|
|
{
|
|
self.visit_string(value.to_string())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_string<E>(&mut self, value: String) -> Result<Value, E> {
|
|
Ok(Value::String(value))
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_none<E>(&mut self) -> Result<Value, E> {
|
|
Ok(Value::Null)
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_some<D>(&mut self, deserializer: &mut D) -> Result<Value, D::Error>
|
|
where D: de::Deserializer,
|
|
{
|
|
de::Deserialize::deserialize(deserializer)
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_unit<E>(&mut self) -> Result<Value, E> {
|
|
Ok(Value::Null)
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
|
|
where V: de::SeqVisitor,
|
|
{
|
|
let values = try!(de::VecVisitor::new().visit_seq(visitor));
|
|
Ok(Value::Array(values))
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_map<V>(&mut self, visitor: V) -> Result<Value, V::Error>
|
|
where V: de::MapVisitor,
|
|
{
|
|
let values = try!(de::BTreeMapVisitor::new().visit_map(visitor));
|
|
Ok(Value::Object(values))
|
|
}
|
|
}
|
|
|
|
deserializer.visit(ValueVisitor)
|
|
}
|
|
}
|
|
|
|
struct WriterFormatter<'a, 'b: 'a> {
|
|
inner: &'a mut fmt::Formatter<'b>,
|
|
}
|
|
|
|
impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> {
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
match self.inner.write_str(str::from_utf8(buf).unwrap()) {
|
|
Ok(_) => Ok(buf.len()),
|
|
Err(_) => Err(io::Error::last_os_error()),
|
|
}
|
|
}
|
|
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl fmt::Debug for Value {
|
|
/// Serializes a json value into a string
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
let mut wr = WriterFormatter { inner: f };
|
|
super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
enum State {
|
|
Value(Value),
|
|
Array(Vec<Value>),
|
|
Object(BTreeMap<String, Value>),
|
|
}
|
|
|
|
pub struct Serializer {
|
|
state: Vec<State>,
|
|
}
|
|
|
|
impl Serializer {
|
|
pub fn new() -> Serializer {
|
|
Serializer {
|
|
state: Vec::with_capacity(4),
|
|
}
|
|
}
|
|
|
|
pub fn unwrap(mut self) -> Value {
|
|
match self.state.pop().unwrap() {
|
|
State::Value(value) => value,
|
|
state => panic!("expected value, found {:?}", state),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ser::Serializer for Serializer {
|
|
type 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]
|
|
fn visit_bool(&mut self, value: bool) -> Result<(), ()> {
|
|
self.state.push(State::Value(Value::Bool(value)));
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_i64(&mut self, value: i64) -> Result<(), ()> {
|
|
self.state.push(State::Value(Value::I64(value)));
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_u64(&mut self, value: u64) -> Result<(), ()> {
|
|
self.state.push(State::Value(Value::I64(value as i64)));
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_f64(&mut self, value: f64) -> Result<(), ()> {
|
|
self.state.push(State::Value(Value::F64(value as f64)));
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_char(&mut self, value: char) -> Result<(), ()> {
|
|
self.state.push(State::Value(Value::String(value.to_string())));
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_str(&mut self, value: &str) -> Result<(), ()> {
|
|
self.state.push(State::Value(Value::String(value.to_string())));
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_none(&mut self) -> Result<(), ()> {
|
|
self.visit_unit()
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_some<V>(&mut self, value: V) -> Result<(), ()>
|
|
where V: ser::Serialize,
|
|
{
|
|
value.visit(self)
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_unit(&mut self) -> Result<(), ()> {
|
|
self.state.push(State::Value(Value::Null));
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> Result<(), ()> {
|
|
let mut values = BTreeMap::new();
|
|
values.insert(variant.to_string(), Value::Array(vec![]));
|
|
|
|
self.state.push(State::Value(Value::Object(values)));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<(), ()>
|
|
where V: ser::SeqVisitor,
|
|
{
|
|
let len = match visitor.size_hint() {
|
|
(_, Some(len)) => len,
|
|
(len, None) => len,
|
|
};
|
|
|
|
let values = Vec::with_capacity(len);
|
|
|
|
self.state.push(State::Array(values));
|
|
|
|
while let Some(()) = try!(visitor.visit(self)) { }
|
|
|
|
let values = match self.state.pop().unwrap() {
|
|
State::Array(values) => values,
|
|
state => panic!("Expected array, found {:?}", state),
|
|
};
|
|
|
|
self.state.push(State::Value(Value::Array(values)));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_enum_seq<V>(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()>
|
|
where V: ser::SeqVisitor,
|
|
{
|
|
try!(self.visit_seq(visitor));
|
|
|
|
let value = match self.state.pop().unwrap() {
|
|
State::Value(value) => value,
|
|
state => panic!("expected value, found {:?}", state),
|
|
};
|
|
|
|
let mut object = BTreeMap::new();
|
|
|
|
object.insert(variant.to_string(), value);
|
|
|
|
self.state.push(State::Value(Value::Object(object)));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_seq_elt<T>(&mut self, _first: bool, value: T) -> Result<(), ()>
|
|
where T: ser::Serialize,
|
|
{
|
|
try!(value.visit(self));
|
|
|
|
let value = match self.state.pop().unwrap() {
|
|
State::Value(value) => value,
|
|
state => panic!("expected value, found {:?}", state),
|
|
};
|
|
|
|
match *self.state.last_mut().unwrap() {
|
|
State::Array(ref mut values) => { values.push(value); }
|
|
ref state => panic!("expected array, found {:?}", state),
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_map<V>(&mut self, mut visitor: V) -> Result<(), ()>
|
|
where V: ser::MapVisitor,
|
|
{
|
|
let values = BTreeMap::new();
|
|
|
|
self.state.push(State::Object(values));
|
|
|
|
while let Some(()) = try!(visitor.visit(self)) { }
|
|
|
|
let values = match self.state.pop().unwrap() {
|
|
State::Object(values) => values,
|
|
state => panic!("expected object, found {:?}", state),
|
|
};
|
|
|
|
self.state.push(State::Value(Value::Object(values)));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_enum_map<V>(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()>
|
|
where V: ser::MapVisitor,
|
|
{
|
|
try!(self.visit_map(visitor));
|
|
|
|
let value = match self.state.pop().unwrap() {
|
|
State::Value(value) => value,
|
|
state => panic!("expected value, found {:?}", state),
|
|
};
|
|
|
|
let mut object = BTreeMap::new();
|
|
|
|
object.insert(variant.to_string(), value);
|
|
|
|
self.state.push(State::Value(Value::Object(object)));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_map_elt<K, V>(&mut self, _first: bool, key: K, value: V) -> Result<(), ()>
|
|
where K: ser::Serialize,
|
|
V: ser::Serialize,
|
|
{
|
|
try!(key.visit(self));
|
|
|
|
let key = match self.state.pop().unwrap() {
|
|
State::Value(Value::String(value)) => value,
|
|
state => panic!("expected key, found {:?}", state),
|
|
};
|
|
|
|
try!(value.visit(self));
|
|
|
|
let value = match self.state.pop().unwrap() {
|
|
State::Value(value) => value,
|
|
state => panic!("expected value, found {:?}", state),
|
|
};
|
|
|
|
match *self.state.last_mut().unwrap() {
|
|
State::Object(ref mut values) => { values.insert(key, value); }
|
|
ref state => panic!("expected object, found {:?}", state),
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub struct Deserializer {
|
|
value: Option<Value>,
|
|
}
|
|
|
|
impl Deserializer {
|
|
/// Creates a new deserializer instance for deserializing the specified JSON value.
|
|
pub fn new(value: Value) -> Deserializer {
|
|
Deserializer {
|
|
value: Some(value),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl de::Deserializer for Deserializer {
|
|
type Error = Error;
|
|
|
|
#[inline]
|
|
fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
where V: de::Visitor,
|
|
{
|
|
let value = match self.value.take() {
|
|
Some(value) => value,
|
|
None => { return Err(de::Error::end_of_stream_error()); }
|
|
};
|
|
|
|
match value {
|
|
Value::Null => visitor.visit_unit(),
|
|
Value::Bool(v) => visitor.visit_bool(v),
|
|
Value::I64(v) => visitor.visit_i64(v),
|
|
Value::F64(v) => visitor.visit_f64(v),
|
|
Value::String(v) => visitor.visit_string(v),
|
|
Value::Array(v) => {
|
|
let len = v.len();
|
|
visitor.visit_seq(SeqDeserializer {
|
|
de: self,
|
|
iter: v.into_iter(),
|
|
len: len,
|
|
})
|
|
}
|
|
Value::Object(v) => {
|
|
let len = v.len();
|
|
visitor.visit_map(MapDeserializer {
|
|
de: self,
|
|
iter: v.into_iter(),
|
|
value: None,
|
|
len: len,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
where V: de::Visitor,
|
|
{
|
|
match self.value {
|
|
Some(Value::Null) => visitor.visit_none(),
|
|
Some(_) => visitor.visit_some(self),
|
|
None => Err(de::Error::end_of_stream_error()),
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
where V: de::Visitor,
|
|
{
|
|
let value = match self.value.take() {
|
|
Some(Value::Object(value)) => value,
|
|
Some(_) => { return Err(de::Error::syntax_error()); }
|
|
None => { return Err(de::Error::end_of_stream_error()); }
|
|
};
|
|
|
|
let mut iter = value.into_iter();
|
|
|
|
let value = match iter.next() {
|
|
Some((variant, Value::Array(fields))) => {
|
|
let len = fields.len();
|
|
try!(visitor.visit_variant(&variant, SeqDeserializer {
|
|
de: self,
|
|
iter: fields.into_iter(),
|
|
len: len,
|
|
}))
|
|
}
|
|
Some((variant, Value::Object(fields))) => {
|
|
let len = fields.len();
|
|
try!(visitor.visit_variant(&variant, MapDeserializer {
|
|
de: self,
|
|
iter: fields.into_iter(),
|
|
value: None,
|
|
len: len,
|
|
}))
|
|
}
|
|
Some(_) => { return Err(de::Error::syntax_error()); }
|
|
None => { return Err(de::Error::syntax_error()); }
|
|
};
|
|
|
|
match iter.next() {
|
|
Some(_) => Err(de::Error::syntax_error()),
|
|
None => Ok(value)
|
|
}
|
|
}
|
|
}
|
|
|
|
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))
|
|
}
|
|
}
|
|
|
|
impl<'a> de::EnumVisitor 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_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
where V: de::EnumSeqVisitor,
|
|
{
|
|
visitor.visit(self)
|
|
}
|
|
}
|
|
|
|
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))
|
|
}
|
|
}
|
|
|
|
impl<'a> de::EnumVisitor for MapDeserializer<'a> {
|
|
type Error = Error;
|
|
|
|
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
where V: de::EnumMapVisitor,
|
|
{
|
|
visitor.visit(self)
|
|
}
|
|
}
|
|
|
|
/// 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)
|
|
}
|