Replace serde1 with serde2!

Closes #26!
This commit is contained in:
Erick Tryzelaar
2015-03-08 22:56:33 -07:00
parent 6726bd12ae
commit 805a3435cf
48 changed files with 4635 additions and 15428 deletions
+20 -71
View File
@@ -10,7 +10,8 @@
use std::collections::BTreeMap;
use json::value::{ToJson, Value};
use ser::{self, Serialize};
use json::value::{self, Value};
pub struct ArrayBuilder {
array: Vec<Value>,
@@ -25,24 +26,25 @@ impl ArrayBuilder {
Value::Array(self.array)
}
pub fn push<T: ToJson>(self, value: T) -> ArrayBuilder {
let mut builder = self;
builder.array.push(value.to_json());
builder
pub fn push<T: ser::Serialize>(mut self, v: T) -> ArrayBuilder {
self.array.push(value::to_value(&v));
self
}
pub fn push_array<F>(self, f: F) -> ArrayBuilder where
pub fn push_array<F>(mut self, f: F) -> ArrayBuilder where
F: FnOnce(ArrayBuilder) -> ArrayBuilder
{
let builder = ArrayBuilder::new();
self.push(f(builder).unwrap())
self.array.push(f(builder).unwrap());
self
}
pub fn push_object<F>(self, f: F) -> ArrayBuilder where
pub fn push_object<F>(mut self, f: F) -> ArrayBuilder where
F: FnOnce(ObjectBuilder) -> ObjectBuilder
{
let builder = ObjectBuilder::new();
self.push(f(builder).unwrap())
self.array.push(f(builder).unwrap());
self
}
}
@@ -59,77 +61,24 @@ impl ObjectBuilder {
Value::Object(self.object)
}
pub fn insert<V: ToJson>(self, key: String, value: V) -> ObjectBuilder {
let mut builder = self;
builder.object.insert(key, value.to_json());
builder
pub fn insert<V: ser::Serialize>(mut self, k: String, v: V) -> ObjectBuilder {
self.object.insert(k, value::to_value(&v));
self
}
pub fn insert_array<F>(self, key: String, f: F) -> ObjectBuilder where
pub fn insert_array<F>(mut self, key: String, f: F) -> ObjectBuilder where
F: FnOnce(ArrayBuilder) -> ArrayBuilder
{
let builder = ArrayBuilder::new();
self.insert(key, f(builder).unwrap())
self.object.insert(key, f(builder).unwrap());
self
}
pub fn insert_object<F>(self, key: String, f: F) -> ObjectBuilder where
pub fn insert_object<F>(mut self, key: String, f: F) -> ObjectBuilder where
F: FnOnce(ObjectBuilder) -> ObjectBuilder
{
let builder = ObjectBuilder::new();
self.insert(key, f(builder).unwrap())
}
}
#[cfg(test)]
mod tests {
use std::collections::BTreeMap;
use json::value::Value;
use super::{ArrayBuilder, ObjectBuilder};
#[test]
fn test_array_builder() {
let value = ArrayBuilder::new().unwrap();
assert_eq!(value, Value::Array(Vec::new()));
let value = ArrayBuilder::new()
.push(1is)
.push(2is)
.push(3is)
.unwrap();
assert_eq!(value, Value::Array(vec!(Value::Integer(1), Value::Integer(2), Value::Integer(3))));
let value = ArrayBuilder::new()
.push_array(|bld| bld.push(1is).push(2is).push(3is))
.unwrap();
assert_eq!(value, Value::Array(vec!(Value::Array(vec!(Value::Integer(1), Value::Integer(2), Value::Integer(3))))));
let value = ArrayBuilder::new()
.push_object(|bld|
bld
.insert("a".to_string(), 1is)
.insert("b".to_string(), 2is))
.unwrap();
let mut map = BTreeMap::new();
map.insert("a".to_string(), Value::Integer(1));
map.insert("b".to_string(), Value::Integer(2));
assert_eq!(value, Value::Array(vec!(Value::Object(map))));
}
#[test]
fn test_object_builder() {
let value = ObjectBuilder::new().unwrap();
assert_eq!(value, Value::Object(BTreeMap::new()));
let value = ObjectBuilder::new()
.insert("a".to_string(), 1is)
.insert("b".to_string(), 2is)
.unwrap();
let mut map = BTreeMap::new();
map.insert("a".to_string(), Value::Integer(1));
map.insert("b".to_string(), Value::Integer(2));
assert_eq!(value, Value::Object(map));
self.object.insert(key, f(builder).unwrap());
self
}
}
+288 -316
View File
@@ -1,110 +1,50 @@
use std::str;
use std::char;
use std::num::Float;
use unicode::str::Utf16Item;
use std::char;
use std::str;
use de;
use super::error::{Error, ErrorCode};
#[derive(PartialEq, Debug)]
enum State {
// Parse a value.
Value,
// Parse a value or ']'.
ListStart,
// Parse ',' or ']' after an element in a list.
ListCommaOrEnd,
// Parse a key:value or an ']'.
ObjectStart,
// Parse ',' or ']' after an element in an object.
ObjectCommaOrEnd,
// Parse a key in an object.
//ObjectKey,
// Parse a value in an object.
ObjectValue,
}
/// A streaming JSON parser implemented as an iterator of JsonEvent, consuming
/// an iterator of char.
pub struct Parser<Iter> {
pub struct Deserializer<Iter> {
rdr: Iter,
ch: Option<u8>,
line: usize,
col: usize,
// A state machine is kept to make it possible to interupt and resume parsing.
state_stack: Vec<State>,
buf: Vec<u8>,
}
impl<Iter: Iterator<Item=u8>> Iterator for Parser<Iter> {
type Item = Result<de::Token, Error>;
#[inline]
fn next(&mut self) -> Option<Result<de::Token, Error>> {
let state = match self.state_stack.pop() {
Some(state) => state,
None => {
// If we have no state left, then we're expecting the structure
// to be done, so make sure there are no trailing characters.
self.parse_whitespace();
if self.eof() {
return None;
} else {
return Some(Err(self.error(ErrorCode::TrailingCharacters)));
}
}
};
match state {
State::Value => Some(self.parse_value()),
State::ListStart => Some(self.parse_list_start()),
State::ListCommaOrEnd => Some(self.parse_list_comma_or_end()),
State::ObjectStart => {
match self.parse_object_start() {
Ok(Some(s)) => Some(Ok(de::Token::String(s.to_string()))),
Ok(None) => Some(Ok(de::Token::End)),
Err(err) => Some(Err(err)),
}
}
State::ObjectCommaOrEnd => {
match self.parse_object_comma_or_end() {
Ok(Some(s)) => Some(Ok(de::Token::String(s.to_string()))),
Ok(None) => Some(Ok(de::Token::End)),
Err(err) => Some(Err(err)),
}
}
//State::ObjectKey => Some(self.parse_object_key()),
State::ObjectValue => Some(self.parse_object_value()),
}
}
}
impl<Iter: Iterator<Item=u8>> Parser<Iter> {
impl<Iter> Deserializer<Iter>
where Iter: Iterator<Item=u8>,
{
/// 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,
col: 0,
state_stack: vec!(State::Value),
buf: Vec::with_capacity(128),
};
p.bump();
return p;
}
#[inline(always)]
#[inline]
pub fn end(&mut self) -> Result<(), Error> {
self.parse_whitespace();
if self.eof() {
Ok(())
} else {
Err(self.error(ErrorCode::TrailingCharacters))
}
}
fn eof(&self) -> bool { self.ch.is_none() }
#[inline]
fn ch_or_null(&self) -> u8 { self.ch.unwrap_or(b'\x00') }
#[inline(always)]
fn bump(&mut self) {
self.ch = self.rdr.next();
@@ -116,23 +56,19 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
}
}
#[inline]
fn next_char(&mut self) -> Option<u8> {
self.bump();
self.ch
}
#[inline(always)]
fn ch_is(&self, c: u8) -> bool {
self.ch == Some(c)
}
#[inline]
fn error(&mut self, reason: ErrorCode) -> Error {
Error::SyntaxError(reason, self.line, self.col)
}
#[inline]
fn parse_whitespace(&mut self) {
while self.ch_is(b' ') ||
self.ch_is(b'\n') ||
@@ -140,8 +76,9 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
self.ch_is(b'\r') { self.bump(); }
}
#[inline]
fn parse_value(&mut self) -> Result<de::Token, Error> {
fn parse_value<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
self.parse_whitespace();
if self.eof() {
@@ -149,22 +86,31 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
}
match self.ch_or_null() {
b'n' => self.parse_ident(b"ull", de::Token::Null),
b't' => self.parse_ident(b"rue", de::Token::Bool(true)),
b'f' => self.parse_ident(b"alse", de::Token::Bool(false)),
b'0' ... b'9' | b'-' => self.parse_number(),
b'n' => {
try!(self.parse_ident(b"ull"));
visitor.visit_unit()
}
b't' => {
try!(self.parse_ident(b"rue"));
visitor.visit_bool(true)
}
b'f' => {
try!(self.parse_ident(b"alse"));
visitor.visit_bool(false)
}
b'0' ... b'9' | b'-' => self.parse_number(visitor),
b'"' => {
Ok(de::Token::String(try!(self.parse_string()).to_string()))
try!(self.parse_string());
let s = str::from_utf8(&self.buf).unwrap();
visitor.visit_str(s)
}
b'[' => {
self.bump();
self.state_stack.push(State::ListStart);
Ok(de::Token::SeqStart(0))
visitor.visit_seq(SeqVisitor::new(self))
}
b'{' => {
self.bump();
self.state_stack.push(State::ObjectStart);
Ok(de::Token::MapStart(0))
visitor.visit_map(MapVisitor::new(self))
}
_ => {
Err(self.error(ErrorCode::ExpectedSomeValue))
@@ -172,18 +118,18 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
}
}
#[inline]
fn parse_ident(&mut self, ident: &[u8], token: de::Token) -> Result<de::Token, Error> {
fn parse_ident(&mut self, ident: &[u8]) -> Result<(), Error> {
if ident.iter().all(|c| Some(*c) == self.next_char()) {
self.bump();
Ok(token)
Ok(())
} else {
Err(self.error(ErrorCode::ExpectedSomeIdent))
}
}
#[inline]
fn parse_number(&mut self) -> Result<de::Token, Error> {
fn parse_number<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
let mut neg = 1;
if self.ch_is(b'-') {
@@ -205,13 +151,12 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
res = try!(self.parse_exponent(res));
}
Ok(de::Token::F64(neg * res))
visitor.visit_f64(neg * res)
} else {
Ok(de::Token::I64(neg * res))
visitor.visit_i64(neg * res)
}
}
#[inline]
fn parse_integer(&mut self) -> Result<i64, Error> {
let mut res = 0;
@@ -245,7 +190,6 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
Ok(res)
}
#[inline]
fn parse_decimal(&mut self, res: f64) -> Result<f64, Error> {
self.bump();
@@ -261,7 +205,7 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
match self.ch_or_null() {
c @ b'0' ... b'9' => {
dec /= 10.0;
res += (((c as isize) - (b'0' as isize)) as f64) * dec;
res += (((c as u64) - (b'0' as u64)) as f64) * dec;
self.bump();
}
_ => break,
@@ -271,11 +215,10 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
Ok(res)
}
#[inline]
fn parse_exponent(&mut self, mut res: f64) -> Result<f64, Error> {
self.bump();
let mut exp = 0us;
let mut exp = 0;
let mut neg_exp = false;
if self.ch_is(b'+') {
@@ -294,7 +237,7 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
match self.ch_or_null() {
c @ b'0' ... b'9' => {
exp *= 10;
exp += (c as usize) - (b'0' as usize);
exp += (c as i32) - (b'0' as i32);
self.bump();
}
@@ -302,7 +245,7 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
}
}
let exp: f64 = 10_f64.powi(exp as i32);
let exp: f64 = 10_f64.powi(exp);
if neg_exp {
res /= exp;
} else {
@@ -312,11 +255,10 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
Ok(res)
}
#[inline]
fn decode_hex_escape(&mut self) -> Result<u16, Error> {
let mut i = 0us;
let mut i = 0;
let mut n = 0u16;
while i < 4us && !self.eof() {
while i < 4 && !self.eof() {
self.bump();
n = match self.ch_or_null() {
c @ b'0' ... b'9' => n * 16_u16 + ((c as u16) - (b'0' as u16)),
@@ -329,19 +271,18 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
_ => { return Err(self.error(ErrorCode::InvalidEscape)); }
};
i += 1us;
i += 1;
}
// Error out if we didn't parse 4 digits.
if i != 4us {
if i != 4 {
return Err(self.error(ErrorCode::InvalidEscape));
}
Ok(n)
}
#[inline]
fn parse_string(&mut self) -> Result<&str, Error> {
fn parse_string(&mut self) -> Result<(), Error> {
self.buf.clear();
let mut escape = false;
@@ -397,7 +338,7 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
}
};
let buf = &mut [0u8; 4];
let buf = &mut [0; 4];
let len = c.encode_utf8(buf).unwrap_or(0);
self.buf.extend(buf[..len].iter().map(|b| *b));
}
@@ -410,7 +351,7 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
match ch {
b'"' => {
self.bump();
return Ok(str::from_utf8(&self.buf).unwrap());
return Ok(());
}
b'\\' => {
escape = true;
@@ -423,92 +364,12 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
}
}
#[inline]
fn parse_list_start(&mut self) -> Result<de::Token, Error> {
self.parse_whitespace();
if self.ch_is(b']') {
self.bump();
Ok(de::Token::End)
} else {
self.state_stack.push(State::ListCommaOrEnd);
self.parse_value()
}
}
#[inline]
fn parse_list_comma_or_end(&mut self) -> Result<de::Token, Error> {
self.parse_whitespace();
if self.ch_is(b',') {
self.bump();
self.state_stack.push(State::ListCommaOrEnd);
self.parse_value()
} else if self.ch_is(b']') {
self.bump();
Ok(de::Token::End)
} else if self.eof() {
Err(self.error(ErrorCode::EOFWhileParsingList))
} else {
Err(self.error(ErrorCode::ExpectedListCommaOrEnd))
}
}
#[inline]
fn parse_object_start(&mut self) -> Result<Option<&str>, Error> {
self.parse_whitespace();
if self.ch_is(b'}') {
self.bump();
Ok(None)
} else {
Ok(Some(try!(self.parse_object_key())))
}
}
#[inline]
fn parse_object_comma_or_end(&mut self) -> Result<Option<&str>, Error> {
self.parse_whitespace();
if self.ch_is(b',') {
self.bump();
Ok(Some(try!(self.parse_object_key())))
} else if self.ch_is(b'}') {
self.bump();
Ok(None)
} else if self.eof() {
Err(self.error(ErrorCode::EOFWhileParsingObject))
} else {
Err(self.error(ErrorCode::ExpectedObjectCommaOrEnd))
}
}
#[inline]
fn parse_object_key(&mut self) -> Result<&str, Error> {
self.parse_whitespace();
if self.eof() {
return Err(self.error(ErrorCode::EOFWhileParsingString));
}
match self.ch_or_null() {
b'"' => {
self.state_stack.push(State::ObjectValue);
Ok(try!(self.parse_string()))
}
_ => Err(self.error(ErrorCode::KeyMustBeAString)),
}
}
#[inline]
fn parse_object_value(&mut self) -> Result<de::Token, Error> {
fn parse_object_colon(&mut self) -> Result<(), Error> {
self.parse_whitespace();
if self.ch_is(b':') {
self.bump();
self.state_stack.push(State::ObjectCommaOrEnd);
self.parse_value()
Ok(())
} else if self.eof() {
Err(self.error(ErrorCode::EOFWhileParsingObject))
} else {
@@ -517,148 +378,259 @@ impl<Iter: Iterator<Item=u8>> Parser<Iter> {
}
}
impl<Iter: Iterator<Item=u8>> de::Deserializer<Error> for Parser<Iter> {
fn end_of_stream_error(&mut self) -> Error {
Error::SyntaxError(ErrorCode::EOFWhileParsingValue, self.line, self.col)
}
impl<Iter> de::Deserializer for Deserializer<Iter>
where Iter: Iterator<Item=u8>,
{
type Error = Error;
fn syntax_error(&mut self, token: de::Token, expected: &'static [de::TokenKind]) -> Error {
Error::SyntaxError(ErrorCode::ExpectedTokens(token, expected), self.line, self.col)
}
fn unexpected_name_error(&mut self, token: de::Token) -> Error {
Error::SyntaxError(ErrorCode::UnexpectedName(token), self.line, self.col)
}
fn conversion_error(&mut self, token: de::Token) -> Error {
Error::SyntaxError(ErrorCode::ConversionError(token), self.line, self.col)
#[inline]
fn visit<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
self.parse_value(visitor)
}
#[inline]
fn missing_field<
T: de::Deserialize<Parser<Iter>, Error>
>(&mut self, _field: &'static str) -> Result<T, Error> {
// JSON can represent `null` values as a missing value, so this isn't
// necessarily an error.
de::Deserialize::deserialize_token(self, de::Token::Null)
}
fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
self.parse_whitespace();
// Special case treating options as a nullable value.
#[inline]
fn expect_option<
U: de::Deserialize<Parser<Iter>, Error>
>(&mut self, token: de::Token) -> Result<Option<U>, Error> {
match token {
de::Token::Null => Ok(None),
token => {
let value: U = try!(de::Deserialize::deserialize_token(self, token));
Ok(Some(value))
}
}
}
// Special case treating enums as a `{"<variant-name>": [<fields>]}`.
#[inline]
fn expect_enum_start(&mut self,
token: de::Token,
_name: &str,
variants: &[&str]) -> Result<usize, Error> {
match token {
de::Token::MapStart(_) => { }
_ => { return Err(self.error(ErrorCode::ExpectedEnumMapStart)); }
};
// Enums only have one field in them, which is the variant name.
let variant = match try!(self.expect_token()) {
de::Token::String(variant) => variant,
_ => { return Err(self.error(ErrorCode::ExpectedEnumVariantString)); }
};
// The variant's field is a list of the values.
match try!(self.expect_token()) {
de::Token::SeqStart(_) => { }
_ => { return Err(self.error(ErrorCode::ExpectedEnumToken)); }
if self.eof() {
return Err(self.error(ErrorCode::EOFWhileParsingValue));
}
match variants.iter().position(|v| *v == &variant[]) {
Some(idx) => Ok(idx),
None => Err(self.error(ErrorCode::UnknownVariant)),
}
}
fn expect_enum_end(&mut self) -> Result<(), Error> {
// There will be one `End` for the list, and one for the object.
match try!(self.expect_token()) {
de::Token::End => {
match try!(self.expect_token()) {
de::Token::End => Ok(()),
_ => Err(self.error(ErrorCode::ExpectedEnumEndToken)),
}
}
_ => Err(self.error(ErrorCode::ExpectedEnumEnd)),
if self.ch_is(b'n') {
try!(self.parse_ident(b"ull"));
visitor.visit_none()
} else {
visitor.visit_some(self)
}
}
#[inline]
fn expect_struct_start(&mut self, token: de::Token, _name: &str) -> Result<(), Error> {
match token {
de::Token::MapStart(_) => Ok(()),
_ => {
static EXPECTED_TOKENS: &'static [de::TokenKind] = &[
de::TokenKind::MapStartKind,
];
Err(self.syntax_error(token, EXPECTED_TOKENS))
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
self.parse_whitespace();
if self.ch_is(b'{') {
self.bump();
self.parse_whitespace();
try!(self.parse_string());
try!(self.parse_object_colon());
let variant = str::from_utf8(&self.buf).unwrap().to_string();
let value = try!(visitor.visit_variant(&variant, EnumVisitor {
de: self,
}));
self.parse_whitespace();
if self.ch_is(b'}') {
self.bump();
Ok(value)
} else {
return Err(self.error(ErrorCode::ExpectedSomeValue));
}
} else {
Err(self.error(ErrorCode::ExpectedSomeValue))
}
}
}
struct SeqVisitor<'a, Iter: 'a> {
de: &'a mut Deserializer<Iter>,
first: bool,
}
impl<'a, Iter> SeqVisitor<'a, Iter> {
fn new(de: &'a mut Deserializer<Iter>) -> Self {
SeqVisitor {
de: de,
first: true,
}
}
}
impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
where Iter: Iterator<Item=u8>
{
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: de::Deserialize,
{
self.de.parse_whitespace();
if self.de.ch_is(b']') {
self.de.bump();
return Ok(None);
}
if self.first {
self.first = false;
} else {
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.de.error(ErrorCode::ExpectedListCommaOrEnd));
}
}
let value = try!(de::Deserialize::deserialize(self.de));
Ok(Some(value))
}
fn end(&mut self) -> Result<(), Error> {
self.de.parse_whitespace();
if self.de.ch_is(b']') {
self.de.bump();
Ok(())
} else if self.de.eof() {
Err(self.de.error(ErrorCode::EOFWhileParsingList))
} else {
Err(self.de.error(ErrorCode::TrailingCharacters))
}
}
}
struct MapVisitor<'a, Iter: 'a> {
de: &'a mut Deserializer<Iter>,
first: bool,
}
impl<'a, Iter> MapVisitor<'a, Iter> {
fn new(de: &'a mut Deserializer<Iter>) -> Self {
MapVisitor {
de: de,
first: true,
}
}
}
impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
where Iter: Iterator<Item=u8>
{
type Error = Error;
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
where K: de::Deserialize,
{
self.de.parse_whitespace();
if self.de.ch_is(b'}') {
self.de.bump();
return Ok(None);
}
if self.first {
self.first = false;
} else {
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.de.error(ErrorCode::ExpectedObjectCommaOrEnd));
}
}
if self.de.eof() {
return Err(self.de.error(ErrorCode::EOFWhileParsingValue));
}
if !self.de.ch_is(b'"') {
return Err(self.de.error(ErrorCode::KeyMustBeAString));
}
Ok(Some(try!(de::Deserialize::deserialize(self.de))))
}
fn visit_value<V>(&mut self) -> Result<V, Error>
where V: de::Deserialize,
{
try!(self.de.parse_object_colon());
Ok(try!(de::Deserialize::deserialize(self.de)))
}
fn end(&mut self) -> Result<(), Error> {
self.de.parse_whitespace();
if self.de.ch_is(b']') {
self.de.bump();
Ok(())
} else if self.de.eof() {
Err(self.de.error(ErrorCode::EOFWhileParsingList))
} else {
Err(self.de.error(ErrorCode::TrailingCharacters))
}
}
}
struct EnumVisitor<'a, Iter: 'a> {
de: &'a mut Deserializer<Iter>,
}
impl<'a, Iter> de::EnumVisitor for EnumVisitor<'a, Iter>
where Iter: Iterator<Item=u8>,
{
type Error = Error;
fn visit_unit(&mut self) -> Result<(), Error> {
de::Deserialize::deserialize(self.de)
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumSeqVisitor,
{
self.de.parse_whitespace();
if self.de.ch_is(b'[') {
self.de.bump();
visitor.visit(SeqVisitor::new(self.de))
} else {
Err(self.de.error(ErrorCode::ExpectedSomeValue))
}
}
#[inline]
fn expect_struct_field_or_end(&mut self,
fields: &'static [&'static str]
) -> Result<Option<Option<usize>>, Error> {
let result = match self.state_stack.pop() {
Some(State::ObjectStart) => {
try!(self.parse_object_start())
}
Some(State::ObjectCommaOrEnd) => {
try!(self.parse_object_comma_or_end())
}
_ => panic!("invalid internal state"),
};
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumMapVisitor,
{
self.de.parse_whitespace();
let s = match result {
Some(s) => s,
None => { return Ok(None); }
};
Ok(Some(fields.iter().position(|field| *field == &s[])))
if self.de.ch_is(b'{') {
self.de.bump();
visitor.visit(MapVisitor::new(self.de))
} else {
Err(self.de.error(ErrorCode::ExpectedSomeValue))
}
}
}
/// Decodes a json value from an `Iterator<u8>`.
pub fn from_iter<
Iter: Iterator<Item=u8>,
T: de::Deserialize<Parser<Iter>, Error>
>(iter: Iter) -> Result<T, Error> {
let mut parser = Parser::new(iter);
let value = try!(de::Deserialize::deserialize(&mut parser));
pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
where I: Iterator<Item=u8>,
T: de::Deserialize
{
let mut de = Deserializer::new(iter);
let value = try!(de::Deserialize::deserialize(&mut de));
// Make sure the whole stream has been consumed.
match parser.next() {
Some(Ok(_token)) => Err(parser.error(ErrorCode::TrailingCharacters)),
Some(Err(err)) => Err(err),
None => Ok(value),
}
try!(de.end());
Ok(value)
}
/// Decodes a json value from a string
pub fn from_str<
'a,
T: de::Deserialize<Parser<str::Bytes<'a>>, Error>
>(s: &'a str) -> Result<T, Error> {
pub fn from_str<'a, T>(s: &'a str) -> Result<T, Error>
where T: de::Deserialize
{
from_iter(s.bytes())
}
#[cfg(test)]
mod tests {
}
+47 -14
View File
@@ -2,12 +2,11 @@ use std::error;
use std::fmt;
use std::io;
use de::{Token, TokenKind};
use de;
/// The errors that can arise while parsing a JSON stream.
#[derive(Clone, PartialEq)]
#[derive(Copy, Clone, PartialEq)]
pub enum ErrorCode {
ConversionError(Token),
EOFWhileParsingList,
EOFWhileParsingObject,
EOFWhileParsingString,
@@ -24,7 +23,6 @@ pub enum ErrorCode {
ExpectedObjectCommaOrEnd,
ExpectedSomeIdent,
ExpectedSomeValue,
ExpectedTokens(Token, &'static [TokenKind]),
InvalidEscape,
InvalidNumber,
InvalidUnicodeCodePoint,
@@ -35,15 +33,16 @@ pub enum ErrorCode {
NotUtf8,
TrailingCharacters,
UnexpectedEndOfHexEscape,
UnexpectedName(Token),
UnknownVariant,
UnrecognizedHex,
}
impl fmt::Debug for ErrorCode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use std::fmt::Debug;
match *self {
ErrorCode::ConversionError(ref token) => write!(f, "failed to convert {:?}", token),
//ErrorCode::ConversionError(ref token) => write!(f, "failed to convert {}", token),
ErrorCode::EOFWhileParsingList => "EOF While parsing list".fmt(f),
ErrorCode::EOFWhileParsingObject => "EOF While parsing object".fmt(f),
ErrorCode::EOFWhileParsingString => "EOF While parsing string".fmt(f),
@@ -60,7 +59,7 @@ impl fmt::Debug for ErrorCode {
ErrorCode::ExpectedObjectCommaOrEnd => "expected `,` or `}`".fmt(f),
ErrorCode::ExpectedSomeIdent => "expected ident".fmt(f),
ErrorCode::ExpectedSomeValue => "expected value".fmt(f),
ErrorCode::ExpectedTokens(ref token, tokens) => write!(f, "expected {:?}, found {:?}", tokens, token),
//ErrorCode::ExpectedTokens(ref token, tokens) => write!(f, "expected {}, found {}", tokens, token),
ErrorCode::InvalidEscape => "invalid escape".fmt(f),
ErrorCode::InvalidNumber => "invalid number".fmt(f),
ErrorCode::InvalidUnicodeCodePoint => "invalid unicode code point".fmt(f),
@@ -71,7 +70,7 @@ impl fmt::Debug for ErrorCode {
ErrorCode::NotUtf8 => "contents not utf-8".fmt(f),
ErrorCode::TrailingCharacters => "trailing characters".fmt(f),
ErrorCode::UnexpectedEndOfHexEscape => "unexpected end of hex escape".fmt(f),
ErrorCode::UnexpectedName(ref name) => write!(f, "unexpected name {:?}", name),
//ErrorCode::UnexpectedName(ref name) => write!(f, "unexpected name {}", name),
ErrorCode::UnknownVariant => "unknown variant".fmt(f),
ErrorCode::UnrecognizedHex => "invalid \\u escape (unrecognized hex)".fmt(f),
}
@@ -83,39 +82,59 @@ pub enum Error {
/// msg, line, col
SyntaxError(ErrorCode, usize, usize),
IoError(io::Error),
/*
ExpectedError(String, String),
MissingFieldError(String),
*/
MissingFieldError(&'static str),
/*
UnknownVariantError(String),
*/
}
impl error::Error for Error {
fn description(&self) -> &str {
match *self {
Error::SyntaxError(..) => "syntax error",
Error::IoError(_) => "Input/Output error",
Error::IoError(ref error) => error.description(),
/*
Error::ExpectedError(ref expected, _) => &expected,
*/
Error::MissingFieldError(_) => "missing field",
/*
Error::UnknownVariantError(_) => "unknown variant",
*/
}
}
fn cause(&self) -> Option<&error::Error> {
match *self {
Error::IoError(ref error) => Some(error),
_ => None,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::SyntaxError(ref code, line, col) => {
write!(fmt, "{:?} at line {:?} column {:?}", code, line, col)
write!(fmt, "{:?} at line {} column {}", code, line, col)
}
Error::IoError(ref error) => fmt::Display::fmt(error, fmt),
/*
Error::ExpectedError(ref expected, ref found) => {
write!(fmt, "expected {:?}, found {:?}", expected, found)
Some(format!("expected {}, found {}", expected, found))
}
*/
Error::MissingFieldError(ref field) => {
write!(fmt, "missing field {:?}", field)
write!(fmt, "missing field {}", field)
}
/*
Error::UnknownVariantError(ref variant) => {
write!(fmt, "unknown variant {:?}", variant)
Some(format!("unknown variant {}", variant))
}
*/
}
}
}
@@ -125,3 +144,17 @@ impl error::FromError<io::Error> for Error {
Error::IoError(error)
}
}
impl de::Error for Error {
fn syntax_error() -> Error {
Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0)
}
fn end_of_stream_error() -> Error {
Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 0, 0)
}
fn missing_field_error(field: &'static str) -> Error {
Error::MissingFieldError(field)
}
}
+7 -305
View File
@@ -1,317 +1,19 @@
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Rust JSON serialization library
// Copyright (c) 2011 Google Inc.
#![forbid(non_camel_case_types)]
#![allow(missing_docs)]
/*!
JSON parsing and serialization
# What is JSON?
JSON (JavaScript Object Notation) is a way to write data in Javascript.
Like XML it allows one to serialize structured data in a text format that can be read by humans
easily.
Its native compatibility with JavaScript and its simple syntax make it used widely.
Json data are serialized in a form of "key":"value".
Data types that can be serialized are JavaScript types :
boolean (`true` or `false`), number (`f64`), string, array, object, 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 serializing 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"
]
}
```
# Rust Type-based Serializing and Deserializing
Rust provides a mechanism for low boilerplate serializing and deserializing
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.
The Rust compiler provides an annotation to automatically generate
the code for these traits: `#[derive_serialize]` and `#[derive_deserialize]`.
To serialize using `Serialize`:
```rust
#![feature(plugin)]
#![plugin(serde_macros)]
extern crate serde;
use std::io::WriteExt;
use serde::json;
use serde::Serialize;
#[derive_serialize]
pub struct TestStruct {
data_str: String,
}
fn main() {
let to_serialize_object = TestStruct {
data_str: "example of string to serialize".to_string()
};
let mut wr = Vec::new();
{
let mut serializer = json::Serializer::new(wr.by_ref());
match to_serialize_object.serialize(&mut serializer) {
Ok(()) => (),
Err(e) => panic!("json serialization error: {:?}", e),
}
}
}
```
Two wrapper functions are provided to serialize a `Serialize` object
into a string (String) or buffer (~[u8]): `json::to_string(value)` and
`json::to_vec(value)`.
```rust
use serde::json;
let to_serialize_object = "example of string to serialize";
let serialized_str: String = json::to_string(&to_serialize_object).unwrap();
```
JSON API provide an enum `json::Value` and a trait `ToJson` to serialize
object. The trait `ToJson` serialize object into a container `json::Value` and
the API provide writer to serialize them into a stream or a string ...
When using `ToJson` the `Serialize` trait implementation is not mandatory.
A basic `ToJson` example using a BTreeMap of attribute name / attribute value:
```rust
#![feature(plugin)]
#![plugin(serde_macros)]
extern crate serde;
use std::collections::BTreeMap;
use serde::json::{ToJson, Value};
pub struct MyStruct {
attr1: u8,
attr2: String,
}
impl ToJson for MyStruct {
fn to_json( &self ) -> Value {
let mut d = BTreeMap::new();
d.insert("attr1".to_string(), self.attr1.to_json());
d.insert("attr2".to_string(), self.attr2.to_json());
d.to_json()
}
}
fn main() {
let test = MyStruct {attr1: 1, attr2:"test".to_string()};
let json: Value = test.to_json();
let json_str: String = json.to_string();
}
```
Or you can use the helper type `ObjectBuilder`:
```rust
#![feature(plugin)]
#![plugin(serde_macros)]
extern crate serde;
use serde::json::{ObjectBuilder, ToJson, Value};
pub struct MyStruct {
attr1: u8,
attr2: String,
}
impl ToJson for MyStruct {
fn to_json( &self ) -> Value {
ObjectBuilder::new()
.insert("attr1".to_string(), &self.attr1)
.insert("attr2".to_string(), &self.attr2)
.unwrap()
}
}
fn main() {
let test = MyStruct {attr1: 1, attr2:"test".to_string()};
let json: Value = test.to_json();
let json_str: String = json.to_string();
}
```
To deserialize a JSON string using `Deserialize` trait:
```rust
#![feature(plugin)]
#![plugin(serde_macros)]
extern crate serde;
use serde::json;
use serde::Deserialize;
#[derive_deserialize]
pub struct MyStruct {
attr1: u8,
attr2: String,
}
fn main() {
let json_str_to_deserialize = "{ \"attr1\": 1, \"attr2\": \"toto\" }";
let mut parser = json::Parser::new(json_str_to_deserialize.bytes());
let deserialized_object: MyStruct = match Deserialize::deserialize(&mut parser) {
Ok(v) => v,
Err(e) => panic!("Decoding error: {:?}", e)
};
}
```
# Examples of use
## Using Autoserialization
Create a struct called `TestStruct1` and serialize and deserialize it to and from JSON
using the serialization API, using the derived serialization code.
```rust
#![feature(plugin)]
#![plugin(serde_macros)]
extern crate serde;
use serde::json;
#[derive_serialize]
#[derive_deserialize]
pub struct TestStruct1 {
data_int: u8,
data_str: String,
data_vector: Vec<u8>,
}
// To serialize use the `json::to_string` to serialize an object in a string.
// It calls the generated `Serialize` impl.
fn main() {
let to_serialize_object = TestStruct1 {
data_int: 1,
data_str: "toto".to_string(),
data_vector: vec![2,3,4,5]
};
let serialized_str: String = json::to_string(&to_serialize_object).unwrap();
// To deserialize use the `json::from_str` function.
let deserialized_object: TestStruct1 = match json::from_str(&serialized_str) {
Ok(deserialized_object) => deserialized_object,
Err(e) => panic!("json deserialization error: {:?}", e),
};
}
```
## Using `ToJson`
This example use the ToJson impl to deserialize the JSON string.
Example of `ToJson` trait implementation for TestStruct1.
```rust
#![feature(plugin)]
#![plugin(serde_macros)]
extern crate serde;
use serde::json::ToJson;
use serde::json;
use serde::Deserialize;
#[derive_serialize] // generate Serialize impl
#[derive_deserialize] // generate Deserialize impl
pub struct TestStruct1 {
data_int: u8,
data_str: String,
data_vector: Vec<u8>,
}
impl ToJson for TestStruct1 {
fn to_json( &self ) -> json::Value {
json::builder::ObjectBuilder::new()
.insert("data_int".to_string(), &self.data_int)
.insert("data_str".to_string(), &self.data_str)
.insert("data_vector".to_string(), &self.data_vector)
.unwrap()
}
}
fn main() {
// Serialization using our impl of to_json
let test: TestStruct1 = TestStruct1 {
data_int: 1,
data_str: "toto".to_string(),
data_vector: vec![2,3,4,5],
};
let json: json::Value = test.to_json();
let json_str: String = json.to_string();
// Deserialize like before.
let mut parser = json::Parser::new(json_str.bytes());
let deserialized: TestStruct1 = Deserialize::deserialize(&mut parser).unwrap();
}
```
*/
pub use self::builder::{ArrayBuilder, ObjectBuilder};
pub use self::de::{
Parser,
from_str,
};
pub use self::de::{Deserializer, from_str};
pub use self::error::{Error, ErrorCode};
pub use self::ser::{
Serializer,
PrettySerializer,
to_writer,
to_writer_pretty,
to_vec,
to_vec_pretty,
to_string,
to_pretty_writer,
to_pretty_vec,
to_pretty_string,
to_string_pretty,
escape_str,
};
pub use self::value::{Value, ToJson, from_json};
pub use self::value::{Value, to_value, from_value};
pub mod builder;
pub mod de;
pub mod error;
pub mod ser;
pub mod value;
pub mod error;
+337 -516
View File
@@ -1,498 +1,310 @@
use std::f32;
use std::f64;
use std::num::{Float, FpCategory};
use std::{f32, f64};
use std::io;
use std::num::{Float, FpCategory};
use std::string::FromUtf8Error;
use ser;
/// A structure for implementing serialization to JSON.
pub struct Serializer<W> {
wr: W,
first: bool,
writer: W,
format: Format,
current_indent: usize,
indent: usize,
}
#[derive(Copy, PartialEq)]
enum Format {
Compact,
Pretty,
}
impl<W: io::Write> Serializer<W> {
/// Creates a new JSON serializer whose output will be written to the writer
/// Creates a new JSON visitr whose output will be written to the writer
/// specified.
pub fn new(wr: W) -> Serializer<W> {
#[inline]
pub fn new(writer: W) -> Serializer<W> {
Serializer {
wr: wr,
first: true,
}
}
/// Unwrap the io::Write from the Serializer.
pub fn unwrap(self) -> W {
self.wr
}
}
impl<W: io::Write> ser::Serializer<io::Error> for Serializer<W> {
#[inline]
fn serialize_null(&mut self) -> io::Result<()> {
self.wr.write_all(b"null")
}
#[inline]
fn serialize_bool(&mut self, value: bool) -> io::Result<()> {
if value {
self.wr.write_all(b"true")
} else {
self.wr.write_all(b"false")
}
}
#[inline]
fn serialize_isize(&mut self, value: isize) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_i8(&mut self, value: i8) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_i16(&mut self, value: i16) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_i32(&mut self, value: i32) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_i64(&mut self, value: i64) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_usize(&mut self, value: usize) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_u8(&mut self, value: u8) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_u16(&mut self, value: u16) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_u32(&mut self, value: u32) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_u64(&mut self, value: u64) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_f32(&mut self, value: f32) -> io::Result<()> {
fmt_f32_or_null(&mut self.wr, value)
}
#[inline]
fn serialize_f64(&mut self, value: f64) -> io::Result<()> {
fmt_f64_or_null(&mut self.wr, value)
}
#[inline]
fn serialize_char(&mut self, value: char) -> io::Result<()> {
escape_char(&mut self.wr, value)
}
#[inline]
fn serialize_str(&mut self, value: &str) -> io::Result<()> {
escape_str(&mut self.wr, value)
}
#[inline]
fn serialize_tuple_start(&mut self, _len: usize) -> io::Result<()> {
self.first = true;
write!(&mut self.wr, "[")
}
#[inline]
fn serialize_tuple_elt<
T: ser::Serialize<Serializer<W>, io::Error>
>(&mut self, value: &T) -> io::Result<()> {
if self.first {
self.first = false;
} else {
try!(write!(&mut self.wr, ","));
}
value.serialize(self)
}
#[inline]
fn serialize_tuple_end(&mut self) -> io::Result<()> {
write!(&mut self.wr, "]")
}
#[inline]
fn serialize_struct_start(&mut self, _name: &str, _len: usize) -> io::Result<()> {
self.first = true;
write!(&mut self.wr, "{{")
}
#[inline]
fn serialize_struct_elt<
T: ser::Serialize<Serializer<W>, io::Error>
>(&mut self, name: &str, value: &T) -> io::Result<()> {
use ser::Serialize;
if self.first {
self.first = false;
} else {
try!(write!(&mut self.wr, ","));
}
try!(name.serialize(self));
try!(write!(&mut self.wr, ":"));
value.serialize(self)
}
#[inline]
fn serialize_struct_end(&mut self) -> io::Result<()> {
write!(&mut self.wr, "}}")
}
#[inline]
fn serialize_enum_start(&mut self, _name: &str, variant: &str, _len: usize) -> io::Result<()> {
self.first = true;
try!(write!(&mut self.wr, "{{"));
try!(self.serialize_str(variant));
write!(&mut self.wr, ":[")
}
#[inline]
fn serialize_enum_elt<
T: ser::Serialize<Serializer<W>, io::Error>
>(&mut self, value: &T) -> io::Result<()> {
if self.first {
self.first = false;
} else {
try!(write!(&mut self.wr, ","));
}
value.serialize(self)
}
#[inline]
fn serialize_enum_end(&mut self) -> io::Result<()> {
write!(&mut self.wr, "]}}")
}
#[inline]
fn serialize_option<
T: ser::Serialize<Serializer<W>, io::Error>
>(&mut self, v: &Option<T>) -> io::Result<()> {
match *v {
Some(ref v) => {
v.serialize(self)
}
None => {
self.serialize_null()
}
}
}
#[inline]
fn serialize_seq<
T: ser::Serialize<Serializer<W>, io::Error>,
Iter: Iterator<Item=T>
>(&mut self, iter: Iter) -> io::Result<()> {
try!(write!(&mut self.wr, "["));
let mut first = true;
for elt in iter {
if first {
first = false;
} else {
try!(write!(&mut self.wr, ","));
}
try!(elt.serialize(self));
}
write!(&mut self.wr, "]")
}
#[inline]
fn serialize_map<
K: ser::Serialize<Serializer<W>, io::Error>,
V: ser::Serialize<Serializer<W>, io::Error>,
Iter: Iterator<Item=(K, V)>
>(&mut self, iter: Iter) -> io::Result<()> {
try!(write!(&mut self.wr, "{{"));
let mut first = true;
for (key, value) in iter {
if first {
first = false;
} else {
try!(write!(&mut self.wr, ","));
}
try!(key.serialize(self));
try!(write!(&mut self.wr, ":"));
try!(value.serialize(self));
}
write!(&mut self.wr, "}}")
}
}
/// Another serializer for JSON, but prints out human-readable JSON instead of
/// compact data
pub struct PrettySerializer<W> {
wr: W,
indent: usize,
first: bool,
}
impl<W: io::Write> PrettySerializer<W> {
/// Creates a new serializer whose output will be written to the specified writer
pub fn new(wr: W) -> PrettySerializer<W> {
PrettySerializer {
wr: wr,
writer: writer,
format: Format::Compact,
current_indent: 0,
indent: 0,
first: true,
}
}
/// Unwrap the io::Write from the Serializer.
pub fn unwrap(self) -> W {
self.wr
}
/// Creates a new JSON visitr whose output will be written to the writer
/// specified.
#[inline]
fn serialize_sep(&mut self) -> io::Result<()> {
if self.first {
self.first = false;
self.indent += 2;
try!(write!(&mut self.wr, "\n"));
} else {
try!(write!(&mut self.wr, ",\n"));
pub fn new_pretty(writer: W) -> Serializer<W> {
Serializer {
writer: writer,
format: Format::Pretty,
current_indent: 0,
indent: 2,
}
spaces(&mut self.wr, self.indent)
}
/// Unwrap the `Writer` from the `Serializer`.
#[inline]
fn serialize_end(&mut self, s: &str) -> io::Result<()> {
if !self.first {
try!(write!(&mut self.wr, "\n"));
self.indent -= 2;
try!(spaces(&mut self.wr, self.indent));
}
self.first = false;
write!(&mut self.wr, "{}", s)
pub fn into_inner(self) -> W {
self.writer
}
}
impl<W: io::Write> ser::Serializer<io::Error> for PrettySerializer<W> {
#[inline]
fn serialize_null(&mut self) -> io::Result<()> {
write!(&mut self.wr, "null")
}
impl<W: io::Write> ser::Serializer for Serializer<W> {
type Value = ();
type Error = io::Error;
#[inline]
fn serialize_bool(&mut self, v: bool) -> io::Result<()> {
if v {
self.wr.write_all(b"true")
} else {
self.wr.write_all(b"false")
}
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,
})
}
}
#[inline]
fn serialize_isize(&mut self, value: isize) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
struct Visitor<'a, W: 'a> {
writer: &'a mut W,
format: Format,
current_indent: usize,
indent: usize,
}
#[inline]
fn serialize_i8(&mut self, value: i8) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_i16(&mut self, value: i16) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_i32(&mut self, value: i32) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_i64(&mut self, value: i64) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_usize(&mut self, value: usize) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_u8(&mut self, value: u8) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_u16(&mut self, value: u16) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_u32(&mut self, value: u32) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_u64(&mut self, value: u64) -> io::Result<()> {
write!(&mut self.wr, "{}", value)
}
#[inline]
fn serialize_f32(&mut self, value: f32) -> io::Result<()> {
fmt_f32_or_null(&mut self.wr, value)
}
#[inline]
fn serialize_f64(&mut self, value: f64) -> io::Result<()> {
fmt_f64_or_null(&mut self.wr, value)
}
#[inline]
fn serialize_char(&mut self, value: char) -> io::Result<()> {
escape_char(&mut self.wr, value)
}
#[inline]
fn serialize_str(&mut self, value: &str) -> io::Result<()> {
escape_str(&mut self.wr, value)
}
#[inline]
fn serialize_tuple_start(&mut self, _len: usize) -> io::Result<()> {
self.first = true;
self.wr.write_all(b"[")
}
#[inline]
fn serialize_tuple_elt<
T: ser::Serialize<PrettySerializer<W>, io::Error>
>(&mut self, value: &T) -> io::Result<()> {
try!(self.serialize_sep());
value.serialize(self)
}
#[inline]
fn serialize_tuple_end(&mut self) -> io::Result<()> {
self.serialize_end("]")
}
#[inline]
fn serialize_struct_start(&mut self, _name: &str, _len: usize) -> io::Result<()> {
self.first = true;
self.wr.write_all(b"{")
}
#[inline]
fn serialize_struct_elt<
T: ser::Serialize<PrettySerializer<W>, io::Error>
>(&mut self, name: &str, value: &T) -> io::Result<()> {
try!(self.serialize_sep());
try!(self.serialize_str(name));
try!(self.wr.write_all(b": "));
value.serialize(self)
}
#[inline]
fn serialize_struct_end(&mut self) -> io::Result<()> {
self.serialize_end("}")
}
#[inline]
fn serialize_enum_start(&mut self, _name: &str, variant: &str, _len: usize) -> io::Result<()> {
self.first = true;
try!(self.wr.write_all(b"{"));
try!(self.serialize_sep());
try!(self.serialize_str(variant));
self.first = true;
self.wr.write_all(b": [")
}
#[inline]
fn serialize_enum_elt<
T: ser::Serialize<PrettySerializer<W>, io::Error>
>(&mut self, value: &T) -> io::Result<()> {
try!(self.serialize_sep());
value.serialize(self)
}
#[inline]
fn serialize_enum_end(&mut self) -> io::Result<()> {
try!(self.serialize_tuple_end());
self.serialize_struct_end()
}
#[inline]
fn serialize_option<
T: ser::Serialize<PrettySerializer<W>, io::Error>
>(&mut self, v: &Option<T>) -> io::Result<()> {
match *v {
Some(ref v) => {
v.serialize(self)
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",")
}
}
None => {
self.serialize_null()
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)
}
}
}
#[inline]
fn serialize_seq<
T: ser::Serialize<PrettySerializer<W>, io::Error>,
Iter: Iterator<Item=T>
>(&mut self, iter: Iter) -> io::Result<()> {
try!(self.wr.write_all(b"["));
self.first = true;
for elt in iter {
try!(self.serialize_sep());
try!(elt.serialize(self));
fn serialize_colon(&mut self) -> io::Result<()> {
match self.format {
Format::Compact => self.writer.write_all(b":"),
Format::Pretty => self.writer.write_all(b": "),
}
self.serialize_end("]")
}
#[inline]
fn serialize_map<
K: ser::Serialize<PrettySerializer<W>, io::Error>,
V: ser::Serialize<PrettySerializer<W>, io::Error>,
Iter: Iterator<Item=(K, V)>
>(&mut self, iter: Iter) -> io::Result<()> {
try!(self.wr.write_all(b"{"));
self.first = true;
for (key, value) in iter {
try!(self.serialize_sep());
try!(key.serialize(self));
try!(self.wr.write_all(b": "));
try!(value.serialize(self));
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.serialize_end("}")
self.writer.write_all(s)
}
}
fn escape_bytes<W>(wr: &mut W, bytes: &[u8]) -> io::Result<()>
impl<'a, W> ser::Visitor for Visitor<'a, W> where W: io::Write, {
type Value = ();
type Error = io::Error;
#[inline]
fn visit_bool(&mut self, value: bool) -> io::Result<()> {
if value {
self.writer.write_all(b"true")
} else {
self.writer.write_all(b"false")
}
}
#[inline]
fn visit_isize(&mut self, value: isize) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_i8(&mut self, value: i8) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_i16(&mut self, value: i16) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_i32(&mut self, value: i32) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_i64(&mut self, value: i64) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_usize(&mut self, value: usize) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_u8(&mut self, value: u8) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_u16(&mut self, value: u16) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_u32(&mut self, value: u32) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_u64(&mut self, value: u64) -> io::Result<()> {
write!(self.writer, "{}", value)
}
#[inline]
fn visit_f32(&mut self, value: f32) -> io::Result<()> {
fmt_f32_or_null(self.writer, value)
}
#[inline]
fn visit_f64(&mut self, value: f64) -> io::Result<()> {
fmt_f64_or_null(self.writer, value)
}
#[inline]
fn visit_char(&mut self, value: char) -> io::Result<()> {
escape_char(self.writer, value)
}
#[inline]
fn visit_str(&mut self, value: &str) -> io::Result<()> {
escape_str(self.writer, value)
}
#[inline]
fn visit_none(&mut self) -> io::Result<()> {
self.visit_unit()
}
#[inline]
fn visit_some<V>(&mut self, value: V) -> io::Result<()>
where V: ser::Serialize
{
value.visit(self)
}
#[inline]
fn visit_unit(&mut self) -> io::Result<()> {
self.writer.write_all(b"null")
}
#[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.visit_str(variant));
try!(self.serialize_colon());
try!(self.writer.write_all(b"[]"));
self.serialize_end(current_indent, b"}")
}
#[inline]
fn visit_seq<V>(&mut self, mut visitor: V) -> io::Result<()>
where V: ser::SeqVisitor,
{
let current_indent = self.current_indent;
try!(self.writer.write_all(b"["));
while let Some(()) = try!(visitor.visit(self)) { }
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.visit_str(variant));
try!(self.serialize_colon());
try!(self.visit_seq(visitor));
self.serialize_end(current_indent, b"}")
}
#[inline]
fn visit_seq_elt<T>(&mut self, first: bool, value: T) -> io::Result<()>
where T: ser::Serialize,
{
try!(self.serialize_sep(first));
value.visit(self)
}
#[inline]
fn visit_map<V>(&mut self, mut visitor: V) -> io::Result<()>
where V: ser::MapVisitor,
{
let current_indent = self.current_indent;
try!(self.writer.write_all(b"{"));
while let Some(()) = try!(visitor.visit(self)) { }
self.serialize_end(current_indent, 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.visit_str(variant));
try!(self.serialize_colon());
try!(self.visit_map(visitor));
self.serialize_end(current_indent, b"}")
}
#[inline]
fn visit_map_elt<K, V>(&mut self, first: bool, 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)
}
}
#[inline]
pub fn escape_bytes<W>(wr: &mut W, bytes: &[u8]) -> io::Result<()>
where W: io::Write
{
try!(wr.write_all(b"\""));
@@ -524,15 +336,18 @@ fn escape_bytes<W>(wr: &mut W, bytes: &[u8]) -> io::Result<()>
try!(wr.write_all(&bytes[start..]));
}
wr.write_all(b"\"")
try!(wr.write_all(b"\""));
Ok(())
}
#[inline]
pub fn escape_str<W>(wr: &mut W, value: &str) -> io::Result<()>
where W: io::Write
{
escape_bytes(wr, value.as_bytes())
}
#[inline]
fn escape_char<W>(wr: &mut W, value: char) -> io::Result<()>
where W: io::Write
{
@@ -559,9 +374,75 @@ fn fmt_f64_or_null<W>(wr: &mut W, value: f64) -> io::Result<()>
}
}
fn spaces<W: io::Write>(wr: &mut W, mut n: usize) -> io::Result<()> {
/// Encode the specified struct into a json `[u8]` writer.
#[inline]
pub fn to_writer<W, T>(writer: &mut W, value: &T) -> io::Result<()>
where W: io::Write,
T: ser::Serialize,
{
let mut ser = Serializer::new(writer);
try!(ser::Serializer::visit(&mut ser, value));
Ok(())
}
/// Encode the specified struct into a json `[u8]` writer.
#[inline]
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));
Ok(())
}
/// Encode the specified struct into a json `[u8]` buffer.
#[inline]
pub fn to_vec<T>(value: &T) -> Vec<u8>
where T: ser::Serialize,
{
// We are writing to a Vec, which doesn't fail. So we can ignore
// the error.
let mut writer = Vec::with_capacity(128);
to_writer(&mut writer, value).unwrap();
writer
}
/// Encode the specified struct into a json `[u8]` buffer.
#[inline]
pub fn to_vec_pretty<T>(value: &T) -> Vec<u8>
where T: ser::Serialize,
{
// We are writing to a Vec, which doesn't fail. So we can ignore
// the error.
let mut writer = Vec::with_capacity(128);
to_writer_pretty(&mut writer, value).unwrap();
writer
}
/// Encode the specified struct into a json `String` buffer.
#[inline]
pub fn to_string<T>(value: &T) -> Result<String, FromUtf8Error>
where T: ser::Serialize
{
let vec = to_vec(value);
String::from_utf8(vec)
}
/// Encode the specified struct into a json `String` buffer.
#[inline]
pub fn to_string_pretty<T>(value: &T) -> Result<String, FromUtf8Error>
where T: ser::Serialize
{
let vec = to_vec_pretty(value);
String::from_utf8(vec)
}
fn spaces<W>(wr: &mut W, mut n: usize) -> io::Result<()>
where W: io::Write,
{
const LEN: usize = 16;
const BUF: &'static [u8; LEN] = &[b' '; LEN];
const BUF: &'static [u8; LEN] = &[b' '; 16];
while n >= LEN {
try!(wr.write_all(BUF));
@@ -574,63 +455,3 @@ fn spaces<W: io::Write>(wr: &mut W, mut n: usize) -> io::Result<()> {
Ok(())
}
}
/// Encode the specified struct into a json `[u8]` writer.
#[inline]
pub fn to_writer<W, T>(writer: W, value: &T) -> io::Result<W>
where W: io::Write,
T: ser::Serialize<Serializer<W>, io::Error>
{
let mut serializer = Serializer::new(writer);
try!(value.serialize(&mut serializer));
Ok(serializer.unwrap())
}
/// Encode the specified struct into a json `[u8]` buffer.
#[inline]
pub fn to_vec<T>(value: &T) -> Vec<u8>
where T: ser::Serialize<Serializer<Vec<u8>>, io::Error>
{
// We are writing to a Vec, which doesn't fail. So we can ignore
// the error.
let writer = Vec::with_capacity(128);
to_writer(writer, value).unwrap()
}
/// Encode the specified struct into a json `String` buffer.
#[inline]
pub fn to_string<T>(value: &T) -> Result<String, FromUtf8Error>
where T: ser::Serialize<Serializer<Vec<u8>>, io::Error>
{
let vec = to_vec(value);
String::from_utf8(vec)
}
/// Encode the specified struct into a json `[u8]` writer.
#[inline]
pub fn to_pretty_writer<
W: io::Write,
T: ser::Serialize<PrettySerializer<W>, io::Error>
>(writer: W, value: &T) -> io::Result<W> {
let mut serializer = PrettySerializer::new(writer);
try!(value.serialize(&mut serializer));
Ok(serializer.unwrap())
}
/// Encode the specified struct into a json `[u8]` buffer.
pub fn to_pretty_vec<
T: ser::Serialize<PrettySerializer<Vec<u8>>, io::Error>
>(value: &T) -> Vec<u8> {
// We are writing to a Vec, which doesn't fail. So we can ignore
// the error.
let writer = Vec::with_capacity(128);
to_pretty_writer(writer, value).unwrap()
}
/// Encode the specified struct into a json `String` buffer.
pub fn to_pretty_string<
T: ser::Serialize<PrettySerializer<Vec<u8>>, io::Error>
>(value: &T) -> Result<String, FromUtf8Error> {
let buf = to_pretty_vec(value);
String::from_utf8(buf)
}
+526 -604
View File
File diff suppressed because it is too large Load Diff