From 0cb7a4062a3c69bb0c54f0c9136889a1006e4f62 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 3 Jan 2015 22:24:50 -0800 Subject: [PATCH] serialize: Use assoc types + less old_orphan_check This commit moves the libserialize crate (and will force the hand of the rustc-serialize crate) to not require the `old_orphan_check` feature gate as well as using associated types wherever possible. Concretely, the following changes were made: * The error type of `Encoder` and `Decoder` is now an associated type, meaning that these traits have no type parameters. * The `Encoder` and `Decoder` type parameters on the `Encodable` and `Decodable` traits have moved to the corresponding method of the trait. This movement alleviates the dependency on `old_orphan_check` but implies that implementations can no longer be specialized for the type of encoder/decoder being implemented. Due to the trait definitions changing, this is a: [breaking-change] --- src/librbml/lib.rs | 465 +- src/librustc/middle/astencode.rs | 23 + src/libserialize/collection_impls.rs | 128 +- src/libserialize/collection_impls_stage0.rs | 289 ++ src/libserialize/json.rs | 33 +- src/libserialize/json_stage0.rs | 3883 +++++++++++++++++ src/libserialize/lib.rs | 14 + src/libserialize/serialize.rs | 491 ++- src/libserialize/serialize_stage0.rs | 629 +++ src/libsyntax/ast.rs | 40 +- src/libsyntax/codemap.rs | 17 + src/libsyntax/ext/deriving/decodable.rs | 30 +- src/libsyntax/ext/deriving/encodable.rs | 32 +- src/libsyntax/owned_slice.rs | 19 + src/libsyntax/parse/token.rs | 17 + src/libsyntax/ptr.rs | 16 + .../compile-fail/variance-trait-matching-2.rs | 30 - src/test/run-pass/issue-11881.rs | 10 +- src/test/run-pass/issue-15924.rs | 2 +- src/test/run-pass/issue-4016.rs | 2 +- 20 files changed, 5744 insertions(+), 426 deletions(-) create mode 100644 src/libserialize/collection_impls_stage0.rs create mode 100644 src/libserialize/json_stage0.rs create mode 100644 src/libserialize/serialize_stage0.rs delete mode 100644 src/test/compile-fail/variance-trait-matching-2.rs diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index f7d5bfcd117..3acedac111d 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -25,7 +25,7 @@ html_playground_url = "http://play.rust-lang.org/")] #![allow(unknown_features)] #![feature(macro_rules, phase, slicing_syntax, globs)] -#![feature(unboxed_closures)] +#![feature(unboxed_closures, associated_types)] #![allow(missing_docs)] extern crate serialize; @@ -417,6 +417,7 @@ pub mod reader { } } + #[cfg(stage0)] impl<'doc> serialize::Decoder for Decoder<'doc> { fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) } @@ -671,6 +672,263 @@ pub mod reader { ApplicationError(err.to_string()) } } + + #[cfg(not(stage0))] + impl<'doc> serialize::Decoder for Decoder<'doc> { + type Error = Error; + fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) } + + fn read_u64(&mut self) -> DecodeResult { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) } + fn read_u32(&mut self) -> DecodeResult { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) } + fn read_u16(&mut self) -> DecodeResult { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) } + fn read_u8 (&mut self) -> DecodeResult { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) } + fn read_uint(&mut self) -> DecodeResult { + let v = doc_as_u64(try!(self.next_doc(EsUint))); + if v > (::std::uint::MAX as u64) { + Err(IntTooBig(v as uint)) + } else { + Ok(v as uint) + } + } + + fn read_i64(&mut self) -> DecodeResult { + Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64) + } + fn read_i32(&mut self) -> DecodeResult { + Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32) + } + fn read_i16(&mut self) -> DecodeResult { + Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16) + } + fn read_i8 (&mut self) -> DecodeResult { + Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8) + } + fn read_int(&mut self) -> DecodeResult { + let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64; + if v > (int::MAX as i64) || v < (int::MIN as i64) { + debug!("FIXME \\#6122: Removing this makes this function miscompile"); + Err(IntTooBig(v as uint)) + } else { + Ok(v as int) + } + } + + fn read_bool(&mut self) -> DecodeResult { + Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0) + } + + fn read_f64(&mut self) -> DecodeResult { + let bits = doc_as_u64(try!(self.next_doc(EsF64))); + Ok(unsafe { transmute(bits) }) + } + fn read_f32(&mut self) -> DecodeResult { + let bits = doc_as_u32(try!(self.next_doc(EsF32))); + Ok(unsafe { transmute(bits) }) + } + fn read_char(&mut self) -> DecodeResult { + Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap()) + } + fn read_str(&mut self) -> DecodeResult { + Ok(try!(self.next_doc(EsStr)).as_str()) + } + + // Compound types: + fn read_enum(&mut self, name: &str, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_enum({})", name); + try!(self._check_label(name)); + + let doc = try!(self.next_doc(EsEnum)); + + let (old_parent, old_pos) = (self.parent, self.pos); + self.parent = doc; + self.pos = self.parent.start; + + let result = try!(f(self)); + + self.parent = old_parent; + self.pos = old_pos; + Ok(result) + } + + fn read_enum_variant(&mut self, _: &[&str], + mut f: F) -> DecodeResult + where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult, + { + debug!("read_enum_variant()"); + let idx = try!(self._next_uint(EsEnumVid)); + debug!(" idx={}", idx); + + let doc = try!(self.next_doc(EsEnumBody)); + + let (old_parent, old_pos) = (self.parent, self.pos); + self.parent = doc; + self.pos = self.parent.start; + + let result = try!(f(self, idx)); + + self.parent = old_parent; + self.pos = old_pos; + Ok(result) + } + + fn read_enum_variant_arg(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_enum_variant_arg(idx={})", idx); + f(self) + } + + fn read_enum_struct_variant(&mut self, _: &[&str], + mut f: F) -> DecodeResult + where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult, + { + debug!("read_enum_struct_variant()"); + let idx = try!(self._next_uint(EsEnumVid)); + debug!(" idx={}", idx); + + let doc = try!(self.next_doc(EsEnumBody)); + + let (old_parent, old_pos) = (self.parent, self.pos); + self.parent = doc; + self.pos = self.parent.start; + + let result = try!(f(self, idx)); + + self.parent = old_parent; + self.pos = old_pos; + Ok(result) + } + + fn read_enum_struct_variant_field(&mut self, + name: &str, + idx: uint, + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx); + f(self) + } + + fn read_struct(&mut self, name: &str, _: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_struct(name={})", name); + f(self) + } + + fn read_struct_field(&mut self, name: &str, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_struct_field(name={}, idx={})", name, idx); + try!(self._check_label(name)); + f(self) + } + + fn read_tuple(&mut self, tuple_len: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_tuple()"); + self.read_seq(move |d, len| { + if len == tuple_len { + f(d) + } else { + Err(Expected(format!("Expected tuple of length `{}`, \ + found tuple of length `{}`", tuple_len, len))) + } + }) + } + + fn read_tuple_arg(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_tuple_arg(idx={})", idx); + self.read_seq_elt(idx, f) + } + + fn read_tuple_struct(&mut self, name: &str, len: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_tuple_struct(name={})", name); + self.read_tuple(len, f) + } + + fn read_tuple_struct_arg(&mut self, + idx: uint, + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_tuple_struct_arg(idx={})", idx); + self.read_tuple_arg(idx, f) + } + + fn read_option(&mut self, mut f: F) -> DecodeResult where + F: FnMut(&mut Decoder<'doc>, bool) -> DecodeResult, + { + debug!("read_option()"); + self.read_enum("Option", move |this| { + this.read_enum_variant(&["None", "Some"], move |this, idx| { + match idx { + 0 => f(this, false), + 1 => f(this, true), + _ => { + Err(Expected(format!("Expected None or Some"))) + } + } + }) + }) + } + + fn read_seq(&mut self, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult, + { + debug!("read_seq()"); + self.push_doc(EsVec, move |d| { + let len = try!(d._next_uint(EsVecLen)); + debug!(" len={}", len); + f(d, len) + }) + } + + fn read_seq_elt(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_seq_elt(idx={})", idx); + self.push_doc(EsVecElt, f) + } + + fn read_map(&mut self, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>, uint) -> DecodeResult, + { + debug!("read_map()"); + self.push_doc(EsMap, move |d| { + let len = try!(d._next_uint(EsMapLen)); + debug!(" len={}", len); + f(d, len) + }) + } + + fn read_map_elt_key(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_map_elt_key(idx={})", idx); + self.push_doc(EsMapKey, f) + } + + fn read_map_elt_val(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder<'doc>) -> DecodeResult, + { + debug!("read_map_elt_val(idx={})", idx); + self.push_doc(EsMapVal, f) + } + + fn error(&mut self, err: &str) -> Error { + ApplicationError(err.to_string()) + } + } } pub mod writer { @@ -872,7 +1130,212 @@ pub mod writer { } } + #[cfg(stage0)] impl<'a, W: Writer + Seek> serialize::Encoder for Encoder<'a, W> { + + fn emit_nil(&mut self) -> EncodeResult { + Ok(()) + } + + fn emit_uint(&mut self, v: uint) -> EncodeResult { + self.wr_tagged_u64(EsUint as uint, v as u64) + } + fn emit_u64(&mut self, v: u64) -> EncodeResult { + self.wr_tagged_u64(EsU64 as uint, v) + } + fn emit_u32(&mut self, v: u32) -> EncodeResult { + self.wr_tagged_u32(EsU32 as uint, v) + } + fn emit_u16(&mut self, v: u16) -> EncodeResult { + self.wr_tagged_u16(EsU16 as uint, v) + } + fn emit_u8(&mut self, v: u8) -> EncodeResult { + self.wr_tagged_u8(EsU8 as uint, v) + } + + fn emit_int(&mut self, v: int) -> EncodeResult { + self.wr_tagged_i64(EsInt as uint, v as i64) + } + fn emit_i64(&mut self, v: i64) -> EncodeResult { + self.wr_tagged_i64(EsI64 as uint, v) + } + fn emit_i32(&mut self, v: i32) -> EncodeResult { + self.wr_tagged_i32(EsI32 as uint, v) + } + fn emit_i16(&mut self, v: i16) -> EncodeResult { + self.wr_tagged_i16(EsI16 as uint, v) + } + fn emit_i8(&mut self, v: i8) -> EncodeResult { + self.wr_tagged_i8(EsI8 as uint, v) + } + + fn emit_bool(&mut self, v: bool) -> EncodeResult { + self.wr_tagged_u8(EsBool as uint, v as u8) + } + + fn emit_f64(&mut self, v: f64) -> EncodeResult { + let bits = unsafe { mem::transmute(v) }; + self.wr_tagged_u64(EsF64 as uint, bits) + } + fn emit_f32(&mut self, v: f32) -> EncodeResult { + let bits = unsafe { mem::transmute(v) }; + self.wr_tagged_u32(EsF32 as uint, bits) + } + fn emit_char(&mut self, v: char) -> EncodeResult { + self.wr_tagged_u32(EsChar as uint, v as u32) + } + + fn emit_str(&mut self, v: &str) -> EncodeResult { + self.wr_tagged_str(EsStr as uint, v) + } + + fn emit_enum(&mut self, name: &str, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + try!(self._emit_label(name)); + try!(self.start_tag(EsEnum as uint)); + try!(f(self)); + self.end_tag() + } + + fn emit_enum_variant(&mut self, + _: &str, + v_id: uint, + _: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + try!(self._emit_tagged_uint(EsEnumVid, v_id)); + try!(self.start_tag(EsEnumBody as uint)); + try!(f(self)); + self.end_tag() + } + + fn emit_enum_variant_arg(&mut self, _: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + f(self) + } + + fn emit_enum_struct_variant(&mut self, + v_name: &str, + v_id: uint, + cnt: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + self.emit_enum_variant(v_name, v_id, cnt, f) + } + + fn emit_enum_struct_variant_field(&mut self, + _: &str, + idx: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + self.emit_enum_variant_arg(idx, f) + } + + fn emit_struct(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + f(self) + } + + fn emit_struct_field(&mut self, name: &str, _: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + try!(self._emit_label(name)); + f(self) + } + + fn emit_tuple(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + self.emit_seq(len, f) + } + fn emit_tuple_arg(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + self.emit_seq_elt(idx, f) + } + + fn emit_tuple_struct(&mut self, _: &str, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + self.emit_seq(len, f) + } + fn emit_tuple_struct_arg(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + self.emit_seq_elt(idx, f) + } + + fn emit_option(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + self.emit_enum("Option", f) + } + fn emit_option_none(&mut self) -> EncodeResult { + self.emit_enum_variant("None", 0, 0, |_| Ok(())) + } + fn emit_option_some(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + + self.emit_enum_variant("Some", 1, 1, f) + } + + fn emit_seq(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + + try!(self.start_tag(EsVec as uint)); + try!(self._emit_tagged_uint(EsVecLen, len)); + try!(f(self)); + self.end_tag() + } + + fn emit_seq_elt(&mut self, _idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + + try!(self.start_tag(EsVecElt as uint)); + try!(f(self)); + self.end_tag() + } + + fn emit_map(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + + try!(self.start_tag(EsMap as uint)); + try!(self._emit_tagged_uint(EsMapLen, len)); + try!(f(self)); + self.end_tag() + } + + fn emit_map_elt_key(&mut self, _idx: uint, mut f: F) -> EncodeResult where + F: FnMut(&mut Encoder<'a, W>) -> EncodeResult, + { + + try!(self.start_tag(EsMapKey as uint)); + try!(f(self)); + self.end_tag() + } + + fn emit_map_elt_val(&mut self, _idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult, + { + try!(self.start_tag(EsMapVal as uint)); + try!(f(self)); + self.end_tag() + } + } + #[cfg(not(stage0))] + impl<'a, W: Writer + Seek> serialize::Encoder for Encoder<'a, W> { + type Error = io::IoError; + fn emit_nil(&mut self) -> EncodeResult { Ok(()) } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index e4d407d66a2..269b09a5f2e 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -263,18 +263,27 @@ trait def_id_encoder_helpers { fn emit_def_id(&mut self, did: ast::DefId); } +#[cfg(stage0)] impl, E> def_id_encoder_helpers for S { fn emit_def_id(&mut self, did: ast::DefId) { did.encode(self).ok().unwrap() } } +#[cfg(not(stage0))] +impl def_id_encoder_helpers for S { + fn emit_def_id(&mut self, did: ast::DefId) { + did.encode(self).ok().unwrap() + } +} + trait def_id_decoder_helpers { fn read_def_id(&mut self, dcx: &DecodeContext) -> ast::DefId; fn read_def_id_nodcx(&mut self, cdata: &cstore::crate_metadata) -> ast::DefId; } +#[cfg(stage0)] impl, E> def_id_decoder_helpers for D { fn read_def_id(&mut self, dcx: &DecodeContext) -> ast::DefId { let did: ast::DefId = Decodable::decode(self).ok().unwrap(); @@ -288,6 +297,20 @@ impl, E> def_id_decoder_helpers for D { } } +#[cfg(not(stage0))] +impl def_id_decoder_helpers for D { + fn read_def_id(&mut self, dcx: &DecodeContext) -> ast::DefId { + let did: ast::DefId = Decodable::decode(self).ok().unwrap(); + did.tr(dcx) + } + + fn read_def_id_nodcx(&mut self, + cdata: &cstore::crate_metadata) -> ast::DefId { + let did: ast::DefId = Decodable::decode(self).ok().unwrap(); + decoder::translate_def_id(cdata, did) + } +} + // ______________________________________________________________________ // Encoding and decoding the AST itself // diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index f2d79b13346..7ba329c518e 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -19,11 +19,9 @@ use std::collections::{DList, RingBuf, BTreeMap, BTreeSet, HashMap, HashSet, Vec use collections::enum_set::{EnumSet, CLike}; impl< - E, - S: Encoder, - T: Encodable -> Encodable for DList { - fn encode(&self, s: &mut S) -> Result<(), E> { + T: Encodable +> Encodable for DList { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { for (i, e) in self.iter().enumerate() { try!(s.emit_seq_elt(i, |s| e.encode(s))); @@ -33,8 +31,8 @@ impl< } } -impl,T:Decodable> Decodable for DList { - fn decode(d: &mut D) -> Result, E> { +impl Decodable for DList { + fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { let mut list = DList::new(); for i in range(0u, len) { @@ -45,12 +43,8 @@ impl,T:Decodable> Decodable for DList { } } -impl< - E, - S: Encoder, - T: Encodable -> Encodable for RingBuf { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for RingBuf { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { for (i, e) in self.iter().enumerate() { try!(s.emit_seq_elt(i, |s| e.encode(s))); @@ -60,8 +54,8 @@ impl< } } -impl,T:Decodable> Decodable for RingBuf { - fn decode(d: &mut D) -> Result, E> { +impl Decodable for RingBuf { + fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { let mut deque: RingBuf = RingBuf::new(); for i in range(0u, len) { @@ -73,12 +67,10 @@ impl,T:Decodable> Decodable for RingBuf { } impl< - E, - S: Encoder, - K: Encodable + PartialEq + Ord, - V: Encodable + PartialEq -> Encodable for BTreeMap { - fn encode(&self, e: &mut S) -> Result<(), E> { + K: Encodable + PartialEq + Ord, + V: Encodable + PartialEq +> Encodable for BTreeMap { + fn encode(&self, e: &mut S) -> Result<(), S::Error> { e.emit_map(self.len(), |e| { let mut i = 0; for (key, val) in self.iter() { @@ -92,12 +84,10 @@ impl< } impl< - E, - D: Decoder, - K: Decodable + PartialEq + Ord, - V: Decodable + PartialEq -> Decodable for BTreeMap { - fn decode(d: &mut D) -> Result, E> { + K: Decodable + PartialEq + Ord, + V: Decodable + PartialEq +> Decodable for BTreeMap { + fn decode(d: &mut D) -> Result, D::Error> { d.read_map(|d, len| { let mut map = BTreeMap::new(); for i in range(0u, len) { @@ -111,11 +101,9 @@ impl< } impl< - E, - S: Encoder, - T: Encodable + PartialEq + Ord -> Encodable for BTreeSet { - fn encode(&self, s: &mut S) -> Result<(), E> { + T: Encodable + PartialEq + Ord +> Encodable for BTreeSet { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { let mut i = 0; for e in self.iter() { @@ -128,11 +116,9 @@ impl< } impl< - E, - D: Decoder, - T: Decodable + PartialEq + Ord -> Decodable for BTreeSet { - fn decode(d: &mut D) -> Result, E> { + T: Decodable + PartialEq + Ord +> Decodable for BTreeSet { + fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { let mut set = BTreeSet::new(); for i in range(0u, len) { @@ -144,11 +130,9 @@ impl< } impl< - E, - S: Encoder, - T: Encodable + CLike -> Encodable for EnumSet { - fn encode(&self, s: &mut S) -> Result<(), E> { + T: Encodable + CLike +> Encodable for EnumSet { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { let mut bits = 0; for item in self.iter() { bits |= item.to_uint(); @@ -158,11 +142,9 @@ impl< } impl< - E, - D: Decoder, - T: Decodable + CLike -> Decodable for EnumSet { - fn decode(d: &mut D) -> Result, E> { + T: Decodable + CLike +> Decodable for EnumSet { + fn decode(d: &mut D) -> Result, D::Error> { let bits = try!(d.read_uint()); let mut set = EnumSet::new(); for bit in range(0, uint::BITS) { @@ -175,14 +157,12 @@ impl< } impl< - E, - S: Encoder, - K: Encodable + Hash + Eq, - V: Encodable, + K: Encodable + Hash + Eq, + V: Encodable, X, H: Hasher -> Encodable for HashMap { - fn encode(&self, e: &mut S) -> Result<(), E> { +> Encodable for HashMap { + fn encode(&self, e: &mut S) -> Result<(), S::Error> { e.emit_map(self.len(), |e| { let mut i = 0; for (key, val) in self.iter() { @@ -196,14 +176,12 @@ impl< } impl< - E, - D: Decoder, - K: Decodable + Hash + Eq, - V: Decodable, + K: Decodable + Hash + Eq, + V: Decodable, S, H: Hasher + Default -> Decodable for HashMap { - fn decode(d: &mut D) -> Result, E> { +> Decodable for HashMap { + fn decode(d: &mut D) -> Result, D::Error> { d.read_map(|d, len| { let hasher = Default::default(); let mut map = HashMap::with_capacity_and_hasher(len, hasher); @@ -218,13 +196,11 @@ impl< } impl< - E, - S: Encoder, - T: Encodable + Hash + Eq, + T: Encodable + Hash + Eq, X, H: Hasher -> Encodable for HashSet { - fn encode(&self, s: &mut S) -> Result<(), E> { +> Encodable for HashSet { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { let mut i = 0; for e in self.iter() { @@ -237,13 +213,11 @@ impl< } impl< - E, - D: Decoder, - T: Decodable + Hash + Eq, + T: Decodable + Hash + Eq, S, H: Hasher + Default -> Decodable for HashSet { - fn decode(d: &mut D) -> Result, E> { +> Decodable for HashSet { + fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { let mut set = HashSet::with_capacity_and_hasher(len, Default::default()); for i in range(0u, len) { @@ -254,12 +228,8 @@ impl< } } -impl< - E, - S: Encoder, - V: Encodable -> Encodable for VecMap { - fn encode(&self, e: &mut S) -> Result<(), E> { +impl Encodable for VecMap { + fn encode(&self, e: &mut S) -> Result<(), S::Error> { e.emit_map(self.len(), |e| { for (i, (key, val)) in self.iter().enumerate() { try!(e.emit_map_elt_key(i, |e| key.encode(e))); @@ -270,12 +240,8 @@ impl< } } -impl< - E, - D: Decoder, - V: Decodable -> Decodable for VecMap { - fn decode(d: &mut D) -> Result, E> { +impl Decodable for VecMap { + fn decode(d: &mut D) -> Result, D::Error> { d.read_map(|d, len| { let mut map = VecMap::new(); for i in range(0u, len) { diff --git a/src/libserialize/collection_impls_stage0.rs b/src/libserialize/collection_impls_stage0.rs new file mode 100644 index 00000000000..f2d79b13346 --- /dev/null +++ b/src/libserialize/collection_impls_stage0.rs @@ -0,0 +1,289 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Implementations of serialization for structures found in libcollections + +use std::uint; +use std::default::Default; +use std::hash::{Hash, Hasher}; + +use {Decodable, Encodable, Decoder, Encoder}; +use std::collections::{DList, RingBuf, BTreeMap, BTreeSet, HashMap, HashSet, VecMap}; +use collections::enum_set::{EnumSet, CLike}; + +impl< + E, + S: Encoder, + T: Encodable +> Encodable for DList { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_seq(self.len(), |s| { + for (i, e) in self.iter().enumerate() { + try!(s.emit_seq_elt(i, |s| e.encode(s))); + } + Ok(()) + }) + } +} + +impl,T:Decodable> Decodable for DList { + fn decode(d: &mut D) -> Result, E> { + d.read_seq(|d, len| { + let mut list = DList::new(); + for i in range(0u, len) { + list.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); + } + Ok(list) + }) + } +} + +impl< + E, + S: Encoder, + T: Encodable +> Encodable for RingBuf { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_seq(self.len(), |s| { + for (i, e) in self.iter().enumerate() { + try!(s.emit_seq_elt(i, |s| e.encode(s))); + } + Ok(()) + }) + } +} + +impl,T:Decodable> Decodable for RingBuf { + fn decode(d: &mut D) -> Result, E> { + d.read_seq(|d, len| { + let mut deque: RingBuf = RingBuf::new(); + for i in range(0u, len) { + deque.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); + } + Ok(deque) + }) + } +} + +impl< + E, + S: Encoder, + K: Encodable + PartialEq + Ord, + V: Encodable + PartialEq +> Encodable for BTreeMap { + fn encode(&self, e: &mut S) -> Result<(), E> { + e.emit_map(self.len(), |e| { + let mut i = 0; + for (key, val) in self.iter() { + try!(e.emit_map_elt_key(i, |e| key.encode(e))); + try!(e.emit_map_elt_val(i, |e| val.encode(e))); + i += 1; + } + Ok(()) + }) + } +} + +impl< + E, + D: Decoder, + K: Decodable + PartialEq + Ord, + V: Decodable + PartialEq +> Decodable for BTreeMap { + fn decode(d: &mut D) -> Result, E> { + d.read_map(|d, len| { + let mut map = BTreeMap::new(); + for i in range(0u, len) { + let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d))); + let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d))); + map.insert(key, val); + } + Ok(map) + }) + } +} + +impl< + E, + S: Encoder, + T: Encodable + PartialEq + Ord +> Encodable for BTreeSet { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_seq(self.len(), |s| { + let mut i = 0; + for e in self.iter() { + try!(s.emit_seq_elt(i, |s| e.encode(s))); + i += 1; + } + Ok(()) + }) + } +} + +impl< + E, + D: Decoder, + T: Decodable + PartialEq + Ord +> Decodable for BTreeSet { + fn decode(d: &mut D) -> Result, E> { + d.read_seq(|d, len| { + let mut set = BTreeSet::new(); + for i in range(0u, len) { + set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); + } + Ok(set) + }) + } +} + +impl< + E, + S: Encoder, + T: Encodable + CLike +> Encodable for EnumSet { + fn encode(&self, s: &mut S) -> Result<(), E> { + let mut bits = 0; + for item in self.iter() { + bits |= item.to_uint(); + } + s.emit_uint(bits) + } +} + +impl< + E, + D: Decoder, + T: Decodable + CLike +> Decodable for EnumSet { + fn decode(d: &mut D) -> Result, E> { + let bits = try!(d.read_uint()); + let mut set = EnumSet::new(); + for bit in range(0, uint::BITS) { + if bits & (1 << bit) != 0 { + set.insert(CLike::from_uint(1 << bit)); + } + } + Ok(set) + } +} + +impl< + E, + S: Encoder, + K: Encodable + Hash + Eq, + V: Encodable, + X, + H: Hasher +> Encodable for HashMap { + fn encode(&self, e: &mut S) -> Result<(), E> { + e.emit_map(self.len(), |e| { + let mut i = 0; + for (key, val) in self.iter() { + try!(e.emit_map_elt_key(i, |e| key.encode(e))); + try!(e.emit_map_elt_val(i, |e| val.encode(e))); + i += 1; + } + Ok(()) + }) + } +} + +impl< + E, + D: Decoder, + K: Decodable + Hash + Eq, + V: Decodable, + S, + H: Hasher + Default +> Decodable for HashMap { + fn decode(d: &mut D) -> Result, E> { + d.read_map(|d, len| { + let hasher = Default::default(); + let mut map = HashMap::with_capacity_and_hasher(len, hasher); + for i in range(0u, len) { + let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d))); + let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d))); + map.insert(key, val); + } + Ok(map) + }) + } +} + +impl< + E, + S: Encoder, + T: Encodable + Hash + Eq, + X, + H: Hasher +> Encodable for HashSet { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_seq(self.len(), |s| { + let mut i = 0; + for e in self.iter() { + try!(s.emit_seq_elt(i, |s| e.encode(s))); + i += 1; + } + Ok(()) + }) + } +} + +impl< + E, + D: Decoder, + T: Decodable + Hash + Eq, + S, + H: Hasher + Default +> Decodable for HashSet { + fn decode(d: &mut D) -> Result, E> { + d.read_seq(|d, len| { + let mut set = HashSet::with_capacity_and_hasher(len, Default::default()); + for i in range(0u, len) { + set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); + } + Ok(set) + }) + } +} + +impl< + E, + S: Encoder, + V: Encodable +> Encodable for VecMap { + fn encode(&self, e: &mut S) -> Result<(), E> { + e.emit_map(self.len(), |e| { + for (i, (key, val)) in self.iter().enumerate() { + try!(e.emit_map_elt_key(i, |e| key.encode(e))); + try!(e.emit_map_elt_val(i, |e| val.encode(e))); + } + Ok(()) + }) + } +} + +impl< + E, + D: Decoder, + V: Decodable +> Decodable for VecMap { + fn decode(d: &mut D) -> Result, E> { + d.read_map(|d, len| { + let mut map = VecMap::new(); + for i in range(0u, len) { + let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d))); + let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d))); + map.insert(key, val); + } + Ok(map) + }) + } +} diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index e31d8157332..e8bd46815e6 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -300,7 +300,7 @@ pub fn error_str(error: ErrorCode) -> &'static str { } /// Shortcut function to decode a JSON `&str` into an object -pub fn decode>(s: &str) -> DecodeResult { +pub fn decode(s: &str) -> DecodeResult { let json = match from_str(s) { Ok(x) => x, Err(e) => return Err(ParseError(e)) @@ -311,9 +311,7 @@ pub fn decode>(s: &str) -> DecodeResult } /// Shortcut function to encode a `T` into a JSON `String` -pub fn encode(object: &T) -> string::String - where T: for<'a> Encodable, fmt::Error> -{ +pub fn encode(object: &T) -> string::String { let mut s = String::new(); { let mut encoder = Encoder::new(&mut s); @@ -444,7 +442,9 @@ impl<'a> Encoder<'a> { } } -impl<'a> ::Encoder for Encoder<'a> { +impl<'a> ::Encoder for Encoder<'a> { + type Error = fmt::Error; + fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") } fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) } @@ -664,7 +664,9 @@ impl<'a> PrettyEncoder<'a> { } } -impl<'a> ::Encoder for PrettyEncoder<'a> { +impl<'a> ::Encoder for PrettyEncoder<'a> { + type Error = fmt::Error; + fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") } fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) } @@ -909,8 +911,8 @@ impl<'a> ::Encoder for PrettyEncoder<'a> { } } -impl, S> Encodable for Json { - fn encode(&self, e: &mut E) -> Result<(), S> { +impl Encodable for Json { + fn encode(&self, e: &mut E) -> Result<(), E::Error> { match *self { Json::I64(v) => v.encode(e), Json::U64(v) => v.encode(e), @@ -2062,7 +2064,9 @@ macro_rules! read_primitive { } } -impl ::Decoder for Decoder { +impl ::Decoder for Decoder { + type Error = DecoderError; + fn read_nil(&mut self) -> DecodeResult<()> { expect!(self.pop(), Null) } @@ -2474,9 +2478,7 @@ impl<'a> fmt::Show for PrettyJson<'a> { } } -impl<'a, T> fmt::Show for AsJson<'a, T> - where T: for<'b> Encodable, fmt::Error> -{ +impl<'a, T: Encodable> fmt::Show for AsJson<'a, T> { /// Encodes a json value into a string fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut shim = FormatShim { inner: f }; @@ -2493,9 +2495,7 @@ impl<'a, T> AsPrettyJson<'a, T> { } } -impl<'a, T> fmt::Show for AsPrettyJson<'a, T> - where T: for<'b> Encodable, fmt::Error> -{ +impl<'a, T: Encodable> fmt::Show for AsPrettyJson<'a, T> { /// Encodes a json value into a string fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut shim = FormatShim { inner: f }; @@ -3155,8 +3155,7 @@ mod tests { A(f64), B(string::String) } - fn check_err>(to_parse: &'static str, - expected: DecoderError) { + fn check_err(to_parse: &'static str, expected: DecoderError) { let res: DecodeResult = match from_str(to_parse) { Err(e) => Err(ParseError(e)), Ok(json) => Decodable::decode(&mut Decoder::new(json)) diff --git a/src/libserialize/json_stage0.rs b/src/libserialize/json_stage0.rs new file mode 100644 index 00000000000..84180159c2b --- /dev/null +++ b/src/libserialize/json_stage0.rs @@ -0,0 +1,3883 @@ +// Copyright 2012-2014 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 or the MIT license +// , 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 to encode structured data in a text format that can be easily read by humans +//! Its simple syntax and native compatibility with JavaScript have made it a widely used format. +//! +//! Data types that can be encoded are JavaScript types (see the `Json` enum for more details): +//! +//! * `Boolean`: equivalent to rust's `bool` +//! * `Number`: equivalent to rust's `f64` +//! * `String`: equivalent to rust's `String` +//! * `Array`: equivalent to rust's `Vec`, but also allowing objects of different types in the +//! same array +//! * `Object`: equivalent to rust's `BTreeMap` +//! * `Null` +//! +//! An object is a series of string keys mapping to values, in `"key": value` format. +//! Arrays are enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }). +//! A simple JSON document encoding a person, his/her age, address and phone numbers could look like +//! +//! ```ignore +//! { +//! "FirstName": "John", +//! "LastName": "Doe", +//! "Age": 43, +//! "Address": { +//! "Street": "Downing Street 10", +//! "City": "London", +//! "Country": "Great Britain" +//! }, +//! "PhoneNumbers": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! } +//! ``` +//! +//! # Rust Type-based Encoding and Decoding +//! +//! Rust provides a mechanism for low boilerplate encoding & decoding of values to and from JSON via +//! the serialization API. +//! To be able to encode a piece of data, it must implement the `serialize::RustcEncodable` trait. +//! To be able to decode a piece of data, it must implement the `serialize::RustcDecodable` trait. +//! The Rust compiler provides an annotation to automatically generate the code for these traits: +//! `#[derive(RustcDecodable, RustcEncodable)]` +//! +//! The JSON API provides an enum `json::Json` and a trait `ToJson` to encode objects. +//! The `ToJson` trait provides a `to_json` method to convert an object into a `json::Json` value. +//! A `json::Json` value can be encoded as a string or buffer using the functions described above. +//! You can also use the `json::Encoder` object, which implements the `Encoder` trait. +//! +//! When using `ToJson` the `RustcEncodable` trait implementation is not mandatory. +//! +//! # Examples of use +//! +//! ## Using Autoserialization +//! +//! Create a struct called `TestStruct` and serialize and deserialize it to and from JSON using the +//! serialization API, using the derived serialization code. +//! +//! ```notrust +//! // FIXME(#19470): this cannot be ```rust``` because it fails orphan checking at the moment +//! extern crate serialize; +//! use serialize::json; +//! +//! // Automatically generate `Decodable` and `Encodable` trait implementations +//! #[derive(RustcDecodable, RustcEncodable)] +//! pub struct TestStruct { +//! data_int: u8, +//! data_str: String, +//! data_vector: Vec, +//! } +//! +//! fn main() { +//! let object = TestStruct { +//! data_int: 1, +//! data_str: "homura".to_string(), +//! data_vector: vec![2,3,4,5], +//! }; +//! +//! // Serialize using `json::encode` +//! let encoded = json::encode(&object); +//! +//! // Deserialize using `json::decode` +//! let decoded: TestStruct = json::decode(encoded.as_slice()).unwrap(); +//! } +//! ``` +//! +//! ## Using the `ToJson` trait +//! +//! The examples above use the `ToJson` trait to generate the JSON string, which is required +//! for custom mappings. +//! +//! ### Simple example of `ToJson` usage +//! +//! ```notrust +//! // FIXME(#19470): this cannot be ```rust``` because it fails orphan checking at the moment +//! extern crate serialize; +//! use serialize::json::{mod, ToJson, Json}; +//! +//! // A custom data structure +//! struct ComplexNum { +//! a: f64, +//! b: f64, +//! } +//! +//! // JSON value representation +//! impl ToJson for ComplexNum { +//! fn to_json(&self) -> Json { +//! Json::String(format!("{}+{}i", self.a, self.b)) +//! } +//! } +//! +//! // Only generate `RustcEncodable` trait implementation +//! #[derive(Encodable)] +//! pub struct ComplexNumRecord { +//! uid: u8, +//! dsc: String, +//! val: Json, +//! } +//! +//! fn main() { +//! let num = ComplexNum { a: 0.0001, b: 12.539 }; +//! let data: String = json::encode(&ComplexNumRecord{ +//! uid: 1, +//! dsc: "test".to_string(), +//! val: num.to_json(), +//! }); +//! println!("data: {}", data); +//! // data: {"uid":1,"dsc":"test","val":"0.0001+12.539j"}; +//! } +//! ``` +//! +//! ### Verbose example of `ToJson` usage +//! +//! ```notrust +//! // FIXME(#19470): this cannot be ```rust``` because it fails orphan checking at the moment +//! extern crate serialize; +//! use std::collections::BTreeMap; +//! use serialize::json::{mod, Json, ToJson}; +//! +//! // Only generate `Decodable` trait implementation +//! #[derive(Decodable)] +//! pub struct TestStruct { +//! data_int: u8, +//! data_str: String, +//! data_vector: Vec, +//! } +//! +//! // Specify encoding method manually +//! impl ToJson for TestStruct { +//! fn to_json(&self) -> Json { +//! let mut d = BTreeMap::new(); +//! // All standard types implement `to_json()`, so use it +//! d.insert("data_int".to_string(), self.data_int.to_json()); +//! d.insert("data_str".to_string(), self.data_str.to_json()); +//! d.insert("data_vector".to_string(), self.data_vector.to_json()); +//! Json::Object(d) +//! } +//! } +//! +//! fn main() { +//! // Serialize using `ToJson` +//! let input_data = TestStruct { +//! data_int: 1, +//! data_str: "madoka".to_string(), +//! data_vector: vec![2,3,4,5], +//! }; +//! let json_obj: Json = input_data.to_json(); +//! let json_str: String = json_obj.to_string(); +//! +//! // Deserialize like before +//! let decoded: TestStruct = json::decode(json_str.as_slice()).unwrap(); +//! } +//! ``` + +use self::JsonEvent::*; +use self::StackElement::*; +use self::ErrorCode::*; +use self::ParserError::*; +use self::DecoderError::*; +use self::ParserState::*; +use self::InternalStackElement::*; + +use std; +use std::collections::{HashMap, BTreeMap}; +use std::{char, f64, fmt, io, num, str}; +use std::mem::{swap, transmute}; +use std::num::{Float, Int}; +use std::num::FpCategory as Fp; +use std::str::FromStr; +use std::string; +use std::ops; +use unicode::str as unicode_str; +use unicode::str::Utf16Item; + +use Encodable; + +/// Represents a json value +#[derive(Clone, PartialEq, PartialOrd)] +pub enum Json { + I64(i64), + U64(u64), + F64(f64), + String(string::String), + Boolean(bool), + Array(self::Array), + Object(self::Object), + Null, +} + +pub type Array = Vec; +pub type Object = BTreeMap; + +pub struct PrettyJson<'a> { inner: &'a Json } + +pub struct AsJson<'a, T: 'a> { inner: &'a T } +pub struct AsPrettyJson<'a, T: 'a> { inner: &'a T, indent: Option } + +/// The errors that can arise while parsing a JSON stream. +#[derive(Clone, Copy, PartialEq)] +pub enum ErrorCode { + InvalidSyntax, + InvalidNumber, + EOFWhileParsingObject, + EOFWhileParsingArray, + EOFWhileParsingValue, + EOFWhileParsingString, + KeyMustBeAString, + ExpectedColon, + TrailingCharacters, + TrailingComma, + InvalidEscape, + InvalidUnicodeCodePoint, + LoneLeadingSurrogateInHexEscape, + UnexpectedEndOfHexEscape, + UnrecognizedHex, + NotFourDigit, + NotUtf8, +} + +#[derive(Clone, Copy, PartialEq, Show)] +pub enum ParserError { + /// msg, line, col + SyntaxError(ErrorCode, uint, uint), + IoError(io::IoErrorKind, &'static str), +} + +// Builder and Parser have the same errors. +pub type BuilderError = ParserError; + +#[derive(Clone, PartialEq, Show)] +pub enum DecoderError { + ParseError(ParserError), + ExpectedError(string::String, string::String), + MissingFieldError(string::String), + UnknownVariantError(string::String), + ApplicationError(string::String) +} + +/// Returns a readable error string for a given error code. +pub fn error_str(error: ErrorCode) -> &'static str { + match error { + InvalidSyntax => "invalid syntax", + InvalidNumber => "invalid number", + EOFWhileParsingObject => "EOF While parsing object", + EOFWhileParsingArray => "EOF While parsing array", + EOFWhileParsingValue => "EOF While parsing value", + EOFWhileParsingString => "EOF While parsing string", + KeyMustBeAString => "key must be a string", + ExpectedColon => "expected `:`", + TrailingCharacters => "trailing characters", + TrailingComma => "trailing comma", + InvalidEscape => "invalid escape", + UnrecognizedHex => "invalid \\u{ esc}ape (unrecognized hex)", + NotFourDigit => "invalid \\u{ esc}ape (not four digits)", + NotUtf8 => "contents not utf-8", + InvalidUnicodeCodePoint => "invalid Unicode code point", + LoneLeadingSurrogateInHexEscape => "lone leading surrogate in hex escape", + UnexpectedEndOfHexEscape => "unexpected end of hex escape", + } +} + +/// Shortcut function to decode a JSON `&str` into an object +pub fn decode>(s: &str) -> DecodeResult { + let json = match from_str(s) { + Ok(x) => x, + Err(e) => return Err(ParseError(e)) + }; + + let mut decoder = Decoder::new(json); + ::Decodable::decode(&mut decoder) +} + +/// Shortcut function to encode a `T` into a JSON `String` +pub fn encode(object: &T) -> string::String + where T: for<'a> Encodable, fmt::Error> +{ + let mut s = String::new(); + { + let mut encoder = Encoder::new(&mut s); + let _ = object.encode(&mut encoder); + } + s +} + +impl fmt::Show for ErrorCode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + error_str(*self).fmt(f) + } +} + +fn io_error_to_error(io: io::IoError) -> ParserError { + IoError(io.kind, io.desc) +} + +impl std::error::Error for DecoderError { + fn description(&self) -> &str { "decoder error" } + fn detail(&self) -> Option { Some(self.to_string()) } +} + +pub type EncodeResult = fmt::Result; +pub type DecodeResult = Result; + +fn escape_str(wr: &mut fmt::Writer, v: &str) -> fmt::Result { + try!(wr.write_str("\"")); + + let mut start = 0; + + for (i, byte) in v.bytes().enumerate() { + let escaped = match byte { + b'"' => "\\\"", + b'\\' => "\\\\", + b'\x00' => "\\u0000", + b'\x01' => "\\u0001", + b'\x02' => "\\u0002", + b'\x03' => "\\u0003", + b'\x04' => "\\u0004", + b'\x05' => "\\u0005", + b'\x06' => "\\u0006", + b'\x07' => "\\u0007", + b'\x08' => "\\b", + b'\t' => "\\t", + b'\n' => "\\n", + b'\x0b' => "\\u000b", + b'\x0c' => "\\f", + b'\r' => "\\r", + b'\x0e' => "\\u000e", + b'\x0f' => "\\u000f", + b'\x10' => "\\u0010", + b'\x11' => "\\u0011", + b'\x12' => "\\u0012", + b'\x13' => "\\u0013", + b'\x14' => "\\u0014", + b'\x15' => "\\u0015", + b'\x16' => "\\u0016", + b'\x17' => "\\u0017", + b'\x18' => "\\u0018", + b'\x19' => "\\u0019", + b'\x1a' => "\\u001a", + b'\x1b' => "\\u001b", + b'\x1c' => "\\u001c", + b'\x1d' => "\\u001d", + b'\x1e' => "\\u001e", + b'\x1f' => "\\u001f", + b'\x7f' => "\\u007f", + _ => { continue; } + }; + + if start < i { + try!(wr.write_str(v[start..i])); + } + + try!(wr.write_str(escaped)); + + start = i + 1; + } + + if start != v.len() { + try!(wr.write_str(v[start..])); + } + + wr.write_str("\"") +} + +fn escape_char(writer: &mut fmt::Writer, v: char) -> fmt::Result { + let mut buf = [0; 4]; + let n = v.encode_utf8(&mut buf).unwrap(); + let buf = unsafe { str::from_utf8_unchecked(buf[0..n]) }; + escape_str(writer, buf) +} + +fn spaces(wr: &mut fmt::Writer, mut n: uint) -> fmt::Result { + const BUF: &'static str = " "; + + while n >= BUF.len() { + try!(wr.write_str(BUF)); + n -= BUF.len(); + } + + if n > 0 { + wr.write_str(BUF[..n]) + } else { + Ok(()) + } +} + +fn fmt_number_or_null(v: f64) -> string::String { + match v.classify() { + Fp::Nan | Fp::Infinite => string::String::from_str("null"), + _ if v.fract() != 0f64 => f64::to_str_digits(v, 6u), + _ => f64::to_str_digits(v, 6u) + ".0", + } +} + +/// A structure for implementing serialization to JSON. +pub struct Encoder<'a> { + writer: &'a mut (fmt::Writer+'a), +} + +impl<'a> Encoder<'a> { + /// Creates a new JSON encoder whose output will be written to the writer + /// specified. + pub fn new(writer: &'a mut fmt::Writer) -> Encoder<'a> { + Encoder { writer: writer } + } +} + +impl<'a> ::Encoder for Encoder<'a> { + fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") } + + fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) } + + fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) } + + fn emit_bool(&mut self, v: bool) -> EncodeResult { + if v { + write!(self.writer, "true") + } else { + write!(self.writer, "false") + } + } + + fn emit_f64(&mut self, v: f64) -> EncodeResult { + write!(self.writer, "{}", fmt_number_or_null(v)) + } + fn emit_f32(&mut self, v: f32) -> EncodeResult { + self.emit_f64(v as f64) + } + + fn emit_char(&mut self, v: char) -> EncodeResult { + escape_char(self.writer, v) + } + fn emit_str(&mut self, v: &str) -> EncodeResult { + escape_str(self.writer, v) + } + + fn emit_enum(&mut self, _name: &str, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + f(self) + } + + fn emit_enum_variant(&mut self, + name: &str, + _id: uint, + cnt: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + // enums are encoded as strings or objects + // Bunny => "Bunny" + // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]} + if cnt == 0 { + escape_str(self.writer, name) + } else { + try!(write!(self.writer, "{{\"variant\":")); + try!(escape_str(self.writer, name)); + try!(write!(self.writer, ",\"fields\":[")); + try!(f(self)); + write!(self.writer, "]}}") + } + } + + fn emit_enum_variant_arg(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + if idx != 0 { + try!(write!(self.writer, ",")); + } + f(self) + } + + fn emit_enum_struct_variant(&mut self, + name: &str, + id: uint, + cnt: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + self.emit_enum_variant(name, id, cnt, f) + } + + fn emit_enum_struct_variant_field(&mut self, + _: &str, + idx: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + self.emit_enum_variant_arg(idx, f) + } + + fn emit_struct(&mut self, _: &str, _: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + try!(write!(self.writer, "{{")); + try!(f(self)); + write!(self.writer, "}}") + } + + fn emit_struct_field(&mut self, name: &str, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + if idx != 0 { try!(write!(self.writer, ",")); } + try!(escape_str(self.writer, name)); + try!(write!(self.writer, ":")); + f(self) + } + + fn emit_tuple(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + self.emit_seq(len, f) + } + fn emit_tuple_arg(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + self.emit_seq_elt(idx, f) + } + + fn emit_tuple_struct(&mut self, _name: &str, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + self.emit_seq(len, f) + } + fn emit_tuple_struct_arg(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + self.emit_seq_elt(idx, f) + } + + fn emit_option(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + f(self) + } + fn emit_option_none(&mut self) -> EncodeResult { self.emit_nil() } + fn emit_option_some(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + f(self) + } + + fn emit_seq(&mut self, _len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + try!(write!(self.writer, "[")); + try!(f(self)); + write!(self.writer, "]") + } + + fn emit_seq_elt(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + if idx != 0 { + try!(write!(self.writer, ",")); + } + f(self) + } + + fn emit_map(&mut self, _len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + try!(write!(self.writer, "{{")); + try!(f(self)); + write!(self.writer, "}}") + } + + fn emit_map_elt_key(&mut self, idx: uint, mut f: F) -> EncodeResult where + F: FnMut(&mut Encoder<'a>) -> EncodeResult, + { + if idx != 0 { try!(write!(self.writer, ",")) } + // ref #12967, make sure to wrap a key in double quotes, + // in the event that its of a type that omits them (eg numbers) + let mut buf = Vec::new(); + // FIXME(14302) remove the transmute and unsafe block. + unsafe { + let mut check_encoder = Encoder::new(&mut buf); + try!(f(transmute(&mut check_encoder))); + } + let out = str::from_utf8(buf[]).unwrap(); + let needs_wrapping = out.char_at(0) != '"' && out.char_at_reverse(out.len()) != '"'; + if needs_wrapping { try!(write!(self.writer, "\"")); } + try!(f(self)); + if needs_wrapping { try!(write!(self.writer, "\"")); } + Ok(()) + } + + fn emit_map_elt_val(&mut self, _idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut Encoder<'a>) -> EncodeResult, + { + try!(write!(self.writer, ":")); + f(self) + } +} + +/// Another encoder for JSON, but prints out human-readable JSON instead of +/// compact data +pub struct PrettyEncoder<'a> { + writer: &'a mut (fmt::Writer+'a), + curr_indent: uint, + indent: uint, +} + +impl<'a> PrettyEncoder<'a> { + /// Creates a new encoder whose output will be written to the specified writer + pub fn new(writer: &'a mut fmt::Writer) -> PrettyEncoder<'a> { + PrettyEncoder { writer: writer, curr_indent: 0, indent: 2, } + } + + /// Set the number of spaces to indent for each level. + /// This is safe to set during encoding. + pub fn set_indent(&mut self, indent: uint) { + // self.indent very well could be 0 so we need to use checked division. + let level = self.curr_indent.checked_div(self.indent).unwrap_or(0); + self.indent = indent; + self.curr_indent = level * self.indent; + } +} + +impl<'a> ::Encoder for PrettyEncoder<'a> { + fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") } + + fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) } + + fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) } + + fn emit_bool(&mut self, v: bool) -> EncodeResult { + if v { + write!(self.writer, "true") + } else { + write!(self.writer, "false") + } + } + + fn emit_f64(&mut self, v: f64) -> EncodeResult { + write!(self.writer, "{}", fmt_number_or_null(v)) + } + fn emit_f32(&mut self, v: f32) -> EncodeResult { + self.emit_f64(v as f64) + } + + fn emit_char(&mut self, v: char) -> EncodeResult { + escape_char(self.writer, v) + } + fn emit_str(&mut self, v: &str) -> EncodeResult { + escape_str(self.writer, v) + } + + fn emit_enum(&mut self, _name: &str, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + f(self) + } + + fn emit_enum_variant(&mut self, + name: &str, + _id: uint, + cnt: uint, + f: F) + -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + if cnt == 0 { + escape_str(self.writer, name) + } else { + try!(write!(self.writer, "{{\n")); + self.curr_indent += self.indent; + try!(spaces(self.writer, self.curr_indent)); + try!(write!(self.writer, "\"variant\": ")); + try!(escape_str(self.writer, name)); + try!(write!(self.writer, ",\n")); + try!(spaces(self.writer, self.curr_indent)); + try!(write!(self.writer, "\"fields\": [\n")); + self.curr_indent += self.indent; + try!(f(self)); + self.curr_indent -= self.indent; + try!(write!(self.writer, "\n")); + try!(spaces(self.writer, self.curr_indent)); + self.curr_indent -= self.indent; + try!(write!(self.writer, "]\n")); + try!(spaces(self.writer, self.curr_indent)); + write!(self.writer, "}}") + } + } + + fn emit_enum_variant_arg(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + if idx != 0 { + try!(write!(self.writer, ",\n")); + } + try!(spaces(self.writer, self.curr_indent)); + f(self) + } + + fn emit_enum_struct_variant(&mut self, + name: &str, + id: uint, + cnt: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + self.emit_enum_variant(name, id, cnt, f) + } + + fn emit_enum_struct_variant_field(&mut self, + _: &str, + idx: uint, + f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + self.emit_enum_variant_arg(idx, f) + } + + + fn emit_struct(&mut self, _: &str, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + if len == 0 { + write!(self.writer, "{{}}") + } else { + try!(write!(self.writer, "{{")); + self.curr_indent += self.indent; + try!(f(self)); + self.curr_indent -= self.indent; + try!(write!(self.writer, "\n")); + try!(spaces(self.writer, self.curr_indent)); + write!(self.writer, "}}") + } + } + + fn emit_struct_field(&mut self, name: &str, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + if idx == 0 { + try!(write!(self.writer, "\n")); + } else { + try!(write!(self.writer, ",\n")); + } + try!(spaces(self.writer, self.curr_indent)); + try!(escape_str(self.writer, name)); + try!(write!(self.writer, ": ")); + f(self) + } + + fn emit_tuple(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + self.emit_seq(len, f) + } + fn emit_tuple_arg(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + self.emit_seq_elt(idx, f) + } + + fn emit_tuple_struct(&mut self, _: &str, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + self.emit_seq(len, f) + } + fn emit_tuple_struct_arg(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + self.emit_seq_elt(idx, f) + } + + fn emit_option(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + f(self) + } + fn emit_option_none(&mut self) -> EncodeResult { self.emit_nil() } + fn emit_option_some(&mut self, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + f(self) + } + + fn emit_seq(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + if len == 0 { + write!(self.writer, "[]") + } else { + try!(write!(self.writer, "[")); + self.curr_indent += self.indent; + try!(f(self)); + self.curr_indent -= self.indent; + try!(write!(self.writer, "\n")); + try!(spaces(self.writer, self.curr_indent)); + write!(self.writer, "]") + } + } + + fn emit_seq_elt(&mut self, idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + if idx == 0 { + try!(write!(self.writer, "\n")); + } else { + try!(write!(self.writer, ",\n")); + } + try!(spaces(self.writer, self.curr_indent)); + f(self) + } + + fn emit_map(&mut self, len: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + if len == 0 { + write!(self.writer, "{{}}") + } else { + try!(write!(self.writer, "{{")); + self.curr_indent += self.indent; + try!(f(self)); + self.curr_indent -= self.indent; + try!(write!(self.writer, "\n")); + try!(spaces(self.writer, self.curr_indent)); + write!(self.writer, "}}") + } + } + + fn emit_map_elt_key(&mut self, idx: uint, mut f: F) -> EncodeResult where + F: FnMut(&mut PrettyEncoder<'a>) -> EncodeResult, + { + if idx == 0 { + try!(write!(self.writer, "\n")); + } else { + try!(write!(self.writer, ",\n")); + } + try!(spaces(self.writer, self.curr_indent)); + // ref #12967, make sure to wrap a key in double quotes, + // in the event that its of a type that omits them (eg numbers) + let mut buf = Vec::new(); + // FIXME(14302) remove the transmute and unsafe block. + unsafe { + let mut check_encoder = PrettyEncoder::new(&mut buf); + try!(f(transmute(&mut check_encoder))); + } + let out = str::from_utf8(buf[]).unwrap(); + let needs_wrapping = out.char_at(0) != '"' && out.char_at_reverse(out.len()) != '"'; + if needs_wrapping { try!(write!(self.writer, "\"")); } + try!(f(self)); + if needs_wrapping { try!(write!(self.writer, "\"")); } + Ok(()) + } + + fn emit_map_elt_val(&mut self, _idx: uint, f: F) -> EncodeResult where + F: FnOnce(&mut PrettyEncoder<'a>) -> EncodeResult, + { + try!(write!(self.writer, ": ")); + f(self) + } +} + +impl, S> Encodable for Json { + fn encode(&self, e: &mut E) -> Result<(), S> { + match *self { + Json::I64(v) => v.encode(e), + Json::U64(v) => v.encode(e), + Json::F64(v) => v.encode(e), + Json::String(ref v) => v.encode(e), + Json::Boolean(v) => v.encode(e), + Json::Array(ref v) => v.encode(e), + Json::Object(ref v) => v.encode(e), + Json::Null => e.emit_nil(), + } + } +} + +/// Create an `AsJson` wrapper which can be used to print a value as JSON +/// on-the-fly via `write!` +pub fn as_json(t: &T) -> AsJson { + AsJson { inner: t } +} + +/// Create an `AsPrettyJson` wrapper which can be used to print a value as JSON +/// on-the-fly via `write!` +pub fn as_pretty_json(t: &T) -> AsPrettyJson { + AsPrettyJson { inner: t, indent: None } +} + +impl Json { + /// Borrow this json object as a pretty object to generate a pretty + /// representation for it via `Show`. + pub fn pretty(&self) -> PrettyJson { + PrettyJson { inner: self } + } + + /// If the Json value is an Object, returns the value associated with the provided key. + /// Otherwise, returns None. + pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{ + match self { + &Json::Object(ref map) => map.get(key), + _ => None + } + } + + /// Attempts to get a nested Json Object for each key in `keys`. + /// If any key is found not to exist, find_path will return None. + /// Otherwise, it will return the Json value associated with the final key. + pub fn find_path<'a>(&'a self, keys: &[&str]) -> Option<&'a Json>{ + let mut target = self; + for key in keys.iter() { + match target.find(*key) { + Some(t) => { target = t; }, + None => return None + } + } + Some(target) + } + + /// If the Json value is an Object, performs a depth-first search until + /// a value associated with the provided key is found. If no value is found + /// or the Json value is not an Object, returns None. + pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> { + match self { + &Json::Object(ref map) => { + match map.get(key) { + Some(json_value) => Some(json_value), + None => { + for (_, v) in map.iter() { + match v.search(key) { + x if x.is_some() => return x, + _ => () + } + } + None + } + } + }, + _ => None + } + } + + /// Returns true if the Json value is an Object. Returns false otherwise. + pub fn is_object<'a>(&'a self) -> bool { + self.as_object().is_some() + } + + /// If the Json value is an Object, returns the associated BTreeMap. + /// Returns None otherwise. + pub fn as_object<'a>(&'a self) -> Option<&'a Object> { + match self { + &Json::Object(ref map) => Some(map), + _ => None + } + } + + /// Returns true if the Json value is an Array. Returns false otherwise. + pub fn is_array<'a>(&'a self) -> bool { + self.as_array().is_some() + } + + /// If the Json value is an Array, returns the associated vector. + /// Returns None otherwise. + pub fn as_array<'a>(&'a self) -> Option<&'a Array> { + match self { + &Json::Array(ref array) => Some(&*array), + _ => None + } + } + + /// Returns true if the Json value is a String. Returns false otherwise. + pub fn is_string<'a>(&'a self) -> bool { + self.as_string().is_some() + } + + /// If the Json value is a String, returns the associated str. + /// Returns None otherwise. + pub fn as_string<'a>(&'a self) -> Option<&'a str> { + match *self { + Json::String(ref s) => Some(s[]), + _ => None + } + } + + /// Returns true if the Json value is a Number. Returns false otherwise. + pub fn is_number(&self) -> bool { + match *self { + Json::I64(_) | Json::U64(_) | Json::F64(_) => true, + _ => false, + } + } + + /// Returns true if the Json value is a i64. Returns false otherwise. + pub fn is_i64(&self) -> bool { + match *self { + Json::I64(_) => true, + _ => false, + } + } + + /// Returns true if the Json value is a u64. Returns false otherwise. + pub fn is_u64(&self) -> bool { + match *self { + Json::U64(_) => true, + _ => false, + } + } + + /// Returns true if the Json value is a f64. Returns false otherwise. + pub fn is_f64(&self) -> bool { + match *self { + Json::F64(_) => true, + _ => false, + } + } + + /// If the Json value is a number, return or cast it to a i64. + /// Returns None otherwise. + pub fn as_i64(&self) -> Option { + match *self { + Json::I64(n) => Some(n), + Json::U64(n) => num::cast(n), + _ => None + } + } + + /// If the Json value is a number, return or cast it to a u64. + /// Returns None otherwise. + pub fn as_u64(&self) -> Option { + match *self { + Json::I64(n) => num::cast(n), + Json::U64(n) => Some(n), + _ => None + } + } + + /// If the Json value is a number, return or cast it to a f64. + /// Returns None otherwise. + pub fn as_f64(&self) -> Option { + match *self { + Json::I64(n) => num::cast(n), + Json::U64(n) => num::cast(n), + Json::F64(n) => Some(n), + _ => None + } + } + + /// Returns true if the Json value is a Boolean. Returns false otherwise. + pub fn is_boolean(&self) -> bool { + self.as_boolean().is_some() + } + + /// If the Json value is a Boolean, returns the associated bool. + /// Returns None otherwise. + pub fn as_boolean(&self) -> Option { + match self { + &Json::Boolean(b) => Some(b), + _ => None + } + } + + /// Returns true if the Json value is a Null. Returns false otherwise. + pub fn is_null(&self) -> bool { + self.as_null().is_some() + } + + /// If the Json value is a Null, returns (). + /// Returns None otherwise. + pub fn as_null(&self) -> Option<()> { + match self { + &Json::Null => Some(()), + _ => None + } + } +} + +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] +impl<'a> ops::Index<&'a str, Json> for Json { + fn index(&self, idx: & &str) -> &Json { + self.find(*idx).unwrap() + } +} + +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +impl<'a> ops::Index<&'a str> for Json { + type Output = Json; + + fn index(&self, idx: & &str) -> &Json { + self.find(*idx).unwrap() + } +} + +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] +impl ops::Index for Json { + fn index<'a>(&'a self, idx: &uint) -> &'a Json { + match self { + &Json::Array(ref v) => v.index(idx), + _ => panic!("can only index Json with uint if it is an array") + } + } +} + +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +impl ops::Index for Json { + type Output = Json; + + fn index<'a>(&'a self, idx: &uint) -> &'a Json { + match self { + &Json::Array(ref v) => v.index(idx), + _ => panic!("can only index Json with uint if it is an array") + } + } +} + +/// The output of the streaming parser. +#[derive(PartialEq, Clone, Show)] +pub enum JsonEvent { + ObjectStart, + ObjectEnd, + ArrayStart, + ArrayEnd, + BooleanValue(bool), + I64Value(i64), + U64Value(u64), + F64Value(f64), + StringValue(string::String), + NullValue, + Error(ParserError), +} + +#[derive(PartialEq, Show)] +enum ParserState { + // Parse a value in an array, true means first element. + ParseArray(bool), + // Parse ',' or ']' after an element in an array. + ParseArrayComma, + // Parse a key:value in an object, true means first element. + ParseObject(bool), + // Parse ',' or ']' after an element in an object. + ParseObjectComma, + // Initial state. + ParseStart, + // Expecting the stream to end. + ParseBeforeFinish, + // Parsing can't continue. + ParseFinished, +} + +/// A Stack represents the current position of the parser in the logical +/// structure of the JSON stream. +/// For example foo.bar[3].x +pub struct Stack { + stack: Vec, + str_buffer: Vec, +} + +/// StackElements compose a Stack. +/// For example, Key("foo"), Key("bar"), Index(3) and Key("x") are the +/// StackElements compositing the stack that represents foo.bar[3].x +#[derive(PartialEq, Clone, Show)] +pub enum StackElement<'l> { + Index(u32), + Key(&'l str), +} + +// Internally, Key elements are stored as indices in a buffer to avoid +// allocating a string for every member of an object. +#[derive(PartialEq, Clone, Show)] +enum InternalStackElement { + InternalIndex(u32), + InternalKey(u16, u16), // start, size +} + +impl Stack { + pub fn new() -> Stack { + Stack { stack: Vec::new(), str_buffer: Vec::new() } + } + + /// Returns The number of elements in the Stack. + pub fn len(&self) -> uint { self.stack.len() } + + /// Returns true if the stack is empty. + pub fn is_empty(&self) -> bool { self.stack.is_empty() } + + /// Provides access to the StackElement at a given index. + /// lower indices are at the bottom of the stack while higher indices are + /// at the top. + pub fn get<'l>(&'l self, idx: uint) -> StackElement<'l> { + match self.stack[idx] { + InternalIndex(i) => Index(i), + InternalKey(start, size) => { + Key(str::from_utf8( + self.str_buffer[start as uint .. start as uint + size as uint]).unwrap()) + } + } + } + + /// Compares this stack with an array of StackElements. + pub fn is_equal_to(&self, rhs: &[StackElement]) -> bool { + if self.stack.len() != rhs.len() { return false; } + for i in range(0, rhs.len()) { + if self.get(i) != rhs[i] { return false; } + } + return true; + } + + /// Returns true if the bottom-most elements of this stack are the same as + /// the ones passed as parameter. + pub fn starts_with(&self, rhs: &[StackElement]) -> bool { + if self.stack.len() < rhs.len() { return false; } + for i in range(0, rhs.len()) { + if self.get(i) != rhs[i] { return false; } + } + return true; + } + + /// Returns true if the top-most elements of this stack are the same as + /// the ones passed as parameter. + pub fn ends_with(&self, rhs: &[StackElement]) -> bool { + if self.stack.len() < rhs.len() { return false; } + let offset = self.stack.len() - rhs.len(); + for i in range(0, rhs.len()) { + if self.get(i + offset) != rhs[i] { return false; } + } + return true; + } + + /// Returns the top-most element (if any). + pub fn top<'l>(&'l self) -> Option> { + return match self.stack.last() { + None => None, + Some(&InternalIndex(i)) => Some(Index(i)), + Some(&InternalKey(start, size)) => { + Some(Key(str::from_utf8( + self.str_buffer[start as uint .. (start+size) as uint] + ).unwrap())) + } + } + } + + // Used by Parser to insert Key elements at the top of the stack. + fn push_key(&mut self, key: string::String) { + self.stack.push(InternalKey(self.str_buffer.len() as u16, key.len() as u16)); + for c in key.as_bytes().iter() { + self.str_buffer.push(*c); + } + } + + // Used by Parser to insert Index elements at the top of the stack. + fn push_index(&mut self, index: u32) { + self.stack.push(InternalIndex(index)); + } + + // Used by Parser to remove the top-most element of the stack. + fn pop(&mut self) { + assert!(!self.is_empty()); + match *self.stack.last().unwrap() { + InternalKey(_, sz) => { + let new_size = self.str_buffer.len() - sz as uint; + self.str_buffer.truncate(new_size); + } + InternalIndex(_) => {} + } + self.stack.pop(); + } + + // Used by Parser to test whether the top-most element is an index. + fn last_is_index(&self) -> bool { + if self.is_empty() { return false; } + return match *self.stack.last().unwrap() { + InternalIndex(_) => true, + _ => false, + } + } + + // Used by Parser to increment the index of the top-most element. + fn bump_index(&mut self) { + let len = self.stack.len(); + let idx = match *self.stack.last().unwrap() { + InternalIndex(i) => { i + 1 } + _ => { panic!(); } + }; + self.stack[len - 1] = InternalIndex(idx); + } +} + +/// A streaming JSON parser implemented as an iterator of JsonEvent, consuming +/// an iterator of char. +pub struct Parser { + rdr: T, + ch: Option, + line: uint, + col: uint, + // We maintain a stack representing where we are in the logical structure + // of the JSON stream. + stack: Stack, + // A state machine is kept to make it possible to interrupt and resume parsing. + state: ParserState, +} + +impl> Iterator for Parser { + type Item = JsonEvent; + + fn next(&mut self) -> Option { + if self.state == ParseFinished { + return None; + } + + if self.state == ParseBeforeFinish { + self.parse_whitespace(); + // Make sure there is no trailing characters. + if self.eof() { + self.state = ParseFinished; + return None; + } else { + return Some(self.error_event(TrailingCharacters)); + } + } + + return Some(self.parse()); + } +} + +impl> Parser { + /// Creates the JSON parser. + pub fn new(rdr: T) -> Parser { + let mut p = Parser { + rdr: rdr, + ch: Some('\x00'), + line: 1, + col: 0, + stack: Stack::new(), + state: ParseStart, + }; + p.bump(); + return p; + } + + /// Provides access to the current position in the logical structure of the + /// JSON stream. + pub fn stack<'l>(&'l self) -> &'l Stack { + return &self.stack; + } + + fn eof(&self) -> bool { self.ch.is_none() } + fn ch_or_null(&self) -> char { self.ch.unwrap_or('\x00') } + fn bump(&mut self) { + self.ch = self.rdr.next(); + + if self.ch_is('\n') { + self.line += 1u; + self.col = 1u; + } else { + self.col += 1u; + } + } + + fn next_char(&mut self) -> Option { + self.bump(); + self.ch + } + fn ch_is(&self, c: char) -> bool { + self.ch == Some(c) + } + + fn error(&self, reason: ErrorCode) -> Result { + Err(SyntaxError(reason, self.line, self.col)) + } + + fn parse_whitespace(&mut self) { + while self.ch_is(' ') || + self.ch_is('\n') || + self.ch_is('\t') || + self.ch_is('\r') { self.bump(); } + } + + fn parse_number(&mut self) -> JsonEvent { + let mut neg = false; + + if self.ch_is('-') { + self.bump(); + neg = true; + } + + let res = match self.parse_u64() { + Ok(res) => res, + Err(e) => { return Error(e); } + }; + + if self.ch_is('.') || self.ch_is('e') || self.ch_is('E') { + let mut res = res as f64; + + if self.ch_is('.') { + res = match self.parse_decimal(res) { + Ok(res) => res, + Err(e) => { return Error(e); } + }; + } + + if self.ch_is('e') || self.ch_is('E') { + res = match self.parse_exponent(res) { + Ok(res) => res, + Err(e) => { return Error(e); } + }; + } + + if neg { + res *= -1.0; + } + + F64Value(res) + } else { + if neg { + let res = -(res as i64); + + // Make sure we didn't underflow. + if res > 0 { + Error(SyntaxError(InvalidNumber, self.line, self.col)) + } else { + I64Value(res) + } + } else { + U64Value(res) + } + } + } + + fn parse_u64(&mut self) -> Result { + let mut accum = 0; + let last_accum = 0; // necessary to detect overflow. + + match self.ch_or_null() { + '0' => { + self.bump(); + + // A leading '0' must be the only digit before the decimal point. + match self.ch_or_null() { + '0' ... '9' => return self.error(InvalidNumber), + _ => () + } + }, + '1' ... '9' => { + while !self.eof() { + match self.ch_or_null() { + c @ '0' ... '9' => { + accum *= 10; + accum += (c as u64) - ('0' as u64); + + // Detect overflow by comparing to the last value. + if accum <= last_accum { return self.error(InvalidNumber); } + + self.bump(); + } + _ => break, + } + } + } + _ => return self.error(InvalidNumber), + } + + Ok(accum) + } + + fn parse_decimal(&mut self, mut res: f64) -> Result { + self.bump(); + + // Make sure a digit follows the decimal place. + match self.ch_or_null() { + '0' ... '9' => (), + _ => return self.error(InvalidNumber) + } + + let mut dec = 1.0; + while !self.eof() { + match self.ch_or_null() { + c @ '0' ... '9' => { + dec /= 10.0; + res += (((c as int) - ('0' as int)) as f64) * dec; + self.bump(); + } + _ => break, + } + } + + Ok(res) + } + + fn parse_exponent(&mut self, mut res: f64) -> Result { + self.bump(); + + let mut exp = 0u; + let mut neg_exp = false; + + if self.ch_is('+') { + self.bump(); + } else if self.ch_is('-') { + self.bump(); + neg_exp = true; + } + + // Make sure a digit follows the exponent place. + match self.ch_or_null() { + '0' ... '9' => (), + _ => return self.error(InvalidNumber) + } + while !self.eof() { + match self.ch_or_null() { + c @ '0' ... '9' => { + exp *= 10; + exp += (c as uint) - ('0' as uint); + + self.bump(); + } + _ => break + } + } + + let exp = 10_f64.powi(exp as i32); + if neg_exp { + res /= exp; + } else { + res *= exp; + } + + Ok(res) + } + + fn decode_hex_escape(&mut self) -> Result { + let mut i = 0u; + let mut n = 0u16; + while i < 4 && !self.eof() { + self.bump(); + n = match self.ch_or_null() { + c @ '0' ... '9' => n * 16 + ((c as u16) - ('0' as u16)), + 'a' | 'A' => n * 16 + 10, + 'b' | 'B' => n * 16 + 11, + 'c' | 'C' => n * 16 + 12, + 'd' | 'D' => n * 16 + 13, + 'e' | 'E' => n * 16 + 14, + 'f' | 'F' => n * 16 + 15, + _ => return self.error(InvalidEscape) + }; + + i += 1u; + } + + // Error out if we didn't parse 4 digits. + if i != 4 { + return self.error(InvalidEscape); + } + + Ok(n) + } + + fn parse_str(&mut self) -> Result { + let mut escape = false; + let mut res = string::String::new(); + + loop { + self.bump(); + if self.eof() { + return self.error(EOFWhileParsingString); + } + + if escape { + match self.ch_or_null() { + '"' => res.push('"'), + '\\' => res.push('\\'), + '/' => res.push('/'), + 'b' => res.push('\x08'), + 'f' => res.push('\x0c'), + 'n' => res.push('\n'), + 'r' => res.push('\r'), + 't' => res.push('\t'), + 'u' => match try!(self.decode_hex_escape()) { + 0xDC00 ... 0xDFFF => { + return self.error(LoneLeadingSurrogateInHexEscape) + } + + // Non-BMP characters are encoded as a sequence of + // two hex escapes, representing UTF-16 surrogates. + n1 @ 0xD800 ... 0xDBFF => { + match (self.next_char(), self.next_char()) { + (Some('\\'), Some('u')) => (), + _ => return self.error(UnexpectedEndOfHexEscape), + } + + let buf = [n1, try!(self.decode_hex_escape())]; + match unicode_str::utf16_items(&buf).next() { + Some(Utf16Item::ScalarValue(c)) => res.push(c), + _ => return self.error(LoneLeadingSurrogateInHexEscape), + } + } + + n => match char::from_u32(n as u32) { + Some(c) => res.push(c), + None => return self.error(InvalidUnicodeCodePoint), + }, + }, + _ => return self.error(InvalidEscape), + } + escape = false; + } else if self.ch_is('\\') { + escape = true; + } else { + match self.ch { + Some('"') => { + self.bump(); + return Ok(res); + }, + Some(c) => res.push(c), + None => unreachable!() + } + } + } + } + + // Invoked at each iteration, consumes the stream until it has enough + // information to return a JsonEvent. + // Manages an internal state so that parsing can be interrupted and resumed. + // Also keeps track of the position in the logical structure of the json + // stream int the form of a stack that can be queried by the user using the + // stack() method. + fn parse(&mut self) -> JsonEvent { + loop { + // The only paths where the loop can spin a new iteration + // are in the cases ParseArrayComma and ParseObjectComma if ',' + // is parsed. In these cases the state is set to (respectively) + // ParseArray(false) and ParseObject(false), which always return, + // so there is no risk of getting stuck in an infinite loop. + // All other paths return before the end of the loop's iteration. + self.parse_whitespace(); + + match self.state { + ParseStart => { + return self.parse_start(); + } + ParseArray(first) => { + return self.parse_array(first); + } + ParseArrayComma => { + match self.parse_array_comma_or_end() { + Some(evt) => { return evt; } + None => {} + } + } + ParseObject(first) => { + return self.parse_object(first); + } + ParseObjectComma => { + self.stack.pop(); + if self.ch_is(',') { + self.state = ParseObject(false); + self.bump(); + } else { + return self.parse_object_end(); + } + } + _ => { + return self.error_event(InvalidSyntax); + } + } + } + } + + fn parse_start(&mut self) -> JsonEvent { + let val = self.parse_value(); + self.state = match val { + Error(_) => ParseFinished, + ArrayStart => ParseArray(true), + ObjectStart => ParseObject(true), + _ => ParseBeforeFinish, + }; + return val; + } + + fn parse_array(&mut self, first: bool) -> JsonEvent { + if self.ch_is(']') { + if !first { + self.error_event(InvalidSyntax) + } else { + self.state = if self.stack.is_empty() { + ParseBeforeFinish + } else if self.stack.last_is_index() { + ParseArrayComma + } else { + ParseObjectComma + }; + self.bump(); + ArrayEnd + } + } else { + if first { + self.stack.push_index(0); + } + let val = self.parse_value(); + self.state = match val { + Error(_) => ParseFinished, + ArrayStart => ParseArray(true), + ObjectStart => ParseObject(true), + _ => ParseArrayComma, + }; + val + } + } + + fn parse_array_comma_or_end(&mut self) -> Option { + if self.ch_is(',') { + self.stack.bump_index(); + self.state = ParseArray(false); + self.bump(); + None + } else if self.ch_is(']') { + self.stack.pop(); + self.state = if self.stack.is_empty() { + ParseBeforeFinish + } else if self.stack.last_is_index() { + ParseArrayComma + } else { + ParseObjectComma + }; + self.bump(); + Some(ArrayEnd) + } else if self.eof() { + Some(self.error_event(EOFWhileParsingArray)) + } else { + Some(self.error_event(InvalidSyntax)) + } + } + + fn parse_object(&mut self, first: bool) -> JsonEvent { + if self.ch_is('}') { + if !first { + if self.stack.is_empty() { + return self.error_event(TrailingComma); + } else { + self.stack.pop(); + } + } + self.state = if self.stack.is_empty() { + ParseBeforeFinish + } else if self.stack.last_is_index() { + ParseArrayComma + } else { + ParseObjectComma + }; + self.bump(); + return ObjectEnd; + } + if self.eof() { + return self.error_event(EOFWhileParsingObject); + } + if !self.ch_is('"') { + return self.error_event(KeyMustBeAString); + } + let s = match self.parse_str() { + Ok(s) => s, + Err(e) => { + self.state = ParseFinished; + return Error(e); + } + }; + self.parse_whitespace(); + if self.eof() { + return self.error_event(EOFWhileParsingObject); + } else if self.ch_or_null() != ':' { + return self.error_event(ExpectedColon); + } + self.stack.push_key(s); + self.bump(); + self.parse_whitespace(); + + let val = self.parse_value(); + + self.state = match val { + Error(_) => ParseFinished, + ArrayStart => ParseArray(true), + ObjectStart => ParseObject(true), + _ => ParseObjectComma, + }; + return val; + } + + fn parse_object_end(&mut self) -> JsonEvent { + if self.ch_is('}') { + self.state = if self.stack.is_empty() { + ParseBeforeFinish + } else if self.stack.last_is_index() { + ParseArrayComma + } else { + ParseObjectComma + }; + self.bump(); + ObjectEnd + } else if self.eof() { + self.error_event(EOFWhileParsingObject) + } else { + self.error_event(InvalidSyntax) + } + } + + fn parse_value(&mut self) -> JsonEvent { + if self.eof() { return self.error_event(EOFWhileParsingValue); } + match self.ch_or_null() { + 'n' => { self.parse_ident("ull", NullValue) } + 't' => { self.parse_ident("rue", BooleanValue(true)) } + 'f' => { self.parse_ident("alse", BooleanValue(false)) } + '0' ... '9' | '-' => self.parse_number(), + '"' => match self.parse_str() { + Ok(s) => StringValue(s), + Err(e) => Error(e), + }, + '[' => { + self.bump(); + ArrayStart + } + '{' => { + self.bump(); + ObjectStart + } + _ => { self.error_event(InvalidSyntax) } + } + } + + fn parse_ident(&mut self, ident: &str, value: JsonEvent) -> JsonEvent { + if ident.chars().all(|c| Some(c) == self.next_char()) { + self.bump(); + value + } else { + Error(SyntaxError(InvalidSyntax, self.line, self.col)) + } + } + + fn error_event(&mut self, reason: ErrorCode) -> JsonEvent { + self.state = ParseFinished; + Error(SyntaxError(reason, self.line, self.col)) + } +} + +/// A Builder consumes a json::Parser to create a generic Json structure. +pub struct Builder { + parser: Parser, + token: Option, +} + +impl> Builder { + /// Create a JSON Builder. + pub fn new(src: T) -> Builder { + Builder { parser: Parser::new(src), token: None, } + } + + // Decode a Json value from a Parser. + pub fn build(&mut self) -> Result { + self.bump(); + let result = self.build_value(); + self.bump(); + match self.token { + None => {} + Some(Error(e)) => { return Err(e); } + ref tok => { panic!("unexpected token {}", tok.clone()); } + } + result + } + + fn bump(&mut self) { + self.token = self.parser.next(); + } + + fn build_value(&mut self) -> Result { + return match self.token { + Some(NullValue) => Ok(Json::Null), + Some(I64Value(n)) => Ok(Json::I64(n)), + Some(U64Value(n)) => Ok(Json::U64(n)), + Some(F64Value(n)) => Ok(Json::F64(n)), + Some(BooleanValue(b)) => Ok(Json::Boolean(b)), + Some(StringValue(ref mut s)) => { + let mut temp = string::String::new(); + swap(s, &mut temp); + Ok(Json::String(temp)) + } + Some(Error(e)) => Err(e), + Some(ArrayStart) => self.build_array(), + Some(ObjectStart) => self.build_object(), + Some(ObjectEnd) => self.parser.error(InvalidSyntax), + Some(ArrayEnd) => self.parser.error(InvalidSyntax), + None => self.parser.error(EOFWhileParsingValue), + } + } + + fn build_array(&mut self) -> Result { + self.bump(); + let mut values = Vec::new(); + + loop { + if self.token == Some(ArrayEnd) { + return Ok(Json::Array(values.into_iter().collect())); + } + match self.build_value() { + Ok(v) => values.push(v), + Err(e) => { return Err(e) } + } + self.bump(); + } + } + + fn build_object(&mut self) -> Result { + self.bump(); + + let mut values = BTreeMap::new(); + + loop { + match self.token { + Some(ObjectEnd) => { return Ok(Json::Object(values)); } + Some(Error(e)) => { return Err(e); } + None => { break; } + _ => {} + } + let key = match self.parser.stack().top() { + Some(Key(k)) => { k.to_string() } + _ => { panic!("invalid state"); } + }; + match self.build_value() { + Ok(value) => { values.insert(key, value); } + Err(e) => { return Err(e); } + } + self.bump(); + } + return self.parser.error(EOFWhileParsingObject); + } +} + +/// Decodes a json value from an `&mut io::Reader` +pub fn from_reader(rdr: &mut io::Reader) -> Result { + let contents = match rdr.read_to_end() { + Ok(c) => c, + Err(e) => return Err(io_error_to_error(e)) + }; + let s = match str::from_utf8(contents.as_slice()).ok() { + Some(s) => s, + _ => return Err(SyntaxError(NotUtf8, 0, 0)) + }; + let mut builder = Builder::new(s.chars()); + builder.build() +} + +/// Decodes a json value from a string +pub fn from_str(s: &str) -> Result { + let mut builder = Builder::new(s.chars()); + builder.build() +} + +/// A structure to decode JSON to values in rust. +pub struct Decoder { + stack: Vec, +} + +impl Decoder { + /// Creates a new decoder instance for decoding the specified JSON value. + pub fn new(json: Json) -> Decoder { + Decoder { stack: vec![json] } + } +} + +impl Decoder { + fn pop(&mut self) -> Json { + self.stack.pop().unwrap() + } +} + +macro_rules! expect { + ($e:expr, Null) => ({ + match $e { + Json::Null => Ok(()), + other => Err(ExpectedError("Null".to_string(), + format!("{}", other))) + } + }); + ($e:expr, $t:ident) => ({ + match $e { + Json::$t(v) => Ok(v), + other => { + Err(ExpectedError(stringify!($t).to_string(), + format!("{}", other))) + } + } + }) +} + +macro_rules! read_primitive { + ($name:ident, $ty:ty) => { + fn $name(&mut self) -> DecodeResult<$ty> { + match self.pop() { + Json::I64(f) => match num::cast(f) { + Some(f) => Ok(f), + None => Err(ExpectedError("Number".to_string(), format!("{}", f))), + }, + Json::U64(f) => match num::cast(f) { + Some(f) => Ok(f), + None => Err(ExpectedError("Number".to_string(), format!("{}", f))), + }, + Json::F64(f) => Err(ExpectedError("Integer".to_string(), format!("{}", f))), + // re: #12967.. a type w/ numeric keys (ie HashMap etc) + // is going to have a string here, as per JSON spec. + Json::String(s) => match s.parse() { + Some(f) => Ok(f), + None => Err(ExpectedError("Number".to_string(), s)), + }, + value => Err(ExpectedError("Number".to_string(), format!("{}", value))), + } + } + } +} + +impl ::Decoder for Decoder { + fn read_nil(&mut self) -> DecodeResult<()> { + expect!(self.pop(), Null) + } + + read_primitive! { read_uint, uint } + read_primitive! { read_u8, u8 } + read_primitive! { read_u16, u16 } + read_primitive! { read_u32, u32 } + read_primitive! { read_u64, u64 } + read_primitive! { read_int, int } + read_primitive! { read_i8, i8 } + read_primitive! { read_i16, i16 } + read_primitive! { read_i32, i32 } + read_primitive! { read_i64, i64 } + + fn read_f32(&mut self) -> DecodeResult { self.read_f64().map(|x| x as f32) } + + fn read_f64(&mut self) -> DecodeResult { + match self.pop() { + Json::I64(f) => Ok(f as f64), + Json::U64(f) => Ok(f as f64), + Json::F64(f) => Ok(f), + Json::String(s) => { + // re: #12967.. a type w/ numeric keys (ie HashMap etc) + // is going to have a string here, as per JSON spec. + match s.parse() { + Some(f) => Ok(f), + None => Err(ExpectedError("Number".to_string(), s)), + } + }, + Json::Null => Ok(f64::NAN), + value => Err(ExpectedError("Number".to_string(), format!("{}", value))) + } + } + + fn read_bool(&mut self) -> DecodeResult { + expect!(self.pop(), Boolean) + } + + fn read_char(&mut self) -> DecodeResult { + let s = try!(self.read_str()); + { + let mut it = s.chars(); + match (it.next(), it.next()) { + // exactly one character + (Some(c), None) => return Ok(c), + _ => () + } + } + Err(ExpectedError("single character string".to_string(), format!("{}", s))) + } + + fn read_str(&mut self) -> DecodeResult { + expect!(self.pop(), String) + } + + fn read_enum(&mut self, _name: &str, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + f(self) + } + + fn read_enum_variant(&mut self, names: &[&str], + mut f: F) -> DecodeResult + where F: FnMut(&mut Decoder, uint) -> DecodeResult, + { + let name = match self.pop() { + Json::String(s) => s, + Json::Object(mut o) => { + let n = match o.remove(&"variant".to_string()) { + Some(Json::String(s)) => s, + Some(val) => { + return Err(ExpectedError("String".to_string(), format!("{}", val))) + } + None => { + return Err(MissingFieldError("variant".to_string())) + } + }; + match o.remove(&"fields".to_string()) { + Some(Json::Array(l)) => { + for field in l.into_iter().rev() { + self.stack.push(field); + } + }, + Some(val) => { + return Err(ExpectedError("Array".to_string(), format!("{}", val))) + } + None => { + return Err(MissingFieldError("fields".to_string())) + } + } + n + } + json => { + return Err(ExpectedError("String or Object".to_string(), format!("{}", json))) + } + }; + let idx = match names.iter().position(|n| *n == name[]) { + Some(idx) => idx, + None => return Err(UnknownVariantError(name)) + }; + f(self, idx) + } + + fn read_enum_variant_arg(&mut self, _idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + f(self) + } + + fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> DecodeResult where + F: FnMut(&mut Decoder, uint) -> DecodeResult, + { + self.read_enum_variant(names, f) + } + + + fn read_enum_struct_variant_field(&mut self, + _name: &str, + idx: uint, + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + self.read_enum_variant_arg(idx, f) + } + + fn read_struct(&mut self, _name: &str, _len: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + let value = try!(f(self)); + self.pop(); + Ok(value) + } + + fn read_struct_field(&mut self, + name: &str, + _idx: uint, + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + let mut obj = try!(expect!(self.pop(), Object)); + + let value = match obj.remove(&name.to_string()) { + None => { + // Add a Null and try to parse it as an Option<_> + // to get None as a default value. + self.stack.push(Json::Null); + match f(self) { + Ok(x) => x, + Err(_) => return Err(MissingFieldError(name.to_string())), + } + }, + Some(json) => { + self.stack.push(json); + try!(f(self)) + } + }; + self.stack.push(Json::Object(obj)); + Ok(value) + } + + fn read_tuple(&mut self, tuple_len: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + self.read_seq(move |d, len| { + if len == tuple_len { + f(d) + } else { + Err(ExpectedError(format!("Tuple{}", tuple_len), format!("Tuple{}", len))) + } + }) + } + + fn read_tuple_arg(&mut self, idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + self.read_seq_elt(idx, f) + } + + fn read_tuple_struct(&mut self, + _name: &str, + len: uint, + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + self.read_tuple(len, f) + } + + fn read_tuple_struct_arg(&mut self, + idx: uint, + f: F) + -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + self.read_tuple_arg(idx, f) + } + + fn read_option(&mut self, mut f: F) -> DecodeResult where + F: FnMut(&mut Decoder, bool) -> DecodeResult, + { + match self.pop() { + Json::Null => f(self, false), + value => { self.stack.push(value); f(self, true) } + } + } + + fn read_seq(&mut self, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder, uint) -> DecodeResult, + { + let array = try!(expect!(self.pop(), Array)); + let len = array.len(); + for v in array.into_iter().rev() { + self.stack.push(v); + } + f(self, len) + } + + fn read_seq_elt(&mut self, _idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + f(self) + } + + fn read_map(&mut self, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder, uint) -> DecodeResult, + { + let obj = try!(expect!(self.pop(), Object)); + let len = obj.len(); + for (key, value) in obj.into_iter() { + self.stack.push(value); + self.stack.push(Json::String(key)); + } + f(self, len) + } + + fn read_map_elt_key(&mut self, _idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + f(self) + } + + fn read_map_elt_val(&mut self, _idx: uint, f: F) -> DecodeResult where + F: FnOnce(&mut Decoder) -> DecodeResult, + { + f(self) + } + + fn error(&mut self, err: &str) -> DecoderError { + ApplicationError(err.to_string()) + } +} + +/// A trait for converting values to JSON +pub trait ToJson for Sized? { + /// Converts the value of `self` to an instance of JSON + fn to_json(&self) -> Json; +} + +macro_rules! to_json_impl_i64 { + ($($t:ty), +) => ( + $(impl ToJson for $t { + fn to_json(&self) -> Json { Json::I64(*self as i64) } + })+ + ) +} + +to_json_impl_i64! { int, i8, i16, i32, i64 } + +macro_rules! to_json_impl_u64 { + ($($t:ty), +) => ( + $(impl ToJson for $t { + fn to_json(&self) -> Json { Json::U64(*self as u64) } + })+ + ) +} + +to_json_impl_u64! { uint, u8, u16, u32, u64 } + +impl ToJson for Json { + fn to_json(&self) -> Json { self.clone() } +} + +impl ToJson for f32 { + fn to_json(&self) -> Json { (*self as f64).to_json() } +} + +impl ToJson for f64 { + fn to_json(&self) -> Json { + match self.classify() { + Fp::Nan | Fp::Infinite => Json::Null, + _ => Json::F64(*self) + } + } +} + +impl ToJson for () { + fn to_json(&self) -> Json { Json::Null } +} + +impl ToJson for bool { + fn to_json(&self) -> Json { Json::Boolean(*self) } +} + +impl ToJson for str { + fn to_json(&self) -> Json { Json::String(self.to_string()) } +} + +impl ToJson for string::String { + fn to_json(&self) -> Json { Json::String((*self).clone()) } +} + +macro_rules! tuple_impl { + // use variables to indicate the arity of the tuple + ($($tyvar:ident),* ) => { + // the trailing commas are for the 1 tuple + impl< + $( $tyvar : ToJson ),* + > ToJson for ( $( $tyvar ),* , ) { + + #[inline] + #[allow(non_snake_case)] + fn to_json(&self) -> Json { + match *self { + ($(ref $tyvar),*,) => Json::Array(vec![$($tyvar.to_json()),*]) + } + } + } + } +} + +tuple_impl!{A} +tuple_impl!{A, B} +tuple_impl!{A, B, C} +tuple_impl!{A, B, C, D} +tuple_impl!{A, B, C, D, E} +tuple_impl!{A, B, C, D, E, F} +tuple_impl!{A, B, C, D, E, F, G} +tuple_impl!{A, B, C, D, E, F, G, H} +tuple_impl!{A, B, C, D, E, F, G, H, I} +tuple_impl!{A, B, C, D, E, F, G, H, I, J} +tuple_impl!{A, B, C, D, E, F, G, H, I, J, K} +tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L} + +impl ToJson for [A] { + fn to_json(&self) -> Json { Json::Array(self.iter().map(|elt| elt.to_json()).collect()) } +} + +impl ToJson for Vec { + fn to_json(&self) -> Json { Json::Array(self.iter().map(|elt| elt.to_json()).collect()) } +} + +impl ToJson for BTreeMap { + fn to_json(&self) -> Json { + let mut d = BTreeMap::new(); + for (key, value) in self.iter() { + d.insert((*key).clone(), value.to_json()); + } + Json::Object(d) + } +} + +impl ToJson for HashMap { + fn to_json(&self) -> Json { + let mut d = BTreeMap::new(); + for (key, value) in self.iter() { + d.insert((*key).clone(), value.to_json()); + } + Json::Object(d) + } +} + +impl ToJson for Option { + fn to_json(&self) -> Json { + match *self { + None => Json::Null, + Some(ref value) => value.to_json() + } + } +} + +struct FormatShim<'a, 'b: 'a> { + inner: &'a mut fmt::Formatter<'b>, +} + +impl<'a, 'b> fmt::Writer for FormatShim<'a, 'b> { + fn write_str(&mut self, s: &str) -> fmt::Result { + self.inner.write_str(s) + } +} + +impl fmt::Show for Json { + /// Encodes a json value into a string + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut shim = FormatShim { inner: f }; + let mut encoder = Encoder::new(&mut shim); + self.encode(&mut encoder) + } +} + +impl<'a> fmt::Show for PrettyJson<'a> { + /// Encodes a json value into a string + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut shim = FormatShim { inner: f }; + let mut encoder = PrettyEncoder::new(&mut shim); + self.inner.encode(&mut encoder) + } +} + +impl<'a, T> fmt::Show for AsJson<'a, T> + where T: for<'b> Encodable, fmt::Error> +{ + /// Encodes a json value into a string + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut shim = FormatShim { inner: f }; + let mut encoder = Encoder::new(&mut shim); + self.inner.encode(&mut encoder) + } +} + +impl<'a, T> AsPrettyJson<'a, T> { + /// Set the indentation level for the emitted JSON + pub fn indent(mut self, indent: uint) -> AsPrettyJson<'a, T> { + self.indent = Some(indent); + self + } +} + +impl<'a, T> fmt::Show for AsPrettyJson<'a, T> + where T: for<'b> Encodable, fmt::Error> +{ + /// Encodes a json value into a string + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut shim = FormatShim { inner: f }; + let mut encoder = PrettyEncoder::new(&mut shim); + match self.indent { + Some(n) => encoder.set_indent(n), + None => {} + } + self.inner.encode(&mut encoder) + } +} + +impl FromStr for Json { + fn from_str(s: &str) -> Option { + from_str(s).ok() + } +} + +#[cfg(test)] +mod tests { + extern crate test; + use self::Animal::*; + use self::DecodeEnum::*; + use self::test::Bencher; + use {Encodable, Decodable}; + use super::Json::*; + use super::ErrorCode::*; + use super::ParserError::*; + use super::DecoderError::*; + use super::JsonEvent::*; + use super::StackElement::*; + use super::{Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser, + StackElement, Stack, Decoder}; + use std::{i64, u64, f32, f64}; + use std::collections::BTreeMap; + use std::num::Float; + use std::string; + + #[derive(RustcDecodable, Eq, PartialEq, Show)] + struct OptionData { + opt: Option, + } + + #[test] + fn test_decode_option_none() { + let s ="{}"; + let obj: OptionData = super::decode(s).unwrap(); + assert_eq!(obj, OptionData { opt: None }); + } + + #[test] + fn test_decode_option_some() { + let s = "{ \"opt\": 10 }"; + let obj: OptionData = super::decode(s).unwrap(); + assert_eq!(obj, OptionData { opt: Some(10u) }); + } + + #[test] + fn test_decode_option_malformed() { + check_err::("{ \"opt\": [] }", + ExpectedError("Number".to_string(), "[]".to_string())); + check_err::("{ \"opt\": false }", + ExpectedError("Number".to_string(), "false".to_string())); + } + + #[derive(PartialEq, RustcEncodable, RustcDecodable, Show)] + enum Animal { + Dog, + Frog(string::String, int) + } + + #[derive(PartialEq, RustcEncodable, RustcDecodable, Show)] + struct Inner { + a: (), + b: uint, + c: Vec, + } + + #[derive(PartialEq, RustcEncodable, RustcDecodable, Show)] + struct Outer { + inner: Vec, + } + + fn mk_object(items: &[(string::String, Json)]) -> Json { + let mut d = BTreeMap::new(); + + for item in items.iter() { + match *item { + (ref key, ref value) => { d.insert((*key).clone(), (*value).clone()); }, + } + }; + + Object(d) + } + + #[test] + fn test_from_str_trait() { + let s = "null"; + assert!(s.parse::().unwrap() == s.parse().unwrap()); + } + + #[test] + fn test_write_null() { + assert_eq!(Null.to_string(), "null"); + assert_eq!(Null.pretty().to_string(), "null"); + } + + #[test] + fn test_write_i64() { + assert_eq!(U64(0).to_string(), "0"); + assert_eq!(U64(0).pretty().to_string(), "0"); + + assert_eq!(U64(1234).to_string(), "1234"); + assert_eq!(U64(1234).pretty().to_string(), "1234"); + + assert_eq!(I64(-5678).to_string(), "-5678"); + assert_eq!(I64(-5678).pretty().to_string(), "-5678"); + + assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000"); + assert_eq!(U64(7650007200025252000).pretty().to_string(), "7650007200025252000"); + } + + #[test] + fn test_write_f64() { + assert_eq!(F64(3.0).to_string(), "3.0"); + assert_eq!(F64(3.0).pretty().to_string(), "3.0"); + + assert_eq!(F64(3.1).to_string(), "3.1"); + assert_eq!(F64(3.1).pretty().to_string(), "3.1"); + + assert_eq!(F64(-1.5).to_string(), "-1.5"); + assert_eq!(F64(-1.5).pretty().to_string(), "-1.5"); + + assert_eq!(F64(0.5).to_string(), "0.5"); + assert_eq!(F64(0.5).pretty().to_string(), "0.5"); + + assert_eq!(F64(f64::NAN).to_string(), "null"); + assert_eq!(F64(f64::NAN).pretty().to_string(), "null"); + + assert_eq!(F64(f64::INFINITY).to_string(), "null"); + assert_eq!(F64(f64::INFINITY).pretty().to_string(), "null"); + + assert_eq!(F64(f64::NEG_INFINITY).to_string(), "null"); + assert_eq!(F64(f64::NEG_INFINITY).pretty().to_string(), "null"); + } + + #[test] + fn test_write_str() { + assert_eq!(String("".to_string()).to_string(), "\"\""); + assert_eq!(String("".to_string()).pretty().to_string(), "\"\""); + + assert_eq!(String("homura".to_string()).to_string(), "\"homura\""); + assert_eq!(String("madoka".to_string()).pretty().to_string(), "\"madoka\""); + } + + #[test] + fn test_write_bool() { + assert_eq!(Boolean(true).to_string(), "true"); + assert_eq!(Boolean(true).pretty().to_string(), "true"); + + assert_eq!(Boolean(false).to_string(), "false"); + assert_eq!(Boolean(false).pretty().to_string(), "false"); + } + + #[test] + fn test_write_array() { + assert_eq!(Array(vec![]).to_string(), "[]"); + assert_eq!(Array(vec![]).pretty().to_string(), "[]"); + + assert_eq!(Array(vec![Boolean(true)]).to_string(), "[true]"); + assert_eq!( + Array(vec![Boolean(true)]).pretty().to_string(), + "\ + [\n \ + true\n\ + ]" + ); + + let long_test_array = Array(vec![ + Boolean(false), + Null, + Array(vec![String("foo\nbar".to_string()), F64(3.5)])]); + + assert_eq!(long_test_array.to_string(), + "[false,null,[\"foo\\nbar\",3.5]]"); + assert_eq!( + long_test_array.pretty().to_string(), + "\ + [\n \ + false,\n \ + null,\n \ + [\n \ + \"foo\\nbar\",\n \ + 3.5\n \ + ]\n\ + ]" + ); + } + + #[test] + fn test_write_object() { + assert_eq!(mk_object(&[]).to_string(), "{}"); + assert_eq!(mk_object(&[]).pretty().to_string(), "{}"); + + assert_eq!( + mk_object(&[ + ("a".to_string(), Boolean(true)) + ]).to_string(), + "{\"a\":true}" + ); + assert_eq!( + mk_object(&[("a".to_string(), Boolean(true))]).pretty().to_string(), + "\ + {\n \ + \"a\": true\n\ + }" + ); + + let complex_obj = mk_object(&[ + ("b".to_string(), Array(vec![ + mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), + mk_object(&[("d".to_string(), String("".to_string()))]) + ])) + ]); + + assert_eq!( + complex_obj.to_string(), + "{\ + \"b\":[\ + {\"c\":\"\\f\\r\"},\ + {\"d\":\"\"}\ + ]\ + }" + ); + assert_eq!( + complex_obj.pretty().to_string(), + "\ + {\n \ + \"b\": [\n \ + {\n \ + \"c\": \"\\f\\r\"\n \ + },\n \ + {\n \ + \"d\": \"\"\n \ + }\n \ + ]\n\ + }" + ); + + let a = mk_object(&[ + ("a".to_string(), Boolean(true)), + ("b".to_string(), Array(vec![ + mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), + mk_object(&[("d".to_string(), String("".to_string()))]) + ])) + ]); + + // We can't compare the strings directly because the object fields be + // printed in a different order. + assert_eq!(a.clone(), a.to_string().parse().unwrap()); + assert_eq!(a.clone(), a.pretty().to_string().parse().unwrap()); + } + + #[test] + fn test_write_enum() { + let animal = Dog; + assert_eq!( + format!("{}", super::as_json(&animal)), + "\"Dog\"" + ); + assert_eq!( + format!("{}", super::as_pretty_json(&animal)), + "\"Dog\"" + ); + + let animal = Frog("Henry".to_string(), 349); + assert_eq!( + format!("{}", super::as_json(&animal)), + "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}" + ); + assert_eq!( + format!("{}", super::as_pretty_json(&animal)), + "{\n \ + \"variant\": \"Frog\",\n \ + \"fields\": [\n \ + \"Henry\",\n \ + 349\n \ + ]\n\ + }" + ); + } + + macro_rules! check_encoder_for_simple { + ($value:expr, $expected:expr) => ({ + let s = format!("{}", super::as_json(&$value)); + assert_eq!(s, $expected); + + let s = format!("{}", super::as_pretty_json(&$value)); + assert_eq!(s, $expected); + }) + } + + #[test] + fn test_write_some() { + check_encoder_for_simple!(Some("jodhpurs".to_string()), "\"jodhpurs\""); + } + + #[test] + fn test_write_none() { + check_encoder_for_simple!(None::, "null"); + } + + #[test] + fn test_write_char() { + check_encoder_for_simple!('a', "\"a\""); + check_encoder_for_simple!('\t', "\"\\t\""); + check_encoder_for_simple!('\u{0000}', "\"\\u0000\""); + check_encoder_for_simple!('\u{001b}', "\"\\u001b\""); + check_encoder_for_simple!('\u{007f}', "\"\\u007f\""); + check_encoder_for_simple!('\u{00a0}', "\"\u{00a0}\""); + check_encoder_for_simple!('\u{abcd}', "\"\u{abcd}\""); + check_encoder_for_simple!('\u{10ffff}', "\"\u{10ffff}\""); + } + + #[test] + fn test_trailing_characters() { + assert_eq!(from_str("nulla"), Err(SyntaxError(TrailingCharacters, 1, 5))); + assert_eq!(from_str("truea"), Err(SyntaxError(TrailingCharacters, 1, 5))); + assert_eq!(from_str("falsea"), Err(SyntaxError(TrailingCharacters, 1, 6))); + assert_eq!(from_str("1a"), Err(SyntaxError(TrailingCharacters, 1, 2))); + assert_eq!(from_str("[]a"), Err(SyntaxError(TrailingCharacters, 1, 3))); + assert_eq!(from_str("{}a"), Err(SyntaxError(TrailingCharacters, 1, 3))); + } + + #[test] + fn test_read_identifiers() { + assert_eq!(from_str("n"), Err(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(from_str("nul"), Err(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(from_str("t"), Err(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(from_str("truz"), Err(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(from_str("f"), Err(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(from_str("faz"), Err(SyntaxError(InvalidSyntax, 1, 3))); + + assert_eq!(from_str("null"), Ok(Null)); + assert_eq!(from_str("true"), Ok(Boolean(true))); + assert_eq!(from_str("false"), Ok(Boolean(false))); + assert_eq!(from_str(" null "), Ok(Null)); + assert_eq!(from_str(" true "), Ok(Boolean(true))); + assert_eq!(from_str(" false "), Ok(Boolean(false))); + } + + #[test] + fn test_decode_identifiers() { + let v: () = super::decode("null").unwrap(); + assert_eq!(v, ()); + + let v: bool = super::decode("true").unwrap(); + assert_eq!(v, true); + + let v: bool = super::decode("false").unwrap(); + assert_eq!(v, false); + } + + #[test] + fn test_read_number() { + assert_eq!(from_str("+"), Err(SyntaxError(InvalidSyntax, 1, 1))); + assert_eq!(from_str("."), Err(SyntaxError(InvalidSyntax, 1, 1))); + assert_eq!(from_str("NaN"), Err(SyntaxError(InvalidSyntax, 1, 1))); + assert_eq!(from_str("-"), Err(SyntaxError(InvalidNumber, 1, 2))); + assert_eq!(from_str("00"), Err(SyntaxError(InvalidNumber, 1, 2))); + assert_eq!(from_str("1."), Err(SyntaxError(InvalidNumber, 1, 3))); + assert_eq!(from_str("1e"), Err(SyntaxError(InvalidNumber, 1, 3))); + assert_eq!(from_str("1e+"), Err(SyntaxError(InvalidNumber, 1, 4))); + + assert_eq!(from_str("18446744073709551616"), Err(SyntaxError(InvalidNumber, 1, 20))); + assert_eq!(from_str("-9223372036854775809"), Err(SyntaxError(InvalidNumber, 1, 21))); + + assert_eq!(from_str("3"), Ok(U64(3))); + assert_eq!(from_str("3.1"), Ok(F64(3.1))); + assert_eq!(from_str("-1.2"), Ok(F64(-1.2))); + assert_eq!(from_str("0.4"), Ok(F64(0.4))); + assert_eq!(from_str("0.4e5"), Ok(F64(0.4e5))); + assert_eq!(from_str("0.4e+15"), Ok(F64(0.4e15))); + assert_eq!(from_str("0.4e-01"), Ok(F64(0.4e-01))); + assert_eq!(from_str(" 3 "), Ok(U64(3))); + + assert_eq!(from_str("-9223372036854775808"), Ok(I64(i64::MIN))); + assert_eq!(from_str("9223372036854775807"), Ok(U64(i64::MAX as u64))); + assert_eq!(from_str("18446744073709551615"), Ok(U64(u64::MAX))); + } + + #[test] + fn test_decode_numbers() { + let v: f64 = super::decode("3").unwrap(); + assert_eq!(v, 3.0); + + let v: f64 = super::decode("3.1").unwrap(); + assert_eq!(v, 3.1); + + let v: f64 = super::decode("-1.2").unwrap(); + assert_eq!(v, -1.2); + + let v: f64 = super::decode("0.4").unwrap(); + assert_eq!(v, 0.4); + + let v: f64 = super::decode("0.4e5").unwrap(); + assert_eq!(v, 0.4e5); + + let v: f64 = super::decode("0.4e15").unwrap(); + assert_eq!(v, 0.4e15); + + let v: f64 = super::decode("0.4e-01").unwrap(); + assert_eq!(v, 0.4e-01); + + let v: u64 = super::decode("0").unwrap(); + assert_eq!(v, 0); + + let v: u64 = super::decode("18446744073709551615").unwrap(); + assert_eq!(v, u64::MAX); + + let v: i64 = super::decode("-9223372036854775808").unwrap(); + assert_eq!(v, i64::MIN); + + let v: i64 = super::decode("9223372036854775807").unwrap(); + assert_eq!(v, i64::MAX); + + let res: DecodeResult = super::decode("765.25252"); + assert_eq!(res, Err(ExpectedError("Integer".to_string(), "765.25252".to_string()))); + } + + #[test] + fn test_read_str() { + assert_eq!(from_str("\""), Err(SyntaxError(EOFWhileParsingString, 1, 2))); + assert_eq!(from_str("\"lol"), Err(SyntaxError(EOFWhileParsingString, 1, 5))); + + assert_eq!(from_str("\"\""), Ok(String("".to_string()))); + assert_eq!(from_str("\"foo\""), Ok(String("foo".to_string()))); + assert_eq!(from_str("\"\\\"\""), Ok(String("\"".to_string()))); + assert_eq!(from_str("\"\\b\""), Ok(String("\x08".to_string()))); + assert_eq!(from_str("\"\\n\""), Ok(String("\n".to_string()))); + assert_eq!(from_str("\"\\r\""), Ok(String("\r".to_string()))); + assert_eq!(from_str("\"\\t\""), Ok(String("\t".to_string()))); + assert_eq!(from_str(" \"foo\" "), Ok(String("foo".to_string()))); + assert_eq!(from_str("\"\\u12ab\""), Ok(String("\u{12ab}".to_string()))); + assert_eq!(from_str("\"\\uAB12\""), Ok(String("\u{AB12}".to_string()))); + } + + #[test] + fn test_decode_str() { + let s = [("\"\"", ""), + ("\"foo\"", "foo"), + ("\"\\\"\"", "\""), + ("\"\\b\"", "\x08"), + ("\"\\n\"", "\n"), + ("\"\\r\"", "\r"), + ("\"\\t\"", "\t"), + ("\"\\u12ab\"", "\u{12ab}"), + ("\"\\uAB12\"", "\u{AB12}")]; + + for &(i, o) in s.iter() { + let v: string::String = super::decode(i).unwrap(); + assert_eq!(v, o); + } + } + + #[test] + fn test_read_array() { + assert_eq!(from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2))); + assert_eq!(from_str("[1"), Err(SyntaxError(EOFWhileParsingArray, 1, 3))); + assert_eq!(from_str("[1,"), Err(SyntaxError(EOFWhileParsingValue, 1, 4))); + assert_eq!(from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); + + assert_eq!(from_str("[]"), Ok(Array(vec![]))); + assert_eq!(from_str("[ ]"), Ok(Array(vec![]))); + assert_eq!(from_str("[true]"), Ok(Array(vec![Boolean(true)]))); + assert_eq!(from_str("[ false ]"), Ok(Array(vec![Boolean(false)]))); + assert_eq!(from_str("[null]"), Ok(Array(vec![Null]))); + assert_eq!(from_str("[3, 1]"), + Ok(Array(vec![U64(3), U64(1)]))); + assert_eq!(from_str("\n[3, 2]\n"), + Ok(Array(vec![U64(3), U64(2)]))); + assert_eq!(from_str("[2, [4, 1]]"), + Ok(Array(vec![U64(2), Array(vec![U64(4), U64(1)])]))); + } + + #[test] + fn test_decode_array() { + let v: Vec<()> = super::decode("[]").unwrap(); + assert_eq!(v, vec![]); + + let v: Vec<()> = super::decode("[null]").unwrap(); + assert_eq!(v, vec![()]); + + let v: Vec = super::decode("[true]").unwrap(); + assert_eq!(v, vec![true]); + + let v: Vec = super::decode("[3, 1]").unwrap(); + assert_eq!(v, vec![3, 1]); + + let v: Vec> = super::decode("[[3], [1, 2]]").unwrap(); + assert_eq!(v, vec![vec![3], vec![1, 2]]); + } + + #[test] + fn test_decode_tuple() { + let t: (uint, uint, uint) = super::decode("[1, 2, 3]").unwrap(); + assert_eq!(t, (1u, 2, 3)); + + let t: (uint, string::String) = super::decode("[1, \"two\"]").unwrap(); + assert_eq!(t, (1u, "two".to_string())); + } + + #[test] + fn test_decode_tuple_malformed_types() { + assert!(super::decode::<(uint, string::String)>("[1, 2]").is_err()); + } + + #[test] + fn test_decode_tuple_malformed_length() { + assert!(super::decode::<(uint, uint)>("[1, 2, 3]").is_err()); + } + + #[test] + fn test_read_object() { + assert_eq!(from_str("{"), Err(SyntaxError(EOFWhileParsingObject, 1, 2))); + assert_eq!(from_str("{ "), Err(SyntaxError(EOFWhileParsingObject, 1, 3))); + assert_eq!(from_str("{1"), Err(SyntaxError(KeyMustBeAString, 1, 2))); + assert_eq!(from_str("{ \"a\""), Err(SyntaxError(EOFWhileParsingObject, 1, 6))); + assert_eq!(from_str("{\"a\""), Err(SyntaxError(EOFWhileParsingObject, 1, 5))); + assert_eq!(from_str("{\"a\" "), Err(SyntaxError(EOFWhileParsingObject, 1, 6))); + + assert_eq!(from_str("{\"a\" 1"), Err(SyntaxError(ExpectedColon, 1, 6))); + assert_eq!(from_str("{\"a\":"), Err(SyntaxError(EOFWhileParsingValue, 1, 6))); + assert_eq!(from_str("{\"a\":1"), Err(SyntaxError(EOFWhileParsingObject, 1, 7))); + assert_eq!(from_str("{\"a\":1 1"), Err(SyntaxError(InvalidSyntax, 1, 8))); + assert_eq!(from_str("{\"a\":1,"), Err(SyntaxError(EOFWhileParsingObject, 1, 8))); + + assert_eq!(from_str("{}").unwrap(), mk_object(&[])); + assert_eq!(from_str("{\"a\": 3}").unwrap(), + mk_object(&[("a".to_string(), U64(3))])); + + assert_eq!(from_str( + "{ \"a\": null, \"b\" : true }").unwrap(), + mk_object(&[ + ("a".to_string(), Null), + ("b".to_string(), Boolean(true))])); + assert_eq!(from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(), + mk_object(&[ + ("a".to_string(), Null), + ("b".to_string(), Boolean(true))])); + assert_eq!(from_str( + "{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(), + mk_object(&[ + ("a".to_string(), F64(1.0)), + ("b".to_string(), Array(vec![Boolean(true)])) + ])); + assert_eq!(from_str( + "{\ + \"a\": 1.0, \ + \"b\": [\ + true,\ + \"foo\\nbar\", \ + { \"c\": {\"d\": null} } \ + ]\ + }").unwrap(), + mk_object(&[ + ("a".to_string(), F64(1.0)), + ("b".to_string(), Array(vec![ + Boolean(true), + String("foo\nbar".to_string()), + mk_object(&[ + ("c".to_string(), mk_object(&[("d".to_string(), Null)])) + ]) + ])) + ])); + } + + #[test] + fn test_decode_struct() { + let s = "{ + \"inner\": [ + { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] } + ] + }"; + + let v: Outer = super::decode(s).unwrap(); + assert_eq!( + v, + Outer { + inner: vec![ + Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] } + ] + } + ); + } + + #[derive(RustcDecodable)] + struct FloatStruct { + f: f64, + a: Vec + } + #[test] + fn test_decode_struct_with_nan() { + let s = "{\"f\":null,\"a\":[null,123]}"; + let obj: FloatStruct = super::decode(s).unwrap(); + assert!(obj.f.is_nan()); + assert!(obj.a[0].is_nan()); + assert_eq!(obj.a[1], 123f64); + } + + #[test] + fn test_decode_option() { + let value: Option = super::decode("null").unwrap(); + assert_eq!(value, None); + + let value: Option = super::decode("\"jodhpurs\"").unwrap(); + assert_eq!(value, Some("jodhpurs".to_string())); + } + + #[test] + fn test_decode_enum() { + let value: Animal = super::decode("\"Dog\"").unwrap(); + assert_eq!(value, Dog); + + let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"; + let value: Animal = super::decode(s).unwrap(); + assert_eq!(value, Frog("Henry".to_string(), 349)); + } + + #[test] + fn test_decode_map() { + let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\ + \"fields\":[\"Henry\", 349]}}"; + let mut map: BTreeMap = super::decode(s).unwrap(); + + assert_eq!(map.remove(&"a".to_string()), Some(Dog)); + assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349))); + } + + #[test] + fn test_multiline_errors() { + assert_eq!(from_str("{\n \"foo\":\n \"bar\""), + Err(SyntaxError(EOFWhileParsingObject, 3u, 8u))); + } + + #[derive(RustcDecodable)] + #[allow(dead_code)] + struct DecodeStruct { + x: f64, + y: bool, + z: string::String, + w: Vec + } + #[derive(RustcDecodable)] + enum DecodeEnum { + A(f64), + B(string::String) + } + fn check_err>(to_parse: &'static str, + expected: DecoderError) { + let res: DecodeResult = match from_str(to_parse) { + Err(e) => Err(ParseError(e)), + Ok(json) => Decodable::decode(&mut Decoder::new(json)) + }; + match res { + Ok(_) => panic!("`{}` parsed & decoded ok, expecting error `{}`", + to_parse, expected), + Err(ParseError(e)) => panic!("`{}` is not valid json: {}", + to_parse, e), + Err(e) => { + assert_eq!(e, expected); + } + } + } + #[test] + fn test_decode_errors_struct() { + check_err::("[]", ExpectedError("Object".to_string(), "[]".to_string())); + check_err::("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}", + ExpectedError("Number".to_string(), "true".to_string())); + check_err::("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}", + ExpectedError("Boolean".to_string(), "[]".to_string())); + check_err::("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}", + ExpectedError("String".to_string(), "{}".to_string())); + check_err::("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}", + ExpectedError("Array".to_string(), "null".to_string())); + check_err::("{\"x\": 1, \"y\": true, \"z\": \"\"}", + MissingFieldError("w".to_string())); + } + #[test] + fn test_decode_errors_enum() { + check_err::("{}", + MissingFieldError("variant".to_string())); + check_err::("{\"variant\": 1}", + ExpectedError("String".to_string(), "1".to_string())); + check_err::("{\"variant\": \"A\"}", + MissingFieldError("fields".to_string())); + check_err::("{\"variant\": \"A\", \"fields\": null}", + ExpectedError("Array".to_string(), "null".to_string())); + check_err::("{\"variant\": \"C\", \"fields\": []}", + UnknownVariantError("C".to_string())); + } + + #[test] + fn test_find(){ + let json_value = from_str("{\"dog\" : \"cat\"}").unwrap(); + let found_str = json_value.find("dog"); + assert!(found_str.unwrap().as_string().unwrap() == "cat"); + } + + #[test] + fn test_find_path(){ + let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); + let found_str = json_value.find_path(&["dog", "cat", "mouse"]); + assert!(found_str.unwrap().as_string().unwrap() == "cheese"); + } + + #[test] + fn test_search(){ + let json_value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); + let found_str = json_value.search("mouse").and_then(|j| j.as_string()); + assert!(found_str.unwrap() == "cheese"); + } + + #[test] + fn test_index(){ + let json_value = from_str("{\"animals\":[\"dog\",\"cat\",\"mouse\"]}").unwrap(); + let ref array = json_value["animals"]; + assert_eq!(array[0].as_string().unwrap(), "dog"); + assert_eq!(array[1].as_string().unwrap(), "cat"); + assert_eq!(array[2].as_string().unwrap(), "mouse"); + } + + #[test] + fn test_is_object(){ + let json_value = from_str("{}").unwrap(); + assert!(json_value.is_object()); + } + + #[test] + fn test_as_object(){ + let json_value = from_str("{}").unwrap(); + let json_object = json_value.as_object(); + assert!(json_object.is_some()); + } + + #[test] + fn test_is_array(){ + let json_value = from_str("[1, 2, 3]").unwrap(); + assert!(json_value.is_array()); + } + + #[test] + fn test_as_array(){ + let json_value = from_str("[1, 2, 3]").unwrap(); + let json_array = json_value.as_array(); + let expected_length = 3; + assert!(json_array.is_some() && json_array.unwrap().len() == expected_length); + } + + #[test] + fn test_is_string(){ + let json_value = from_str("\"dog\"").unwrap(); + assert!(json_value.is_string()); + } + + #[test] + fn test_as_string(){ + let json_value = from_str("\"dog\"").unwrap(); + let json_str = json_value.as_string(); + let expected_str = "dog"; + assert_eq!(json_str, Some(expected_str)); + } + + #[test] + fn test_is_number(){ + let json_value = from_str("12").unwrap(); + assert!(json_value.is_number()); + } + + #[test] + fn test_is_i64(){ + let json_value = from_str("-12").unwrap(); + assert!(json_value.is_i64()); + + let json_value = from_str("12").unwrap(); + assert!(!json_value.is_i64()); + + let json_value = from_str("12.0").unwrap(); + assert!(!json_value.is_i64()); + } + + #[test] + fn test_is_u64(){ + let json_value = from_str("12").unwrap(); + assert!(json_value.is_u64()); + + let json_value = from_str("-12").unwrap(); + assert!(!json_value.is_u64()); + + let json_value = from_str("12.0").unwrap(); + assert!(!json_value.is_u64()); + } + + #[test] + fn test_is_f64(){ + let json_value = from_str("12").unwrap(); + assert!(!json_value.is_f64()); + + let json_value = from_str("-12").unwrap(); + assert!(!json_value.is_f64()); + + let json_value = from_str("12.0").unwrap(); + assert!(json_value.is_f64()); + + let json_value = from_str("-12.0").unwrap(); + assert!(json_value.is_f64()); + } + + #[test] + fn test_as_i64(){ + let json_value = from_str("-12").unwrap(); + let json_num = json_value.as_i64(); + assert_eq!(json_num, Some(-12)); + } + + #[test] + fn test_as_u64(){ + let json_value = from_str("12").unwrap(); + let json_num = json_value.as_u64(); + assert_eq!(json_num, Some(12)); + } + + #[test] + fn test_as_f64(){ + let json_value = from_str("12.0").unwrap(); + let json_num = json_value.as_f64(); + assert_eq!(json_num, Some(12f64)); + } + + #[test] + fn test_is_boolean(){ + let json_value = from_str("false").unwrap(); + assert!(json_value.is_boolean()); + } + + #[test] + fn test_as_boolean(){ + let json_value = from_str("false").unwrap(); + let json_bool = json_value.as_boolean(); + let expected_bool = false; + assert!(json_bool.is_some() && json_bool.unwrap() == expected_bool); + } + + #[test] + fn test_is_null(){ + let json_value = from_str("null").unwrap(); + assert!(json_value.is_null()); + } + + #[test] + fn test_as_null(){ + let json_value = from_str("null").unwrap(); + let json_null = json_value.as_null(); + let expected_null = (); + assert!(json_null.is_some() && json_null.unwrap() == expected_null); + } + + #[test] + fn test_encode_hashmap_with_numeric_key() { + use std::str::from_utf8; + use std::io::Writer; + use std::collections::HashMap; + let mut hm: HashMap = HashMap::new(); + hm.insert(1, true); + let mut mem_buf = Vec::new(); + write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap(); + let json_str = from_utf8(mem_buf[]).unwrap(); + match from_str(json_str) { + Err(_) => panic!("Unable to parse json_str: {}", json_str), + _ => {} // it parsed and we are good to go + } + } + + #[test] + fn test_prettyencode_hashmap_with_numeric_key() { + use std::str::from_utf8; + use std::io::Writer; + use std::collections::HashMap; + let mut hm: HashMap = HashMap::new(); + hm.insert(1, true); + let mut mem_buf = Vec::new(); + write!(&mut mem_buf, "{}", super::as_pretty_json(&hm)).unwrap(); + let json_str = from_utf8(mem_buf[]).unwrap(); + match from_str(json_str) { + Err(_) => panic!("Unable to parse json_str: {}", json_str), + _ => {} // it parsed and we are good to go + } + } + + #[test] + fn test_prettyencoder_indent_level_param() { + use std::str::from_utf8; + use std::collections::BTreeMap; + + let mut tree = BTreeMap::new(); + + tree.insert("hello".to_string(), String("guten tag".to_string())); + tree.insert("goodbye".to_string(), String("sayonara".to_string())); + + let json = Array( + // The following layout below should look a lot like + // the pretty-printed JSON (indent * x) + vec! + ( // 0x + String("greetings".to_string()), // 1x + Object(tree), // 1x + 2x + 2x + 1x + ) // 0x + // End JSON array (7 lines) + ); + + // Helper function for counting indents + fn indents(source: &str) -> uint { + let trimmed = source.trim_left_matches(' '); + source.len() - trimmed.len() + } + + // Test up to 4 spaces of indents (more?) + for i in range(0, 4u) { + let mut writer = Vec::new(); + write!(&mut writer, "{}", + super::as_pretty_json(&json).indent(i)).unwrap(); + + let printed = from_utf8(writer[]).unwrap(); + + // Check for indents at each line + let lines: Vec<&str> = printed.lines().collect(); + assert_eq!(lines.len(), 7); // JSON should be 7 lines + + assert_eq!(indents(lines[0]), 0 * i); // [ + assert_eq!(indents(lines[1]), 1 * i); // "greetings", + assert_eq!(indents(lines[2]), 1 * i); // { + assert_eq!(indents(lines[3]), 2 * i); // "hello": "guten tag", + assert_eq!(indents(lines[4]), 2 * i); // "goodbye": "sayonara" + assert_eq!(indents(lines[5]), 1 * i); // }, + assert_eq!(indents(lines[6]), 0 * i); // ] + + // Finally, test that the pretty-printed JSON is valid + from_str(printed).ok().expect("Pretty-printed JSON is invalid!"); + } + } + + #[test] + fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() { + use std::collections::HashMap; + use Decodable; + let json_str = "{\"1\":true}"; + let json_obj = match from_str(json_str) { + Err(_) => panic!("Unable to parse json_str: {}", json_str), + Ok(o) => o + }; + let mut decoder = Decoder::new(json_obj); + let _hm: HashMap = Decodable::decode(&mut decoder).unwrap(); + } + + #[test] + fn test_hashmap_with_numeric_key_will_error_with_string_keys() { + use std::collections::HashMap; + use Decodable; + let json_str = "{\"a\":true}"; + let json_obj = match from_str(json_str) { + Err(_) => panic!("Unable to parse json_str: {}", json_str), + Ok(o) => o + }; + let mut decoder = Decoder::new(json_obj); + let result: Result, DecoderError> = Decodable::decode(&mut decoder); + assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string()))); + } + + fn assert_stream_equal(src: &str, + expected: Vec<(JsonEvent, Vec)>) { + let mut parser = Parser::new(src.chars()); + let mut i = 0; + loop { + let evt = match parser.next() { + Some(e) => e, + None => { break; } + }; + let (ref expected_evt, ref expected_stack) = expected[i]; + if !parser.stack().is_equal_to(expected_stack.as_slice()) { + panic!("Parser stack is not equal to {}", expected_stack); + } + assert_eq!(&evt, expected_evt); + i+=1; + } + } + #[test] + #[cfg_attr(target_word_size = "32", ignore)] // FIXME(#14064) + fn test_streaming_parser() { + assert_stream_equal( + r#"{ "foo":"bar", "array" : [0, 1, 2, 3, 4, 5], "idents":[null,true,false]}"#, + vec![ + (ObjectStart, vec![]), + (StringValue("bar".to_string()), vec![Key("foo")]), + (ArrayStart, vec![Key("array")]), + (U64Value(0), vec![Key("array"), Index(0)]), + (U64Value(1), vec![Key("array"), Index(1)]), + (U64Value(2), vec![Key("array"), Index(2)]), + (U64Value(3), vec![Key("array"), Index(3)]), + (U64Value(4), vec![Key("array"), Index(4)]), + (U64Value(5), vec![Key("array"), Index(5)]), + (ArrayEnd, vec![Key("array")]), + (ArrayStart, vec![Key("idents")]), + (NullValue, vec![Key("idents"), Index(0)]), + (BooleanValue(true), vec![Key("idents"), Index(1)]), + (BooleanValue(false), vec![Key("idents"), Index(2)]), + (ArrayEnd, vec![Key("idents")]), + (ObjectEnd, vec![]), + ] + ); + } + fn last_event(src: &str) -> JsonEvent { + let mut parser = Parser::new(src.chars()); + let mut evt = NullValue; + loop { + evt = match parser.next() { + Some(e) => e, + None => return evt, + } + } + } + + #[test] + #[cfg_attr(target_word_size = "32", ignore)] // FIXME(#14064) + fn test_read_object_streaming() { + assert_eq!(last_event("{ "), Error(SyntaxError(EOFWhileParsingObject, 1, 3))); + assert_eq!(last_event("{1"), Error(SyntaxError(KeyMustBeAString, 1, 2))); + assert_eq!(last_event("{ \"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); + assert_eq!(last_event("{\"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 5))); + assert_eq!(last_event("{\"a\" "), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); + + assert_eq!(last_event("{\"a\" 1"), Error(SyntaxError(ExpectedColon, 1, 6))); + assert_eq!(last_event("{\"a\":"), Error(SyntaxError(EOFWhileParsingValue, 1, 6))); + assert_eq!(last_event("{\"a\":1"), Error(SyntaxError(EOFWhileParsingObject, 1, 7))); + assert_eq!(last_event("{\"a\":1 1"), Error(SyntaxError(InvalidSyntax, 1, 8))); + assert_eq!(last_event("{\"a\":1,"), Error(SyntaxError(EOFWhileParsingObject, 1, 8))); + assert_eq!(last_event("{\"a\":1,}"), Error(SyntaxError(TrailingComma, 1, 8))); + + assert_stream_equal( + "{}", + vec![(ObjectStart, vec![]), (ObjectEnd, vec![])] + ); + assert_stream_equal( + "{\"a\": 3}", + vec![ + (ObjectStart, vec![]), + (U64Value(3), vec![Key("a")]), + (ObjectEnd, vec![]), + ] + ); + assert_stream_equal( + "{ \"a\": null, \"b\" : true }", + vec![ + (ObjectStart, vec![]), + (NullValue, vec![Key("a")]), + (BooleanValue(true), vec![Key("b")]), + (ObjectEnd, vec![]), + ] + ); + assert_stream_equal( + "{\"a\" : 1.0 ,\"b\": [ true ]}", + vec![ + (ObjectStart, vec![]), + (F64Value(1.0), vec![Key("a")]), + (ArrayStart, vec![Key("b")]), + (BooleanValue(true),vec![Key("b"), Index(0)]), + (ArrayEnd, vec![Key("b")]), + (ObjectEnd, vec![]), + ] + ); + assert_stream_equal( + r#"{ + "a": 1.0, + "b": [ + true, + "foo\nbar", + { "c": {"d": null} } + ] + }"#, + vec![ + (ObjectStart, vec![]), + (F64Value(1.0), vec![Key("a")]), + (ArrayStart, vec![Key("b")]), + (BooleanValue(true), vec![Key("b"), Index(0)]), + (StringValue("foo\nbar".to_string()), vec![Key("b"), Index(1)]), + (ObjectStart, vec![Key("b"), Index(2)]), + (ObjectStart, vec![Key("b"), Index(2), Key("c")]), + (NullValue, vec![Key("b"), Index(2), Key("c"), Key("d")]), + (ObjectEnd, vec![Key("b"), Index(2), Key("c")]), + (ObjectEnd, vec![Key("b"), Index(2)]), + (ArrayEnd, vec![Key("b")]), + (ObjectEnd, vec![]), + ] + ); + } + #[test] + #[cfg_attr(target_word_size = "32", ignore)] // FIXME(#14064) + fn test_read_array_streaming() { + assert_stream_equal( + "[]", + vec![ + (ArrayStart, vec![]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[ ]", + vec![ + (ArrayStart, vec![]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[true]", + vec![ + (ArrayStart, vec![]), + (BooleanValue(true), vec![Index(0)]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[ false ]", + vec![ + (ArrayStart, vec![]), + (BooleanValue(false), vec![Index(0)]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[null]", + vec![ + (ArrayStart, vec![]), + (NullValue, vec![Index(0)]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[3, 1]", + vec![ + (ArrayStart, vec![]), + (U64Value(3), vec![Index(0)]), + (U64Value(1), vec![Index(1)]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "\n[3, 2]\n", + vec![ + (ArrayStart, vec![]), + (U64Value(3), vec![Index(0)]), + (U64Value(2), vec![Index(1)]), + (ArrayEnd, vec![]), + ] + ); + assert_stream_equal( + "[2, [4, 1]]", + vec![ + (ArrayStart, vec![]), + (U64Value(2), vec![Index(0)]), + (ArrayStart, vec![Index(1)]), + (U64Value(4), vec![Index(1), Index(0)]), + (U64Value(1), vec![Index(1), Index(1)]), + (ArrayEnd, vec![Index(1)]), + (ArrayEnd, vec![]), + ] + ); + + assert_eq!(last_event("["), Error(SyntaxError(EOFWhileParsingValue, 1, 2))); + + assert_eq!(from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2))); + assert_eq!(from_str("[1"), Err(SyntaxError(EOFWhileParsingArray, 1, 3))); + assert_eq!(from_str("[1,"), Err(SyntaxError(EOFWhileParsingValue, 1, 4))); + assert_eq!(from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); + + } + #[test] + fn test_trailing_characters_streaming() { + assert_eq!(last_event("nulla"), Error(SyntaxError(TrailingCharacters, 1, 5))); + assert_eq!(last_event("truea"), Error(SyntaxError(TrailingCharacters, 1, 5))); + assert_eq!(last_event("falsea"), Error(SyntaxError(TrailingCharacters, 1, 6))); + assert_eq!(last_event("1a"), Error(SyntaxError(TrailingCharacters, 1, 2))); + assert_eq!(last_event("[]a"), Error(SyntaxError(TrailingCharacters, 1, 3))); + assert_eq!(last_event("{}a"), Error(SyntaxError(TrailingCharacters, 1, 3))); + } + #[test] + fn test_read_identifiers_streaming() { + assert_eq!(Parser::new("null".chars()).next(), Some(NullValue)); + assert_eq!(Parser::new("true".chars()).next(), Some(BooleanValue(true))); + assert_eq!(Parser::new("false".chars()).next(), Some(BooleanValue(false))); + + assert_eq!(last_event("n"), Error(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(last_event("nul"), Error(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(last_event("t"), Error(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(last_event("truz"), Error(SyntaxError(InvalidSyntax, 1, 4))); + assert_eq!(last_event("f"), Error(SyntaxError(InvalidSyntax, 1, 2))); + assert_eq!(last_event("faz"), Error(SyntaxError(InvalidSyntax, 1, 3))); + } + + #[test] + fn test_stack() { + let mut stack = Stack::new(); + + assert!(stack.is_empty()); + assert!(stack.len() == 0); + assert!(!stack.last_is_index()); + + stack.push_index(0); + stack.bump_index(); + + assert!(stack.len() == 1); + assert!(stack.is_equal_to(&[Index(1)])); + assert!(stack.starts_with(&[Index(1)])); + assert!(stack.ends_with(&[Index(1)])); + assert!(stack.last_is_index()); + assert!(stack.get(0) == Index(1)); + + stack.push_key("foo".to_string()); + + assert!(stack.len() == 2); + assert!(stack.is_equal_to(&[Index(1), Key("foo")])); + assert!(stack.starts_with(&[Index(1), Key("foo")])); + assert!(stack.starts_with(&[Index(1)])); + assert!(stack.ends_with(&[Index(1), Key("foo")])); + assert!(stack.ends_with(&[Key("foo")])); + assert!(!stack.last_is_index()); + assert!(stack.get(0) == Index(1)); + assert!(stack.get(1) == Key("foo")); + + stack.push_key("bar".to_string()); + + assert!(stack.len() == 3); + assert!(stack.is_equal_to(&[Index(1), Key("foo"), Key("bar")])); + assert!(stack.starts_with(&[Index(1)])); + assert!(stack.starts_with(&[Index(1), Key("foo")])); + assert!(stack.starts_with(&[Index(1), Key("foo"), Key("bar")])); + assert!(stack.ends_with(&[Key("bar")])); + assert!(stack.ends_with(&[Key("foo"), Key("bar")])); + assert!(stack.ends_with(&[Index(1), Key("foo"), Key("bar")])); + assert!(!stack.last_is_index()); + assert!(stack.get(0) == Index(1)); + assert!(stack.get(1) == Key("foo")); + assert!(stack.get(2) == Key("bar")); + + stack.pop(); + + assert!(stack.len() == 2); + assert!(stack.is_equal_to(&[Index(1), Key("foo")])); + assert!(stack.starts_with(&[Index(1), Key("foo")])); + assert!(stack.starts_with(&[Index(1)])); + assert!(stack.ends_with(&[Index(1), Key("foo")])); + assert!(stack.ends_with(&[Key("foo")])); + assert!(!stack.last_is_index()); + assert!(stack.get(0) == Index(1)); + assert!(stack.get(1) == Key("foo")); + } + + #[test] + fn test_to_json() { + use std::collections::{HashMap,BTreeMap}; + use super::ToJson; + + let array2 = Array(vec!(U64(1), U64(2))); + let array3 = Array(vec!(U64(1), U64(2), U64(3))); + let object = { + let mut tree_map = BTreeMap::new(); + tree_map.insert("a".to_string(), U64(1)); + tree_map.insert("b".to_string(), U64(2)); + Object(tree_map) + }; + + assert_eq!(array2.to_json(), array2); + assert_eq!(object.to_json(), object); + assert_eq!(3_i.to_json(), I64(3)); + assert_eq!(4_i8.to_json(), I64(4)); + assert_eq!(5_i16.to_json(), I64(5)); + assert_eq!(6_i32.to_json(), I64(6)); + assert_eq!(7_i64.to_json(), I64(7)); + assert_eq!(8_u.to_json(), U64(8)); + assert_eq!(9_u8.to_json(), U64(9)); + assert_eq!(10_u16.to_json(), U64(10)); + assert_eq!(11_u32.to_json(), U64(11)); + assert_eq!(12_u64.to_json(), U64(12)); + assert_eq!(13.0_f32.to_json(), F64(13.0_f64)); + assert_eq!(14.0_f64.to_json(), F64(14.0_f64)); + assert_eq!(().to_json(), Null); + assert_eq!(f32::INFINITY.to_json(), Null); + assert_eq!(f64::NAN.to_json(), Null); + assert_eq!(true.to_json(), Boolean(true)); + assert_eq!(false.to_json(), Boolean(false)); + assert_eq!("abc".to_json(), String("abc".to_string())); + assert_eq!("abc".to_string().to_json(), String("abc".to_string())); + assert_eq!((1u, 2u).to_json(), array2); + assert_eq!((1u, 2u, 3u).to_json(), array3); + assert_eq!([1u, 2].to_json(), array2); + assert_eq!((&[1u, 2, 3]).to_json(), array3); + assert_eq!((vec![1u, 2]).to_json(), array2); + assert_eq!(vec!(1u, 2, 3).to_json(), array3); + let mut tree_map = BTreeMap::new(); + tree_map.insert("a".to_string(), 1u); + tree_map.insert("b".to_string(), 2); + assert_eq!(tree_map.to_json(), object); + let mut hash_map = HashMap::new(); + hash_map.insert("a".to_string(), 1u); + hash_map.insert("b".to_string(), 2); + assert_eq!(hash_map.to_json(), object); + assert_eq!(Some(15i).to_json(), I64(15)); + assert_eq!(Some(15u).to_json(), U64(15)); + assert_eq!(None::.to_json(), Null); + } + + #[bench] + fn bench_streaming_small(b: &mut Bencher) { + b.iter( || { + let mut parser = Parser::new( + r#"{ + "a": 1.0, + "b": [ + true, + "foo\nbar", + { "c": {"d": null} } + ] + }"#.chars() + ); + loop { + match parser.next() { + None => return, + _ => {} + } + } + }); + } + #[bench] + fn bench_small(b: &mut Bencher) { + b.iter( || { + let _ = from_str(r#"{ + "a": 1.0, + "b": [ + true, + "foo\nbar", + { "c": {"d": null} } + ] + }"#); + }); + } + + fn big_json() -> string::String { + let mut src = "[\n".to_string(); + for _ in range(0i, 500) { + src.push_str(r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": \ + [1,2,3]},"#); + } + src.push_str("{}]"); + return src; + } + + #[bench] + fn bench_streaming_large(b: &mut Bencher) { + let src = big_json(); + b.iter( || { + let mut parser = Parser::new(src.chars()); + loop { + match parser.next() { + None => return, + _ => {} + } + } + }); + } + #[bench] + fn bench_large(b: &mut Bencher) { + let src = big_json(); + b.iter( || { let _ = from_str(src.as_slice()); }); + } +} diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 1ec6a2af309..8ad2013f936 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -40,11 +40,25 @@ extern crate collections; pub use self::serialize::{Decoder, Encoder, Decodable, Encodable, DecoderHelpers, EncoderHelpers}; +#[cfg(stage0)] +#[path = "serialize_stage0.rs"] mod serialize; +#[cfg(not(stage0))] +mod serialize; + +#[cfg(stage0)] +#[path = "collection_impls_stage0.rs"] +mod collection_impls; +#[cfg(not(stage0))] mod collection_impls; pub mod base64; pub mod hex; + +#[cfg(stage0)] +#[path = "json_stage0.rs"] +pub mod json; +#[cfg(not(stage0))] pub mod json; mod rustc_serialize { diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index 558f9e603e1..0646ee1758f 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -19,406 +19,424 @@ use std::rc::Rc; use std::cell::{Cell, RefCell}; use std::sync::Arc; -pub trait Encoder { +pub trait Encoder { + type Error; + // Primitive types: - fn emit_nil(&mut self) -> Result<(), E>; - fn emit_uint(&mut self, v: uint) -> Result<(), E>; - fn emit_u64(&mut self, v: u64) -> Result<(), E>; - fn emit_u32(&mut self, v: u32) -> Result<(), E>; - fn emit_u16(&mut self, v: u16) -> Result<(), E>; - fn emit_u8(&mut self, v: u8) -> Result<(), E>; - fn emit_int(&mut self, v: int) -> Result<(), E>; - fn emit_i64(&mut self, v: i64) -> Result<(), E>; - fn emit_i32(&mut self, v: i32) -> Result<(), E>; - fn emit_i16(&mut self, v: i16) -> Result<(), E>; - fn emit_i8(&mut self, v: i8) -> Result<(), E>; - fn emit_bool(&mut self, v: bool) -> Result<(), E>; - fn emit_f64(&mut self, v: f64) -> Result<(), E>; - fn emit_f32(&mut self, v: f32) -> Result<(), E>; - fn emit_char(&mut self, v: char) -> Result<(), E>; - fn emit_str(&mut self, v: &str) -> Result<(), E>; + fn emit_nil(&mut self) -> Result<(), Self::Error>; + fn emit_uint(&mut self, v: uint) -> Result<(), Self::Error>; + fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error>; + fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error>; + fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error>; + fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error>; + fn emit_int(&mut self, v: int) -> Result<(), Self::Error>; + fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error>; + fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error>; + fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error>; + fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error>; + fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error>; + fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error>; + fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error>; + fn emit_char(&mut self, v: char) -> Result<(), Self::Error>; + fn emit_str(&mut self, v: &str) -> Result<(), Self::Error>; // Compound types: - fn emit_enum(&mut self, name: &str, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_enum(&mut self, name: &str, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; fn emit_enum_variant(&mut self, v_name: &str, v_id: uint, len: uint, - f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; - fn emit_enum_variant_arg(&mut self, a_idx: uint, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; + f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + fn emit_enum_variant_arg(&mut self, a_idx: uint, f: F) + -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; fn emit_enum_struct_variant(&mut self, v_name: &str, v_id: uint, len: uint, - f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; + f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; fn emit_enum_struct_variant_field(&mut self, f_name: &str, f_idx: uint, - f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; + f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_struct(&mut self, name: &str, len: uint, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; - fn emit_struct_field(&mut self, f_name: &str, f_idx: uint, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_struct(&mut self, name: &str, len: uint, f: F) + -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + fn emit_struct_field(&mut self, f_name: &str, f_idx: uint, f: F) + -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_tuple(&mut self, len: uint, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; - fn emit_tuple_arg(&mut self, idx: uint, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_tuple(&mut self, len: uint, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + fn emit_tuple_arg(&mut self, idx: uint, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_tuple_struct(&mut self, name: &str, len: uint, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; - fn emit_tuple_struct_arg(&mut self, f_idx: uint, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_tuple_struct(&mut self, name: &str, len: uint, f: F) + -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + fn emit_tuple_struct_arg(&mut self, f_idx: uint, f: F) + -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; // Specialized types: - fn emit_option(&mut self, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; - fn emit_option_none(&mut self) -> Result<(), E>; - fn emit_option_some(&mut self, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_option(&mut self, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + fn emit_option_none(&mut self) -> Result<(), Self::Error>; + fn emit_option_some(&mut self, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_seq(&mut self, len: uint, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; - fn emit_seq_elt(&mut self, idx: uint, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_seq(&mut self, len: uint, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + fn emit_seq_elt(&mut self, idx: uint, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - fn emit_map(&mut self, len: uint, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; - fn emit_map_elt_key(&mut self, idx: uint, f: F) -> Result<(), E> where - F: FnMut(&mut Self) -> Result<(), E>; - fn emit_map_elt_val(&mut self, idx: uint, f: F) -> Result<(), E> where - F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_map(&mut self, len: uint, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; + fn emit_map_elt_key(&mut self, idx: uint, f: F) -> Result<(), Self::Error> + where F: FnMut(&mut Self) -> Result<(), Self::Error>; + fn emit_map_elt_val(&mut self, idx: uint, f: F) -> Result<(), Self::Error> + where F: FnOnce(&mut Self) -> Result<(), Self::Error>; } -pub trait Decoder { +pub trait Decoder { + type Error; + // Primitive types: - fn read_nil(&mut self) -> Result<(), E>; - fn read_uint(&mut self) -> Result; - fn read_u64(&mut self) -> Result; - fn read_u32(&mut self) -> Result; - fn read_u16(&mut self) -> Result; - fn read_u8(&mut self) -> Result; - fn read_int(&mut self) -> Result; - fn read_i64(&mut self) -> Result; - fn read_i32(&mut self) -> Result; - fn read_i16(&mut self) -> Result; - fn read_i8(&mut self) -> Result; - fn read_bool(&mut self) -> Result; - fn read_f64(&mut self) -> Result; - fn read_f32(&mut self) -> Result; - fn read_char(&mut self) -> Result; - fn read_str(&mut self) -> Result; + fn read_nil(&mut self) -> Result<(), Self::Error>; + fn read_uint(&mut self) -> Result; + fn read_u64(&mut self) -> Result; + fn read_u32(&mut self) -> Result; + fn read_u16(&mut self) -> Result; + fn read_u8(&mut self) -> Result; + fn read_int(&mut self) -> Result; + fn read_i64(&mut self) -> Result; + fn read_i32(&mut self) -> Result; + fn read_i16(&mut self) -> Result; + fn read_i8(&mut self) -> Result; + fn read_bool(&mut self) -> Result; + fn read_f64(&mut self) -> Result; + fn read_f32(&mut self) -> Result; + fn read_char(&mut self) -> Result; + fn read_str(&mut self) -> Result; // Compound types: - fn read_enum(&mut self, name: &str, f: F) -> Result where - F: FnOnce(&mut Self) -> Result; + fn read_enum(&mut self, name: &str, f: F) -> Result + where F: FnOnce(&mut Self) -> Result; - fn read_enum_variant(&mut self, names: &[&str], f: F) -> Result where - F: FnMut(&mut Self, uint) -> Result; - fn read_enum_variant_arg(&mut self, a_idx: uint, f: F) -> Result where - F: FnOnce(&mut Self) -> Result; + fn read_enum_variant(&mut self, names: &[&str], f: F) + -> Result + where F: FnMut(&mut Self, uint) -> Result; + fn read_enum_variant_arg(&mut self, a_idx: uint, f: F) + -> Result + where F: FnOnce(&mut Self) -> Result; - fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> Result where - F: FnMut(&mut Self, uint) -> Result; + fn read_enum_struct_variant(&mut self, names: &[&str], f: F) + -> Result + where F: FnMut(&mut Self, uint) -> Result; fn read_enum_struct_variant_field(&mut self, &f_name: &str, f_idx: uint, f: F) - -> Result where - F: FnOnce(&mut Self) -> Result; + -> Result + where F: FnOnce(&mut Self) -> Result; - fn read_struct(&mut self, s_name: &str, len: uint, f: F) -> Result where - F: FnOnce(&mut Self) -> Result; + fn read_struct(&mut self, s_name: &str, len: uint, f: F) + -> Result + where F: FnOnce(&mut Self) -> Result; fn read_struct_field(&mut self, f_name: &str, f_idx: uint, f: F) - -> Result where - F: FnOnce(&mut Self) -> Result; + -> Result + where F: FnOnce(&mut Self) -> Result; - fn read_tuple(&mut self, len: uint, f: F) -> Result where - F: FnOnce(&mut Self) -> Result; - fn read_tuple_arg(&mut self, a_idx: uint, f: F) -> Result where - F: FnOnce(&mut Self) -> Result; + fn read_tuple(&mut self, len: uint, f: F) -> Result + where F: FnOnce(&mut Self) -> Result; + fn read_tuple_arg(&mut self, a_idx: uint, f: F) + -> Result + where F: FnOnce(&mut Self) -> Result; - fn read_tuple_struct(&mut self, s_name: &str, len: uint, f: F) -> Result where - F: FnOnce(&mut Self) -> Result; - fn read_tuple_struct_arg(&mut self, a_idx: uint, f: F) -> Result where - F: FnOnce(&mut Self) -> Result; + fn read_tuple_struct(&mut self, s_name: &str, len: uint, f: F) + -> Result + where F: FnOnce(&mut Self) -> Result; + fn read_tuple_struct_arg(&mut self, a_idx: uint, f: F) + -> Result + where F: FnOnce(&mut Self) -> Result; // Specialized types: - fn read_option(&mut self, f: F) -> Result where - F: FnMut(&mut Self, bool) -> Result; + fn read_option(&mut self, f: F) -> Result + where F: FnMut(&mut Self, bool) -> Result; - fn read_seq(&mut self, f: F) -> Result where - F: FnOnce(&mut Self, uint) -> Result; - fn read_seq_elt(&mut self, idx: uint, f: F) -> Result where - F: FnOnce(&mut Self) -> Result; + fn read_seq(&mut self, f: F) -> Result + where F: FnOnce(&mut Self, uint) -> Result; + fn read_seq_elt(&mut self, idx: uint, f: F) -> Result + where F: FnOnce(&mut Self) -> Result; - fn read_map(&mut self, f: F) -> Result where - F: FnOnce(&mut Self, uint) -> Result; - fn read_map_elt_key(&mut self, idx: uint, f: F) -> Result where - F: FnOnce(&mut Self) -> Result; - fn read_map_elt_val(&mut self, idx: uint, f: F) -> Result where - F: FnOnce(&mut Self) -> Result; + fn read_map(&mut self, f: F) -> Result + where F: FnOnce(&mut Self, uint) -> Result; + fn read_map_elt_key(&mut self, idx: uint, f: F) + -> Result + where F: FnOnce(&mut Self) -> Result; + fn read_map_elt_val(&mut self, idx: uint, f: F) + -> Result + where F: FnOnce(&mut Self) -> Result; // Failure - fn error(&mut self, err: &str) -> E; + fn error(&mut self, err: &str) -> Self::Error; } -pub trait Encodable, E> for Sized? { - fn encode(&self, s: &mut S) -> Result<(), E>; +pub trait Encodable for Sized? { + fn encode(&self, s: &mut S) -> Result<(), S::Error>; } -pub trait Decodable, E> { - fn decode(d: &mut D) -> Result; +pub trait Decodable { + fn decode(d: &mut D) -> Result; } -impl> Encodable for uint { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for uint { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_uint(*self) } } -impl> Decodable for uint { - fn decode(d: &mut D) -> Result { +impl Decodable for uint { + fn decode(d: &mut D) -> Result { d.read_uint() } } -impl> Encodable for u8 { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for u8 { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u8(*self) } } -impl> Decodable for u8 { - fn decode(d: &mut D) -> Result { +impl Decodable for u8 { + fn decode(d: &mut D) -> Result { d.read_u8() } } -impl> Encodable for u16 { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for u16 { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u16(*self) } } -impl> Decodable for u16 { - fn decode(d: &mut D) -> Result { +impl Decodable for u16 { + fn decode(d: &mut D) -> Result { d.read_u16() } } -impl> Encodable for u32 { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for u32 { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u32(*self) } } -impl> Decodable for u32 { - fn decode(d: &mut D) -> Result { +impl Decodable for u32 { + fn decode(d: &mut D) -> Result { d.read_u32() } } -impl> Encodable for u64 { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for u64 { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u64(*self) } } -impl> Decodable for u64 { - fn decode(d: &mut D) -> Result { +impl Decodable for u64 { + fn decode(d: &mut D) -> Result { d.read_u64() } } -impl> Encodable for int { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for int { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_int(*self) } } -impl> Decodable for int { - fn decode(d: &mut D) -> Result { +impl Decodable for int { + fn decode(d: &mut D) -> Result { d.read_int() } } -impl> Encodable for i8 { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for i8 { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_i8(*self) } } -impl> Decodable for i8 { - fn decode(d: &mut D) -> Result { +impl Decodable for i8 { + fn decode(d: &mut D) -> Result { d.read_i8() } } -impl> Encodable for i16 { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for i16 { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_i16(*self) } } -impl> Decodable for i16 { - fn decode(d: &mut D) -> Result { +impl Decodable for i16 { + fn decode(d: &mut D) -> Result { d.read_i16() } } -impl> Encodable for i32 { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for i32 { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_i32(*self) } } -impl> Decodable for i32 { - fn decode(d: &mut D) -> Result { +impl Decodable for i32 { + fn decode(d: &mut D) -> Result { d.read_i32() } } -impl> Encodable for i64 { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for i64 { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_i64(*self) } } -impl> Decodable for i64 { - fn decode(d: &mut D) -> Result { +impl Decodable for i64 { + fn decode(d: &mut D) -> Result { d.read_i64() } } -impl> Encodable for str { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for str { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_str(self) } } -impl> Encodable for String { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for String { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_str(self[]) } } -impl> Decodable for String { - fn decode(d: &mut D) -> Result { +impl Decodable for String { + fn decode(d: &mut D) -> Result { d.read_str() } } -impl> Encodable for f32 { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for f32 { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_f32(*self) } } -impl> Decodable for f32 { - fn decode(d: &mut D) -> Result { +impl Decodable for f32 { + fn decode(d: &mut D) -> Result { d.read_f32() } } -impl> Encodable for f64 { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for f64 { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_f64(*self) } } -impl> Decodable for f64 { - fn decode(d: &mut D) -> Result { +impl Decodable for f64 { + fn decode(d: &mut D) -> Result { d.read_f64() } } -impl> Encodable for bool { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for bool { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_bool(*self) } } -impl> Decodable for bool { - fn decode(d: &mut D) -> Result { +impl Decodable for bool { + fn decode(d: &mut D) -> Result { d.read_bool() } } -impl> Encodable for char { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for char { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_char(*self) } } -impl> Decodable for char { - fn decode(d: &mut D) -> Result { +impl Decodable for char { + fn decode(d: &mut D) -> Result { d.read_char() } } -impl> Encodable for () { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for () { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_nil() } } -impl> Decodable for () { - fn decode(d: &mut D) -> Result<(), E> { +impl Decodable for () { + fn decode(d: &mut D) -> Result<(), D::Error> { d.read_nil() } } -impl<'a, E, S: Encoder, Sized? T: Encodable> Encodable for &'a T { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl<'a, Sized? T: Encodable> Encodable for &'a T { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { (**self).encode(s) } } -impl, Sized? T: Encodable> Encodable for Box { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for Box { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { (**self).encode(s) } } -impl, T: Decodable> Decodable for Box { - fn decode(d: &mut D) -> Result, E> { +impl< T: Decodable> Decodable for Box { + fn decode(d: &mut D) -> Result, D::Error> { Ok(box try!(Decodable::decode(d))) } } -impl, T: Decodable> Decodable for Box<[T]> { - fn decode(d: &mut D) -> Result, E> { +impl< T: Decodable> Decodable for Box<[T]> { + fn decode(d: &mut D) -> Result, D::Error> { let v: Vec = try!(Decodable::decode(d)); Ok(v.into_boxed_slice()) } } -impl,T:Encodable> Encodable for Rc { +impl Encodable for Rc { #[inline] - fn encode(&self, s: &mut S) -> Result<(), E> { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { (**self).encode(s) } } -impl,T:Decodable> Decodable for Rc { +impl Decodable for Rc { #[inline] - fn decode(d: &mut D) -> Result, E> { + fn decode(d: &mut D) -> Result, D::Error> { Ok(Rc::new(try!(Decodable::decode(d)))) } } -impl,T:Encodable> Encodable for [T] { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for [T] { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { for (i, e) in self.iter().enumerate() { try!(s.emit_seq_elt(i, |s| e.encode(s))) @@ -428,8 +446,8 @@ impl,T:Encodable> Encodable for [T] { } } -impl,T:Encodable> Encodable for Vec { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for Vec { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_seq(self.len(), |s| { for (i, e) in self.iter().enumerate() { try!(s.emit_seq_elt(i, |s| e.encode(s))) @@ -439,8 +457,8 @@ impl,T:Encodable> Encodable for Vec { } } -impl,T:Decodable> Decodable for Vec { - fn decode(d: &mut D) -> Result, E> { +impl Decodable for Vec { + fn decode(d: &mut D) -> Result, D::Error> { d.read_seq(|d, len| { let mut v = Vec::with_capacity(len); for i in range(0, len) { @@ -451,8 +469,8 @@ impl,T:Decodable> Decodable for Vec { } } -impl,T:Encodable> Encodable for Option { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for Option { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_option(|s| { match *self { None => s.emit_option_none(), @@ -462,8 +480,8 @@ impl,T:Encodable> Encodable for Option { } } -impl,T:Decodable> Decodable for Option { - fn decode(d: &mut D) -> Result, E> { +impl Decodable for Option { + fn decode(d: &mut D) -> Result, D::Error> { d.read_option(|d, b| { if b { Ok(Some(try!(Decodable::decode(d)))) @@ -487,22 +505,23 @@ macro_rules! count_idents { macro_rules! tuple { () => (); ( $($name:ident,)+ ) => ( - impl,$($name:Decodable),*> Decodable for ($($name,)*) { + impl<$($name:Decodable),*> Decodable for ($($name,)*) { #[allow(non_snake_case)] - fn decode(d: &mut D) -> Result<($($name,)*), E> { + fn decode(d: &mut D) -> Result<($($name,)*), D::Error> { let len: uint = count_idents!($($name),*); d.read_tuple(len, |d| { let mut i = 0; - let ret = ($(try!(d.read_tuple_arg({ i+=1; i-1 }, |d| -> Result<$name,E> { + let ret = ($(try!(d.read_tuple_arg({ i+=1; i-1 }, + |d| -> Result<$name,D::Error> { Decodable::decode(d) })),)*); return Ok(ret); }) } } - impl,$($name:Encodable),*> Encodable for ($($name,)*) { + impl<$($name:Encodable),*> Encodable for ($($name,)*) { #[allow(non_snake_case)] - fn encode(&self, s: &mut S) -> Result<(), E> { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { let ($(ref $name,)*) = *self; let mut n = 0; $(let $name = $name; n += 1;)* @@ -519,40 +538,40 @@ macro_rules! tuple { tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } -impl> Encodable for path::posix::Path { - fn encode(&self, e: &mut S) -> Result<(), E> { +impl Encodable for path::posix::Path { + fn encode(&self, e: &mut S) -> Result<(), S::Error> { self.as_vec().encode(e) } } -impl> Decodable for path::posix::Path { - fn decode(d: &mut D) -> Result { +impl Decodable for path::posix::Path { + fn decode(d: &mut D) -> Result { let bytes: Vec = try!(Decodable::decode(d)); Ok(path::posix::Path::new(bytes)) } } -impl> Encodable for path::windows::Path { - fn encode(&self, e: &mut S) -> Result<(), E> { +impl Encodable for path::windows::Path { + fn encode(&self, e: &mut S) -> Result<(), S::Error> { self.as_vec().encode(e) } } -impl> Decodable for path::windows::Path { - fn decode(d: &mut D) -> Result { +impl Decodable for path::windows::Path { + fn decode(d: &mut D) -> Result { let bytes: Vec = try!(Decodable::decode(d)); Ok(path::windows::Path::new(bytes)) } } -impl, T: Encodable + Copy> Encodable for Cell { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for Cell { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { self.get().encode(s) } } -impl, T: Decodable + Copy> Decodable for Cell { - fn decode(d: &mut D) -> Result, E> { +impl Decodable for Cell { + fn decode(d: &mut D) -> Result, D::Error> { Ok(Cell::new(try!(Decodable::decode(d)))) } } @@ -562,26 +581,26 @@ impl, T: Decodable + Copy> Decodable for Cell { // `encoder.error("attempting to Encode borrowed RefCell")` // from `encode` when `try_borrow` returns `None`. -impl, T: Encodable> Encodable for RefCell { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for RefCell { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { self.borrow().encode(s) } } -impl, T: Decodable> Decodable for RefCell { - fn decode(d: &mut D) -> Result, E> { +impl Decodable for RefCell { + fn decode(d: &mut D) -> Result, D::Error> { Ok(RefCell::new(try!(Decodable::decode(d)))) } } -impl, T:Encodable> Encodable for Arc { - fn encode(&self, s: &mut S) -> Result<(), E> { +impl Encodable for Arc { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { (**self).encode(s) } } -impl,T:Decodable+Send+Sync> Decodable for Arc { - fn decode(d: &mut D) -> Result, E> { +impl Decodable for Arc { + fn decode(d: &mut D) -> Result, D::Error> { Ok(Arc::new(try!(Decodable::decode(d)))) } } @@ -589,14 +608,15 @@ impl,T:Decodable+Send+Sync> Decodable for Arc { // ___________________________________________________________________________ // Helper routines -pub trait EncoderHelpers { - fn emit_from_vec(&mut self, v: &[T], f: F) -> Result<(), E> where - F: FnMut(&mut Self, &T) -> Result<(), E>; +pub trait EncoderHelpers: Encoder { + fn emit_from_vec(&mut self, v: &[T], f: F) + -> Result<(), ::Error> + where F: FnMut(&mut Self, &T) -> Result<(), ::Error>; } -impl> EncoderHelpers for S { - fn emit_from_vec(&mut self, v: &[T], mut f: F) -> Result<(), E> where - F: FnMut(&mut S, &T) -> Result<(), E>, +impl EncoderHelpers for S { + fn emit_from_vec(&mut self, v: &[T], mut f: F) -> Result<(), S::Error> where + F: FnMut(&mut S, &T) -> Result<(), S::Error>, { self.emit_seq(v.len(), |this| { for (i, e) in v.iter().enumerate() { @@ -609,14 +629,15 @@ impl> EncoderHelpers for S { } } -pub trait DecoderHelpers { - fn read_to_vec(&mut self, f: F) -> Result, E> where - F: FnMut(&mut Self) -> Result; +pub trait DecoderHelpers: Decoder { + fn read_to_vec(&mut self, f: F) + -> Result, ::Error> where + F: FnMut(&mut Self) -> Result::Error>; } -impl> DecoderHelpers for D { - fn read_to_vec(&mut self, mut f: F) -> Result, E> where F: - FnMut(&mut D) -> Result, +impl DecoderHelpers for D { + fn read_to_vec(&mut self, mut f: F) -> Result, D::Error> where F: + FnMut(&mut D) -> Result, { self.read_seq(|this, len| { let mut v = Vec::with_capacity(len); diff --git a/src/libserialize/serialize_stage0.rs b/src/libserialize/serialize_stage0.rs new file mode 100644 index 00000000000..558f9e603e1 --- /dev/null +++ b/src/libserialize/serialize_stage0.rs @@ -0,0 +1,629 @@ +// Copyright 2012-2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Support code for encoding and decoding types. + +/* +Core encoding and decoding interfaces. +*/ + +use std::path; +use std::rc::Rc; +use std::cell::{Cell, RefCell}; +use std::sync::Arc; + +pub trait Encoder { + // Primitive types: + fn emit_nil(&mut self) -> Result<(), E>; + fn emit_uint(&mut self, v: uint) -> Result<(), E>; + fn emit_u64(&mut self, v: u64) -> Result<(), E>; + fn emit_u32(&mut self, v: u32) -> Result<(), E>; + fn emit_u16(&mut self, v: u16) -> Result<(), E>; + fn emit_u8(&mut self, v: u8) -> Result<(), E>; + fn emit_int(&mut self, v: int) -> Result<(), E>; + fn emit_i64(&mut self, v: i64) -> Result<(), E>; + fn emit_i32(&mut self, v: i32) -> Result<(), E>; + fn emit_i16(&mut self, v: i16) -> Result<(), E>; + fn emit_i8(&mut self, v: i8) -> Result<(), E>; + fn emit_bool(&mut self, v: bool) -> Result<(), E>; + fn emit_f64(&mut self, v: f64) -> Result<(), E>; + fn emit_f32(&mut self, v: f32) -> Result<(), E>; + fn emit_char(&mut self, v: char) -> Result<(), E>; + fn emit_str(&mut self, v: &str) -> Result<(), E>; + + // Compound types: + fn emit_enum(&mut self, name: &str, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_enum_variant(&mut self, v_name: &str, + v_id: uint, + len: uint, + f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_enum_variant_arg(&mut self, a_idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_enum_struct_variant(&mut self, v_name: &str, + v_id: uint, + len: uint, + f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_enum_struct_variant_field(&mut self, + f_name: &str, + f_idx: uint, + f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_struct(&mut self, name: &str, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_struct_field(&mut self, f_name: &str, f_idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_tuple(&mut self, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_tuple_arg(&mut self, idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_tuple_struct(&mut self, name: &str, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_tuple_struct_arg(&mut self, f_idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + // Specialized types: + fn emit_option(&mut self, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_option_none(&mut self) -> Result<(), E>; + fn emit_option_some(&mut self, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_seq(&mut self, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_seq_elt(&mut self, idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + + fn emit_map(&mut self, len: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; + fn emit_map_elt_key(&mut self, idx: uint, f: F) -> Result<(), E> where + F: FnMut(&mut Self) -> Result<(), E>; + fn emit_map_elt_val(&mut self, idx: uint, f: F) -> Result<(), E> where + F: FnOnce(&mut Self) -> Result<(), E>; +} + +pub trait Decoder { + // Primitive types: + fn read_nil(&mut self) -> Result<(), E>; + fn read_uint(&mut self) -> Result; + fn read_u64(&mut self) -> Result; + fn read_u32(&mut self) -> Result; + fn read_u16(&mut self) -> Result; + fn read_u8(&mut self) -> Result; + fn read_int(&mut self) -> Result; + fn read_i64(&mut self) -> Result; + fn read_i32(&mut self) -> Result; + fn read_i16(&mut self) -> Result; + fn read_i8(&mut self) -> Result; + fn read_bool(&mut self) -> Result; + fn read_f64(&mut self) -> Result; + fn read_f32(&mut self) -> Result; + fn read_char(&mut self) -> Result; + fn read_str(&mut self) -> Result; + + // Compound types: + fn read_enum(&mut self, name: &str, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + + fn read_enum_variant(&mut self, names: &[&str], f: F) -> Result where + F: FnMut(&mut Self, uint) -> Result; + fn read_enum_variant_arg(&mut self, a_idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + + fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> Result where + F: FnMut(&mut Self, uint) -> Result; + fn read_enum_struct_variant_field(&mut self, + &f_name: &str, + f_idx: uint, + f: F) + -> Result where + F: FnOnce(&mut Self) -> Result; + + fn read_struct(&mut self, s_name: &str, len: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + fn read_struct_field(&mut self, + f_name: &str, + f_idx: uint, + f: F) + -> Result where + F: FnOnce(&mut Self) -> Result; + + fn read_tuple(&mut self, len: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + fn read_tuple_arg(&mut self, a_idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + + fn read_tuple_struct(&mut self, s_name: &str, len: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + fn read_tuple_struct_arg(&mut self, a_idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + + // Specialized types: + fn read_option(&mut self, f: F) -> Result where + F: FnMut(&mut Self, bool) -> Result; + + fn read_seq(&mut self, f: F) -> Result where + F: FnOnce(&mut Self, uint) -> Result; + fn read_seq_elt(&mut self, idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + + fn read_map(&mut self, f: F) -> Result where + F: FnOnce(&mut Self, uint) -> Result; + fn read_map_elt_key(&mut self, idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + fn read_map_elt_val(&mut self, idx: uint, f: F) -> Result where + F: FnOnce(&mut Self) -> Result; + + // Failure + fn error(&mut self, err: &str) -> E; +} + +pub trait Encodable, E> for Sized? { + fn encode(&self, s: &mut S) -> Result<(), E>; +} + +pub trait Decodable, E> { + fn decode(d: &mut D) -> Result; +} + +impl> Encodable for uint { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_uint(*self) + } +} + +impl> Decodable for uint { + fn decode(d: &mut D) -> Result { + d.read_uint() + } +} + +impl> Encodable for u8 { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_u8(*self) + } +} + +impl> Decodable for u8 { + fn decode(d: &mut D) -> Result { + d.read_u8() + } +} + +impl> Encodable for u16 { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_u16(*self) + } +} + +impl> Decodable for u16 { + fn decode(d: &mut D) -> Result { + d.read_u16() + } +} + +impl> Encodable for u32 { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_u32(*self) + } +} + +impl> Decodable for u32 { + fn decode(d: &mut D) -> Result { + d.read_u32() + } +} + +impl> Encodable for u64 { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_u64(*self) + } +} + +impl> Decodable for u64 { + fn decode(d: &mut D) -> Result { + d.read_u64() + } +} + +impl> Encodable for int { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_int(*self) + } +} + +impl> Decodable for int { + fn decode(d: &mut D) -> Result { + d.read_int() + } +} + +impl> Encodable for i8 { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_i8(*self) + } +} + +impl> Decodable for i8 { + fn decode(d: &mut D) -> Result { + d.read_i8() + } +} + +impl> Encodable for i16 { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_i16(*self) + } +} + +impl> Decodable for i16 { + fn decode(d: &mut D) -> Result { + d.read_i16() + } +} + +impl> Encodable for i32 { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_i32(*self) + } +} + +impl> Decodable for i32 { + fn decode(d: &mut D) -> Result { + d.read_i32() + } +} + +impl> Encodable for i64 { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_i64(*self) + } +} + +impl> Decodable for i64 { + fn decode(d: &mut D) -> Result { + d.read_i64() + } +} + +impl> Encodable for str { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_str(self) + } +} + +impl> Encodable for String { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_str(self[]) + } +} + +impl> Decodable for String { + fn decode(d: &mut D) -> Result { + d.read_str() + } +} + +impl> Encodable for f32 { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_f32(*self) + } +} + +impl> Decodable for f32 { + fn decode(d: &mut D) -> Result { + d.read_f32() + } +} + +impl> Encodable for f64 { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_f64(*self) + } +} + +impl> Decodable for f64 { + fn decode(d: &mut D) -> Result { + d.read_f64() + } +} + +impl> Encodable for bool { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_bool(*self) + } +} + +impl> Decodable for bool { + fn decode(d: &mut D) -> Result { + d.read_bool() + } +} + +impl> Encodable for char { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_char(*self) + } +} + +impl> Decodable for char { + fn decode(d: &mut D) -> Result { + d.read_char() + } +} + +impl> Encodable for () { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_nil() + } +} + +impl> Decodable for () { + fn decode(d: &mut D) -> Result<(), E> { + d.read_nil() + } +} + +impl<'a, E, S: Encoder, Sized? T: Encodable> Encodable for &'a T { + fn encode(&self, s: &mut S) -> Result<(), E> { + (**self).encode(s) + } +} + +impl, Sized? T: Encodable> Encodable for Box { + fn encode(&self, s: &mut S) -> Result<(), E> { + (**self).encode(s) + } +} + +impl, T: Decodable> Decodable for Box { + fn decode(d: &mut D) -> Result, E> { + Ok(box try!(Decodable::decode(d))) + } +} + +impl, T: Decodable> Decodable for Box<[T]> { + fn decode(d: &mut D) -> Result, E> { + let v: Vec = try!(Decodable::decode(d)); + Ok(v.into_boxed_slice()) + } +} + +impl,T:Encodable> Encodable for Rc { + #[inline] + fn encode(&self, s: &mut S) -> Result<(), E> { + (**self).encode(s) + } +} + +impl,T:Decodable> Decodable for Rc { + #[inline] + fn decode(d: &mut D) -> Result, E> { + Ok(Rc::new(try!(Decodable::decode(d)))) + } +} + +impl,T:Encodable> Encodable for [T] { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_seq(self.len(), |s| { + for (i, e) in self.iter().enumerate() { + try!(s.emit_seq_elt(i, |s| e.encode(s))) + } + Ok(()) + }) + } +} + +impl,T:Encodable> Encodable for Vec { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_seq(self.len(), |s| { + for (i, e) in self.iter().enumerate() { + try!(s.emit_seq_elt(i, |s| e.encode(s))) + } + Ok(()) + }) + } +} + +impl,T:Decodable> Decodable for Vec { + fn decode(d: &mut D) -> Result, E> { + d.read_seq(|d, len| { + let mut v = Vec::with_capacity(len); + for i in range(0, len) { + v.push(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); + } + Ok(v) + }) + } +} + +impl,T:Encodable> Encodable for Option { + fn encode(&self, s: &mut S) -> Result<(), E> { + s.emit_option(|s| { + match *self { + None => s.emit_option_none(), + Some(ref v) => s.emit_option_some(|s| v.encode(s)), + } + }) + } +} + +impl,T:Decodable> Decodable for Option { + fn decode(d: &mut D) -> Result, E> { + d.read_option(|d, b| { + if b { + Ok(Some(try!(Decodable::decode(d)))) + } else { + Ok(None) + } + }) + } +} + +macro_rules! peel { + ($name:ident, $($other:ident,)*) => (tuple! { $($other,)* }) +} + +/// Evaluates to the number of identifiers passed to it, for example: `count_idents!(a, b, c) == 3 +macro_rules! count_idents { + () => { 0u }; + ($_i:ident $(, $rest:ident)*) => { 1 + count_idents!($($rest),*) } +} + +macro_rules! tuple { + () => (); + ( $($name:ident,)+ ) => ( + impl,$($name:Decodable),*> Decodable for ($($name,)*) { + #[allow(non_snake_case)] + fn decode(d: &mut D) -> Result<($($name,)*), E> { + let len: uint = count_idents!($($name),*); + d.read_tuple(len, |d| { + let mut i = 0; + let ret = ($(try!(d.read_tuple_arg({ i+=1; i-1 }, |d| -> Result<$name,E> { + Decodable::decode(d) + })),)*); + return Ok(ret); + }) + } + } + impl,$($name:Encodable),*> Encodable for ($($name,)*) { + #[allow(non_snake_case)] + fn encode(&self, s: &mut S) -> Result<(), E> { + let ($(ref $name,)*) = *self; + let mut n = 0; + $(let $name = $name; n += 1;)* + s.emit_tuple(n, |s| { + let mut i = 0; + $(try!(s.emit_tuple_arg({ i+=1; i-1 }, |s| $name.encode(s)));)* + Ok(()) + }) + } + } + peel! { $($name,)* } + ) +} + +tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } + +impl> Encodable for path::posix::Path { + fn encode(&self, e: &mut S) -> Result<(), E> { + self.as_vec().encode(e) + } +} + +impl> Decodable for path::posix::Path { + fn decode(d: &mut D) -> Result { + let bytes: Vec = try!(Decodable::decode(d)); + Ok(path::posix::Path::new(bytes)) + } +} + +impl> Encodable for path::windows::Path { + fn encode(&self, e: &mut S) -> Result<(), E> { + self.as_vec().encode(e) + } +} + +impl> Decodable for path::windows::Path { + fn decode(d: &mut D) -> Result { + let bytes: Vec = try!(Decodable::decode(d)); + Ok(path::windows::Path::new(bytes)) + } +} + +impl, T: Encodable + Copy> Encodable for Cell { + fn encode(&self, s: &mut S) -> Result<(), E> { + self.get().encode(s) + } +} + +impl, T: Decodable + Copy> Decodable for Cell { + fn decode(d: &mut D) -> Result, E> { + Ok(Cell::new(try!(Decodable::decode(d)))) + } +} + +// FIXME: #15036 +// Should use `try_borrow`, returning a +// `encoder.error("attempting to Encode borrowed RefCell")` +// from `encode` when `try_borrow` returns `None`. + +impl, T: Encodable> Encodable for RefCell { + fn encode(&self, s: &mut S) -> Result<(), E> { + self.borrow().encode(s) + } +} + +impl, T: Decodable> Decodable for RefCell { + fn decode(d: &mut D) -> Result, E> { + Ok(RefCell::new(try!(Decodable::decode(d)))) + } +} + +impl, T:Encodable> Encodable for Arc { + fn encode(&self, s: &mut S) -> Result<(), E> { + (**self).encode(s) + } +} + +impl,T:Decodable+Send+Sync> Decodable for Arc { + fn decode(d: &mut D) -> Result, E> { + Ok(Arc::new(try!(Decodable::decode(d)))) + } +} + +// ___________________________________________________________________________ +// Helper routines + +pub trait EncoderHelpers { + fn emit_from_vec(&mut self, v: &[T], f: F) -> Result<(), E> where + F: FnMut(&mut Self, &T) -> Result<(), E>; +} + +impl> EncoderHelpers for S { + fn emit_from_vec(&mut self, v: &[T], mut f: F) -> Result<(), E> where + F: FnMut(&mut S, &T) -> Result<(), E>, + { + self.emit_seq(v.len(), |this| { + for (i, e) in v.iter().enumerate() { + try!(this.emit_seq_elt(i, |this| { + f(this, e) + })); + } + Ok(()) + }) + } +} + +pub trait DecoderHelpers { + fn read_to_vec(&mut self, f: F) -> Result, E> where + F: FnMut(&mut Self) -> Result; +} + +impl> DecoderHelpers for D { + fn read_to_vec(&mut self, mut f: F) -> Result, E> where F: + FnMut(&mut D) -> Result, + { + self.read_seq(|this, len| { + let mut v = Vec::with_capacity(len); + for i in range(0, len) { + v.push(try!(this.read_seq_elt(i, |this| f(this)))); + } + Ok(v) + }) + } +} diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 03b9eaf76b9..c9d27e304ff 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -182,18 +182,34 @@ impl Name { /// A mark represents a unique id associated with a macro expansion pub type Mrk = u32; +#[cfg(stage0)] impl, E> Encodable for Ident { fn encode(&self, s: &mut S) -> Result<(), E> { s.emit_str(token::get_ident(*self).get()) } } +#[cfg(not(stage0))] +impl Encodable for Ident { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_str(token::get_ident(*self).get()) + } +} + +#[cfg(stage0)] impl, E> Decodable for Ident { fn decode(d: &mut D) -> Result { Ok(str_to_ident(try!(d.read_str())[])) } } +#[cfg(not(stage0))] +impl Decodable for Ident { + fn decode(d: &mut D) -> Result { + Ok(str_to_ident(try!(d.read_str())[])) + } +} + /// Function name (not all functions have names) pub type FnIdent = Option; @@ -1686,27 +1702,7 @@ mod test { // are ASTs encodable? #[test] fn check_asts_encodable() { - use std::io; - let e = Crate { - module: Mod { - inner: Span { - lo: BytePos(11), - hi: BytePos(19), - expn_id: NO_EXPANSION, - }, - view_items: Vec::new(), - items: Vec::new(), - }, - attrs: Vec::new(), - config: Vec::new(), - span: Span { - lo: BytePos(10), - hi: BytePos(20), - expn_id: NO_EXPANSION, - }, - exported_macros: Vec::new(), - }; - // doesn't matter which encoder we use.... - let _f = &e as &serialize::Encodable; + fn assert_encodable() {} + assert_encodable::(); } } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 2c7bbcb6faf..a49f2614cd7 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -120,6 +120,7 @@ impl PartialEq for Span { impl Eq for Span {} +#[cfg(stage0)] impl, E> Encodable for Span { /* Note #1972 -- spans are encoded but not decoded */ fn encode(&self, s: &mut S) -> Result<(), E> { @@ -127,12 +128,28 @@ impl, E> Encodable for Span { } } +#[cfg(not(stage0))] +impl Encodable for Span { + /* Note #1972 -- spans are encoded but not decoded */ + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_nil() + } +} + +#[cfg(stage0)] impl, E> Decodable for Span { fn decode(_d: &mut D) -> Result { Ok(DUMMY_SP) } } +#[cfg(not(stage0))] +impl Decodable for Span { + fn decode(_d: &mut D) -> Result { + Ok(DUMMY_SP) + } +} + pub fn spanned(lo: BytePos, hi: BytePos, t: T) -> Spanned { respan(mk_sp(lo, hi), t) } diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 882136cb862..c0631b8350b 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -52,27 +52,29 @@ fn expand_deriving_decodable_imp(cx: &mut ExtCtxt, let trait_def = TraitDef { span: span, attributes: Vec::new(), - path: Path::new_(vec!(krate, "Decodable"), None, - vec!(box Literal(Path::new_local("__D")), - box Literal(Path::new_local("__E"))), true), + path: Path::new_(vec!(krate, "Decodable"), None, vec!(), true), additional_bounds: Vec::new(), - generics: LifetimeBounds { - lifetimes: Vec::new(), - bounds: vec!(("__D", vec!(Path::new_( - vec!(krate, "Decoder"), None, - vec!(box Literal(Path::new_local("__E"))), true))), - ("__E", vec!())) - }, + generics: LifetimeBounds::empty(), methods: vec!( MethodDef { name: "decode", - generics: LifetimeBounds::empty(), + generics: LifetimeBounds { + lifetimes: Vec::new(), + bounds: vec!(("__D", vec!(Path::new_( + vec!(krate, "Decoder"), None, + vec!(), true)))) + }, explicit_self: None, args: vec!(Ptr(box Literal(Path::new_local("__D")), Borrowed(None, MutMutable))), - ret_ty: Literal(Path::new_(vec!("std", "result", "Result"), None, - vec!(box Self, - box Literal(Path::new_local("__E"))), true)), + ret_ty: Literal(Path::new_( + vec!("std", "result", "Result"), + None, + vec!(box Self, box Literal(Path::new_( + vec!["__D", "Error"], None, vec![], false + ))), + true + )), attributes: Vec::new(), combine_substructure: combine_substructure(|a, b, c| { decodable_substructure(a, b, c, krate) diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index b2c929123d5..4323d2979cc 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -128,29 +128,29 @@ fn expand_deriving_encodable_imp(cx: &mut ExtCtxt, let trait_def = TraitDef { span: span, attributes: Vec::new(), - path: Path::new_(vec!(krate, "Encodable"), None, - vec!(box Literal(Path::new_local("__S")), - box Literal(Path::new_local("__E"))), true), + path: Path::new_(vec!(krate, "Encodable"), None, vec!(), true), additional_bounds: Vec::new(), - generics: LifetimeBounds { - lifetimes: Vec::new(), - bounds: vec!(("__S", vec!(Path::new_( - vec!(krate, "Encoder"), None, - vec!(box Literal(Path::new_local("__E"))), true))), - ("__E", vec!())) - }, + generics: LifetimeBounds::empty(), methods: vec!( MethodDef { name: "encode", - generics: LifetimeBounds::empty(), + generics: LifetimeBounds { + lifetimes: Vec::new(), + bounds: vec!(("__S", vec!(Path::new_( + vec!(krate, "Encoder"), None, + vec!(), true)))) + }, explicit_self: borrowed_explicit_self(), args: vec!(Ptr(box Literal(Path::new_local("__S")), Borrowed(None, MutMutable))), - ret_ty: Literal(Path::new_(vec!("std", "result", "Result"), - None, - vec!(box Tuple(Vec::new()), - box Literal(Path::new_local("__E"))), - true)), + ret_ty: Literal(Path::new_( + vec!("std", "result", "Result"), + None, + vec!(box Tuple(Vec::new()), box Literal(Path::new_( + vec!["__S", "Error"], None, vec![], false + ))), + true + )), attributes: Vec::new(), combine_substructure: combine_substructure(|a, b, c| { encodable_substructure(a, b, c) diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs index b87e2c6abbc..2a27431a086 100644 --- a/src/libsyntax/owned_slice.rs +++ b/src/libsyntax/owned_slice.rs @@ -82,12 +82,21 @@ impl FromIterator for OwnedSlice { } } +#[cfg(stage0)] impl, T: Encodable, E> Encodable for OwnedSlice { fn encode(&self, s: &mut S) -> Result<(), E> { self.as_slice().encode(s) } } +#[cfg(not(stage0))] +impl Encodable for OwnedSlice { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + self.as_slice().encode(s) + } +} + +#[cfg(stage0)] impl, T: Decodable, E> Decodable for OwnedSlice { fn decode(d: &mut D) -> Result, E> { Ok(OwnedSlice::from_vec(match Decodable::decode(d) { @@ -96,3 +105,13 @@ impl, T: Decodable, E> Decodable for OwnedSlice { })) } } + +#[cfg(not(stage0))] +impl Decodable for OwnedSlice { + fn decode(d: &mut D) -> Result, D::Error> { + Ok(OwnedSlice::from_vec(match Decodable::decode(d) { + Ok(t) => t, + Err(e) => return Err(e) + })) + } +} diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 4bfcc94a083..b7e89b32b70 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -653,6 +653,7 @@ impl<'a> PartialEq for &'a str { } } +#[cfg(stage0)] impl, E> Decodable for InternedString { fn decode(d: &mut D) -> Result { Ok(get_name(get_ident_interner().intern( @@ -660,12 +661,28 @@ impl, E> Decodable for InternedString { } } +#[cfg(not(stage0))] +impl Decodable for InternedString { + fn decode(d: &mut D) -> Result { + Ok(get_name(get_ident_interner().intern( + try!(d.read_str())[]))) + } +} + +#[cfg(stage0)] impl, E> Encodable for InternedString { fn encode(&self, s: &mut S) -> Result<(), E> { s.emit_str(self.string[]) } } +#[cfg(not(stage0))] +impl Encodable for InternedString { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_str(self.string[]) + } +} + /// Returns the string contents of a name, using the task-local interner. #[inline] pub fn get_name(name: ast::Name) -> InternedString { diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index 6eee1d903ea..13eda7bb88f 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -111,14 +111,30 @@ impl> Hash for P { } } +#[cfg(stage0)] impl, T: 'static + Decodable> Decodable for P { fn decode(d: &mut D) -> Result, E> { Decodable::decode(d).map(P) } } +#[cfg(not(stage0))] +impl Decodable for P { + fn decode(d: &mut D) -> Result, D::Error> { + Decodable::decode(d).map(P) + } +} + +#[cfg(stage0)] impl, T: Encodable> Encodable for P { fn encode(&self, s: &mut S) -> Result<(), E> { (**self).encode(s) } } + +#[cfg(not(stage0))] +impl Encodable for P { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + (**self).encode(s) + } +} diff --git a/src/test/compile-fail/variance-trait-matching-2.rs b/src/test/compile-fail/variance-trait-matching-2.rs deleted file mode 100644 index cae7a4cefad..00000000000 --- a/src/test/compile-fail/variance-trait-matching-2.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate serialize; - -use std::fmt; -use serialize::{Encodable, Encoder}; - -pub fn buffer_encode<'a, - T:Encodable,fmt::Error>>( - to_encode_object: &T) - -> String { - let mut m = String::new(); - { - let mut encoder = - serialize::json::Encoder::new(&mut m); - //~^ ERROR `m` does not live long enough - to_encode_object.encode(&mut encoder); - } - m -} - -fn main() {} diff --git a/src/test/run-pass/issue-11881.rs b/src/test/run-pass/issue-11881.rs index 24deb7c2e4b..d0d8a8589a4 100644 --- a/src/test/run-pass/issue-11881.rs +++ b/src/test/run-pass/issue-11881.rs @@ -40,16 +40,10 @@ enum WireProtocol { // ... } -fn encode_json< - T: for<'a> Encodable, - fmt::Error>>(val: &T, - wr: &mut SeekableMemWriter) { +fn encode_json(val: &T, wr: &mut SeekableMemWriter) { write!(wr, "{}", json::as_json(val)); } -fn encode_rbml<'a, - T: Encodable, - io::IoError>>(val: &T, - wr: &'a mut SeekableMemWriter) { +fn encode_rbml(val: &T, wr: &mut SeekableMemWriter) { let mut encoder = writer::Encoder::new(wr); val.encode(&mut encoder); } diff --git a/src/test/run-pass/issue-15924.rs b/src/test/run-pass/issue-15924.rs index 1ab8deda383..db9f1cc9df7 100644 --- a/src/test/run-pass/issue-15924.rs +++ b/src/test/run-pass/issue-15924.rs @@ -21,7 +21,7 @@ struct Foo { } #[unsafe_destructor] -impl Encodable, fmt::Error>> Drop for Foo { +impl Drop for Foo { fn drop(&mut self) { json::encode(&self.v); } diff --git a/src/test/run-pass/issue-4016.rs b/src/test/run-pass/issue-4016.rs index e5cc8414f06..220332f6354 100644 --- a/src/test/run-pass/issue-4016.rs +++ b/src/test/run-pass/issue-4016.rs @@ -13,7 +13,7 @@ extern crate serialize; use serialize::{json, Decodable}; -trait JD : Decodable { } +trait JD : Decodable {} fn exec() { let doc = json::from_str("").unwrap();