* `Boolean`: equivalent to rust's `bool`
* `Number`: equivalent to rust's `f64`
* `String`: equivalent to rust's `String`
-* `Array`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the same
+* `List`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the same
array
* `Object`: equivalent to rust's `Treemap<String, json::Json>`
* `Null`
use std::mem::{swap, transmute};
use std::num::{FPNaN, FPInfinite};
use std::str::ScalarValue;
-use std::string::String;
+use std::string;
use std::vec::Vec;
use Encodable;
I64(i64),
U64(u64),
F64(f64),
- String(String),
+ String(string::String),
Boolean(bool),
- List(List),
- Object(Object),
+ List(JsonList),
+ Object(JsonObject),
Null,
}
-pub type List = Vec<Json>;
-pub type Object = TreeMap<String, Json>;
+pub type JsonList = Vec<Json>;
+pub type JsonObject = TreeMap<string::String, Json>;
/// The errors that can arise while parsing a JSON stream.
#[deriving(Clone, PartialEq)]
KeyMustBeAString,
ExpectedColon,
TrailingCharacters,
+ TrailingComma,
InvalidEscape,
InvalidUnicodeCodePoint,
LoneLeadingSurrogateInHexEscape,
#[deriving(Clone, PartialEq, Show)]
pub enum DecoderError {
ParseError(ParserError),
- ExpectedError(String, String),
- MissingFieldError(String),
- UnknownVariantError(String),
- ApplicationError(String)
+ ExpectedError(string::String, string::String),
+ MissingFieldError(string::String),
+ UnknownVariantError(string::String),
+ ApplicationError(string::String)
}
/// Returns a readable error string for a given error code.
KeyMustBeAString => "key must be a string",
ExpectedColon => "expected `:`",
TrailingCharacters => "trailing characters",
+ TrailingComma => "trailing comma",
InvalidEscape => "invalid escape",
UnrecognizedHex => "invalid \\u escape (unrecognized hex)",
NotFourDigit => "invalid \\u escape (not four digits)",
}
/// Shortcut function to encode a `T` into a JSON `String`
-pub fn encode<'a, T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> String {
+pub fn encode<'a, T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> string::String {
let buff = Encoder::buffer_encode(object);
- String::from_utf8(buff).unwrap()
+ string::String::from_utf8(buff).unwrap()
}
impl fmt::Show for ErrorCode {
}
}
-fn fmt_number_or_null(v: f64) -> String {
+fn fmt_number_or_null(v: f64) -> string::String {
match v.classify() {
- FPNaN | FPInfinite => String::from_str("null"),
+ FPNaN | FPInfinite => string::String::from_str("null"),
_ => f64::to_str_digits(v, 6u)
}
}
///
/// Note: this function is deprecated. Consider using `json::encode` instead.
#[deprecated = "Replaced by `json::encode`"]
- pub fn str_encode<T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> String {
+ pub fn str_encode<T: Encodable<Encoder<'a>, io::IoError>>(object: &T) -> string::String {
encode(object)
}
}
}
/// Encodes a json value into a string
- pub fn to_pretty_str(&self) -> String {
+ pub fn to_pretty_str(&self) -> string::String {
let mut s = MemWriter::new();
self.to_pretty_writer(&mut s as &mut io::Writer).unwrap();
- String::from_utf8(s.unwrap()).unwrap()
+ string::String::from_utf8(s.unwrap()).unwrap()
}
/// 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: &String) -> Option<&'a Json>{
+ pub fn find<'a>(&'a self, key: &string::String) -> Option<&'a Json>{
match self {
&Object(ref map) => map.find(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: &[&String]) -> Option<&'a Json>{
+ pub fn find_path<'a>(&'a self, keys: &[&string::String]) -> Option<&'a Json>{
let mut target = self;
for key in keys.iter() {
match target.find(*key) {
/// 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: &String) -> Option<&'a Json> {
+ pub fn search<'a>(&'a self, key: &string::String) -> Option<&'a Json> {
match self {
&Object(ref map) => {
match map.find(key) {
/// If the Json value is an Object, returns the associated TreeMap.
/// Returns None otherwise.
- pub fn as_object<'a>(&'a self) -> Option<&'a Object> {
+ pub fn as_object<'a>(&'a self) -> Option<&'a JsonObject> {
match self {
&Object(ref map) => Some(map),
_ => None
/// If the Json value is a List, returns the associated vector.
/// Returns None otherwise.
- pub fn as_list<'a>(&'a self) -> Option<&'a List> {
+ pub fn as_list<'a>(&'a self) -> Option<&'a JsonList> {
match self {
&List(ref list) => Some(&*list),
_ => None
I64Value(i64),
U64Value(u64),
F64Value(f64),
- StringValue(String),
+ StringValue(string::String),
NullValue,
Error(ParserError),
}
#[deriving(PartialEq, Show)]
enum ParserState {
// Parse a value in a list, true means first element.
- ParseList(bool),
+ ParseArray(bool),
// Parse ',' or ']' after an element in a list.
ParseListComma,
// Parse a key:value in an object, true means first element.
}
// Used by Parser to insert Key elements at the top of the stack.
- fn push_key(&mut self, key: String) {
+ 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);
Ok(n)
}
- fn parse_str(&mut self) -> Result<String, ParserError> {
+ fn parse_str(&mut self) -> Result<string::String, ParserError> {
let mut escape = false;
- let mut res = String::new();
+ let mut res = string::String::new();
loop {
self.bump();
// The only paths where the loop can spin a new iteration
// are in the cases ParseListComma and ParseObjectComma if ','
// is parsed. In these cases the state is set to (respectively)
- // ParseList(false) and ParseObject(false), which always return,
+ // 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();
ParseStart => {
return self.parse_start();
}
- ParseList(first) => {
+ ParseArray(first) => {
return self.parse_list(first);
}
ParseListComma => {
let val = self.parse_value();
self.state = match val {
Error(_) => { ParseFinished }
- ListStart => { ParseList(true) }
+ ListStart => { ParseArray(true) }
ObjectStart => { ParseObject(true) }
_ => { ParseBeforeFinish }
};
self.state = match val {
Error(_) => { ParseFinished }
- ListStart => { ParseList(true) }
+ ListStart => { ParseArray(true) }
ObjectStart => { ParseObject(true) }
_ => { ParseListComma }
};
fn parse_list_comma_or_end(&mut self) -> Option<JsonEvent> {
if self.ch_is(',') {
self.stack.bump_index();
- self.state = ParseList(false);
+ self.state = ParseArray(false);
self.bump();
return None;
} else if self.ch_is(']') {
fn parse_object(&mut self, first: bool) -> JsonEvent {
if self.ch_is('}') {
if !first {
- self.stack.pop();
+ if self.stack.is_empty() {
+ return self.error_event(TrailingComma);
+ } else {
+ self.stack.pop();
+ }
}
if self.stack.is_empty() {
self.state = ParseBeforeFinish;
self.state = match val {
Error(_) => { ParseFinished }
- ListStart => { ParseList(true) }
+ ListStart => { ParseArray(true) }
ObjectStart => { ParseObject(true) }
_ => { ParseObjectComma }
};
Some(F64Value(n)) => { Ok(F64(n)) }
Some(BooleanValue(b)) => { Ok(Boolean(b)) }
Some(StringValue(ref mut s)) => {
- let mut temp = String::new();
+ let mut temp = string::String::new();
swap(s, &mut temp);
Ok(String(temp))
}
loop {
if self.token == Some(ListEnd) {
- return Ok(List(values.move_iter().collect()));
+ return Ok(List(values.into_iter().collect()));
}
match self.build_value() {
Ok(v) => values.push(v),
Err(ExpectedError("single character string".to_string(), format!("{}", s)))
}
- fn read_str(&mut self) -> DecodeResult<String> {
+ fn read_str(&mut self) -> DecodeResult<string::String> {
debug!("read_str");
expect!(self.pop(), String)
}
};
match o.pop(&"fields".to_string()) {
Some(List(l)) => {
- for field in l.move_iter().rev() {
+ for field in l.into_iter().rev() {
self.stack.push(field);
}
},
debug!("read_seq()");
let list = try!(expect!(self.pop(), List));
let len = list.len();
- for v in list.move_iter().rev() {
+ for v in list.into_iter().rev() {
self.stack.push(v);
}
f(self, len)
debug!("read_map()");
let obj = try!(expect!(self.pop(), Object));
let len = obj.len();
- for (key, value) in obj.move_iter() {
+ for (key, value) in obj.into_iter() {
self.stack.push(value);
self.stack.push(String(key));
}
fn to_json(&self) -> Json { Boolean(*self) }
}
-impl ToJson for String {
+impl ToJson for string::String {
fn to_json(&self) -> Json { String((*self).clone()) }
}
fn to_json(&self) -> Json { List(self.iter().map(|elt| elt.to_json()).collect()) }
}
-impl<A: ToJson> ToJson for TreeMap<String, A> {
+impl<A: ToJson> ToJson for TreeMap<string::String, A> {
fn to_json(&self) -> Json {
let mut d = TreeMap::new();
for (key, value) in self.iter() {
}
}
-impl<A: ToJson> ToJson for HashMap<String, A> {
+impl<A: ToJson> ToJson for HashMap<string::String, A> {
fn to_json(&self) -> Json {
let mut d = TreeMap::new();
for (key, value) in self.iter() {
extern crate test;
use self::test::Bencher;
use {Encodable, Decodable};
- use super::{Encoder, Decoder, Error, Boolean, I64, U64, F64, List, String, Null,
+ use super::{List, Encoder, Decoder, Error, Boolean, I64, U64, F64, String, Null,
PrettyEncoder, Object, Json, from_str, ParseError, ExpectedError,
MissingFieldError, UnknownVariantError, DecodeResult, DecoderError,
JsonEvent, Parser, StackElement,
F64Value, StringValue, NullValue, SyntaxError, Key, Index, Stack,
InvalidSyntax, InvalidNumber, EOFWhileParsingObject, EOFWhileParsingList,
EOFWhileParsingValue, EOFWhileParsingString, KeyMustBeAString, ExpectedColon,
- TrailingCharacters};
+ TrailingCharacters, TrailingComma};
use std::{i64, u64, f32, f64, io};
use std::collections::TreeMap;
+ use std::string;
#[deriving(Decodable, Eq, PartialEq, Show)]
struct OptionData {
#[deriving(PartialEq, Encodable, Decodable, Show)]
enum Animal {
Dog,
- Frog(String, int)
+ Frog(string::String, int)
}
#[deriving(PartialEq, Encodable, Decodable, Show)]
struct Inner {
a: (),
b: uint,
- c: Vec<String>,
+ c: Vec<string::String>,
}
#[deriving(PartialEq, Encodable, Decodable, Show)]
inner: Vec<Inner>,
}
- fn mk_object(items: &[(String, Json)]) -> Json {
+ fn mk_object(items: &[(string::String, Json)]) -> Json {
let mut d = TreeMap::new();
for item in items.iter() {
from_str(a.to_pretty_str().as_slice()).unwrap());
}
- fn with_str_writer(f: |&mut io::Writer|) -> String {
+ fn with_str_writer(f: |&mut io::Writer|) -> string::String {
use std::io::MemWriter;
use std::str;
#[test]
fn test_write_none() {
- let value: Option<String> = None;
+ let value: Option<string::String> = None;
let s = with_str_writer(|writer| {
let mut encoder = Encoder::new(writer);
value.encode(&mut encoder).unwrap();
("\"\\uAB12\"", "\uAB12")];
for &(i, o) in s.iter() {
- let v: String = super::decode(i).unwrap();
+ let v: string::String = super::decode(i).unwrap();
assert_eq!(v.as_slice(), o);
}
}
#[test]
fn test_decode_option() {
- let value: Option<String> = super::decode("null").unwrap();
+ let value: Option<string::String> = super::decode("null").unwrap();
assert_eq!(value, None);
- let value: Option<String> = super::decode("\"jodhpurs\"").unwrap();
+ let value: Option<string::String> = super::decode("\"jodhpurs\"").unwrap();
assert_eq!(value, Some("jodhpurs".to_string()));
}
fn test_decode_map() {
let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\
\"fields\":[\"Henry\", 349]}}";
- let mut map: TreeMap<String, Animal> = super::decode(s).unwrap();
+ let mut map: TreeMap<string::String, Animal> = super::decode(s).unwrap();
assert_eq!(map.pop(&"a".to_string()), Some(Dog));
assert_eq!(map.pop(&"b".to_string()), Some(Frog("Henry".to_string(), 349)));
struct DecodeStruct {
x: f64,
y: bool,
- z: String,
+ z: string::String,
w: Vec<DecodeStruct>
}
#[deriving(Decodable)]
enum DecodeEnum {
A(f64),
- B(String)
+ B(string::String)
}
fn check_err<T: Decodable<Decoder, DecoderError>>(to_parse: &'static str,
expected: DecoderError) {
}
}
}
+
#[test]
#[ignore(cfg(target_word_size = "32"))] // FIXME(#14064)
fn test_read_object_streaming() {
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(
"{}",
});
}
- fn big_json() -> String {
+ 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": \