Add support for json deserializing enums and options, clean up tests
This commit is contained in:
parent
85fd2797a6
commit
27a914cdcf
539
json.rs
539
json.rs
@ -316,9 +316,10 @@ enum JsonDeserializerState {
|
||||
JsonDeserializerValueState(Json),
|
||||
JsonDeserializerListState(vec::MoveItems<Json>),
|
||||
JsonDeserializerObjectState(treemap::MoveEntries<String, Json>),
|
||||
JsonDeserializerEndState,
|
||||
}
|
||||
|
||||
struct JsonDeserializer {
|
||||
pub struct JsonDeserializer {
|
||||
stack: Vec<JsonDeserializerState>,
|
||||
}
|
||||
|
||||
@ -380,6 +381,9 @@ impl Iterator<Result<de::Token, ParserError>> for JsonDeserializer {
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(JsonDeserializerEndState) => {
|
||||
return Some(Ok(de::End));
|
||||
}
|
||||
None => { return None; }
|
||||
}
|
||||
}
|
||||
@ -394,6 +398,131 @@ impl de::Deserializer<ParserError> for JsonDeserializer {
|
||||
fn syntax_error(&self) -> ParserError {
|
||||
SyntaxError(InvalidSyntax, 0, 0)
|
||||
}
|
||||
|
||||
// Special case treating options as a nullable value.
|
||||
#[inline]
|
||||
fn expect_option<
|
||||
U: de::Deserializable<ParserError, JsonDeserializer>
|
||||
>(&mut self, token: de::Token) -> Result<Option<U>, ParserError> {
|
||||
match token {
|
||||
de::Null => Ok(None),
|
||||
token => {
|
||||
let value: U = try!(de::Deserializable::deserialize_token(self, token));
|
||||
Ok(Some(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn expect_enum_start(&mut self, token: de::Token, _name: &str, variants: &[&str]) -> Result<uint, ParserError> {
|
||||
let variant = match token {
|
||||
de::String(variant) => {
|
||||
self.stack.push(JsonDeserializerEndState);
|
||||
variant
|
||||
}
|
||||
de::MapStart(_) => {
|
||||
let state = match self.stack.pop() {
|
||||
Some(state) => state,
|
||||
None => { fail!("state machine error, state stack empty"); }
|
||||
};
|
||||
|
||||
let mut iter = match state {
|
||||
JsonDeserializerObjectState(iter) => iter,
|
||||
_ => { fail!("state machine error, expected an object"); }
|
||||
};
|
||||
|
||||
let mut variant = None;
|
||||
let mut fields = None;
|
||||
|
||||
for (key, value) in iter {
|
||||
if key.equiv(&"variant") {
|
||||
match value {
|
||||
String(v) => { variant = Some(v); }
|
||||
value => {
|
||||
return Err(ExpectedError("String".to_string(),
|
||||
format!("{}", value)))
|
||||
}
|
||||
}
|
||||
} else if key.equiv(&"fields") {
|
||||
match value {
|
||||
List(v) => { fields = Some(v); }
|
||||
value => {
|
||||
return Err(ExpectedError("List".to_string(),
|
||||
format!("{}", value)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (variant, fields) = match (variant, fields) {
|
||||
(Some(variant), Some(fields)) => (variant, fields),
|
||||
(None, _) => {
|
||||
return Err(MissingFieldError("variant".to_string()))
|
||||
}
|
||||
(_, None) => {
|
||||
return Err(MissingFieldError("fields".to_string()))
|
||||
}
|
||||
};
|
||||
|
||||
self.stack.push(JsonDeserializerEndState);
|
||||
|
||||
for field in fields.move_iter().rev() {
|
||||
self.stack.push(JsonDeserializerValueState(field));
|
||||
}
|
||||
|
||||
variant
|
||||
}
|
||||
token => {
|
||||
return Err(ExpectedError("String or Object".to_string(),
|
||||
format!("{}", token)))
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
let name = match self.stack.pop() {
|
||||
String(s) => s,
|
||||
Object(mut object) => {
|
||||
let n = match object.pop_equiv(&"variant") {
|
||||
Some(String(s)) => s,
|
||||
Some(value) => {
|
||||
return Err(ExpectedError("String".to_string(),
|
||||
format!("{}", value)))
|
||||
}
|
||||
None => {
|
||||
return Err(MissingFieldError("variant".to_string()))
|
||||
}
|
||||
};
|
||||
match object.pop_equiv(&"fields") {
|
||||
Some(List(list)) => {
|
||||
for field in list.move_iter().rev() {
|
||||
self.stack.push(JsonDeserializerValueState(field));
|
||||
}
|
||||
},
|
||||
Some(value) => {
|
||||
return Err(ExpectedError("List".to_string(),
|
||||
format!("{}", value)))
|
||||
}
|
||||
None => {
|
||||
return Err(MissingFieldError("fields".to_string()))
|
||||
}
|
||||
}
|
||||
n
|
||||
}
|
||||
json => {
|
||||
return Err(ExpectedError("String or Object".to_string(),
|
||||
format!("{}", json)))
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
match variants.iter().position(|v| *v == variant.as_slice()) {
|
||||
Some(idx) => Ok(idx),
|
||||
None => Err(UnknownVariantError(variant)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The errors that can arise while parsing a JSON stream.
|
||||
@ -422,11 +551,15 @@ pub enum ParserError {
|
||||
/// msg, line, col
|
||||
SyntaxError(ErrorCode, uint, uint),
|
||||
IoError(io::IoErrorKind, &'static str),
|
||||
ExpectedError(String, String),
|
||||
MissingFieldError(String),
|
||||
UnknownVariantError(String),
|
||||
}
|
||||
|
||||
// Builder and Parser have the same errors.
|
||||
pub type BuilderError = ParserError;
|
||||
|
||||
/*
|
||||
#[deriving(Clone, Eq, Show)]
|
||||
pub enum DecoderError {
|
||||
ParseError(ParserError),
|
||||
@ -434,6 +567,7 @@ pub enum DecoderError {
|
||||
MissingFieldError(String),
|
||||
UnknownVariantError(String),
|
||||
}
|
||||
*/
|
||||
|
||||
/// Returns a readable error string for a given error code.
|
||||
pub fn error_str(error: ErrorCode) -> &'static str {
|
||||
@ -469,7 +603,7 @@ fn io_error_to_error(io: io::IoError) -> ParserError {
|
||||
}
|
||||
|
||||
pub type EncodeResult = io::IoResult<()>;
|
||||
pub type DecodeResult<T> = Result<T, DecoderError>;
|
||||
//pub type DecodeResult<T> = Result<T, DecoderError>;
|
||||
|
||||
fn escape_str(s: &str) -> String {
|
||||
let mut escaped = String::from_str("\"");
|
||||
@ -1754,7 +1888,7 @@ impl<T: Iterator<char>> de::Deserializer<ParserError> for Parser<T> {
|
||||
#[inline]
|
||||
fn expect_enum_start(&mut self, token: de::Token, _name: &str, variants: &[&str]) -> Result<uint, ParserError> {
|
||||
match token {
|
||||
Str(name) =>
|
||||
Str(name) =>
|
||||
|
||||
}
|
||||
|
||||
@ -2463,7 +2597,7 @@ mod tests {
|
||||
Object,
|
||||
};
|
||||
use super::{Parser, ParserError, from_iter};
|
||||
use super::{JsonDeserializer, from_json};
|
||||
use super::{JsonDeserializer, from_json, ToJson};
|
||||
use super::{
|
||||
EOFWhileParsingList,
|
||||
EOFWhileParsingObject,
|
||||
@ -2472,7 +2606,7 @@ mod tests {
|
||||
ExpectedColon,
|
||||
InvalidNumber,
|
||||
InvalidSyntax,
|
||||
KeyMustBeAString,
|
||||
KeyMustBeAString,
|
||||
TrailingCharacters,
|
||||
SyntaxError,
|
||||
};
|
||||
@ -2483,6 +2617,14 @@ mod tests {
|
||||
use std::str;
|
||||
use collections::TreeMap;
|
||||
|
||||
macro_rules! treemap {
|
||||
($($k:expr => $v:expr),*) => ({
|
||||
let mut _m = ::collections::TreeMap::new();
|
||||
$(_m.insert($k, $v);)*
|
||||
_m
|
||||
})
|
||||
}
|
||||
|
||||
#[deriving(Eq, Show)]
|
||||
enum Animal {
|
||||
Dog,
|
||||
@ -2574,6 +2716,18 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for Inner {
|
||||
fn to_json(&self) -> Json {
|
||||
Object(
|
||||
treemap!(
|
||||
"a".to_string() => self.a.to_json(),
|
||||
"b".to_string() => self.b.to_json(),
|
||||
"c".to_string() => self.c.to_json()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Eq, Show)]
|
||||
struct Outer {
|
||||
inner: Vec<Inner>,
|
||||
@ -2622,6 +2776,16 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for Outer {
|
||||
fn to_json(&self) -> Json {
|
||||
Object(
|
||||
treemap!(
|
||||
"inner".to_string() => self.inner.to_json()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
fn mk_object(items: &[(String, Json)]) -> Json {
|
||||
let mut d = box TreeMap::new();
|
||||
@ -2874,59 +3038,61 @@ mod tests {
|
||||
}
|
||||
*/
|
||||
|
||||
fn test_parser_err<
|
||||
fn test_parse_err<
|
||||
'a,
|
||||
T: Eq + Show + de::Deserializable<ParserError, Parser<str::Chars<'a>>>
|
||||
>(errors: &[(&'a str, ParserError)]) {
|
||||
for &(s, err) in errors.iter() {
|
||||
for &(s, ref err) in errors.iter() {
|
||||
let v: Result<T, ParserError> = from_iter(s.chars());
|
||||
assert_eq!(v, Err(err));
|
||||
assert_eq!(v.unwrap_err(), *err);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_parser_ok<
|
||||
fn test_parse_ok<
|
||||
'a,
|
||||
T: Eq + Show + de::Deserializable<ParserError, Parser<str::Chars<'a>>>
|
||||
T: Eq + Show + ToJson + de::Deserializable<ParserError, Parser<str::Chars<'a>>>
|
||||
>(errors: &[(&'a str, T)]) {
|
||||
for &(s, ref value) in errors.iter() {
|
||||
let v: T = from_iter(s.chars()).unwrap();
|
||||
assert_eq!(v, *value);
|
||||
|
||||
let v: Json = from_iter(s.chars()).unwrap();
|
||||
assert_eq!(v, value.to_json());
|
||||
}
|
||||
}
|
||||
|
||||
fn test_json_deserializer_ok<
|
||||
T: Eq + Show + de::Deserializable<ParserError, JsonDeserializer>
|
||||
>(errors: &[(Json, T)]) {
|
||||
for &(ref json, ref value) in errors.iter() {
|
||||
let v: T = from_json(json.clone()).unwrap();
|
||||
fn test_json_deserialize_ok<
|
||||
T: Eq + Show + ToJson + de::Deserializable<ParserError, JsonDeserializer>
|
||||
>(errors: &[T]) {
|
||||
for value in errors.iter() {
|
||||
let v: T = from_json(value.to_json()).unwrap();
|
||||
assert_eq!(v, *value);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_null() {
|
||||
test_parser_err::<()>([
|
||||
fn test_parse_null() {
|
||||
test_parse_err::<()>([
|
||||
("n", SyntaxError(InvalidSyntax, 1, 2)),
|
||||
("nul", SyntaxError(InvalidSyntax, 1, 4)),
|
||||
("nulla", SyntaxError(TrailingCharacters, 1, 5)),
|
||||
]);
|
||||
|
||||
test_parser_ok([
|
||||
test_parse_ok([
|
||||
("null", ()),
|
||||
]);
|
||||
|
||||
test_parser_ok([
|
||||
("null", Null),
|
||||
]);
|
||||
|
||||
test_json_deserializer_ok([
|
||||
(Null, ()),
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_bool() {
|
||||
test_parser_err::<bool>([
|
||||
fn test_json_deserialize_null() {
|
||||
test_json_deserialize_ok([
|
||||
(),
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_bool() {
|
||||
test_parse_err::<bool>([
|
||||
("t", SyntaxError(InvalidSyntax, 1, 2)),
|
||||
("truz", SyntaxError(InvalidSyntax, 1, 4)),
|
||||
("f", SyntaxError(InvalidSyntax, 1, 2)),
|
||||
@ -2935,20 +3101,17 @@ mod tests {
|
||||
("falsea", SyntaxError(TrailingCharacters, 1, 6)),
|
||||
]);
|
||||
|
||||
test_parser_ok([
|
||||
test_parse_ok([
|
||||
("true", true),
|
||||
("false", false),
|
||||
]);
|
||||
}
|
||||
|
||||
test_parser_ok([
|
||||
("true", Boolean(true)),
|
||||
("false", Boolean(false)),
|
||||
]);
|
||||
|
||||
|
||||
test_json_deserializer_ok([
|
||||
(Boolean(true), true),
|
||||
(Boolean(false), false),
|
||||
#[test]
|
||||
fn test_json_deserialize_bool() {
|
||||
test_json_deserialize_ok([
|
||||
true,
|
||||
false,
|
||||
]);
|
||||
}
|
||||
|
||||
@ -2975,8 +3138,8 @@ mod tests {
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn test_decode_numbers() {
|
||||
let errors = [
|
||||
fn test_parse_numbers() {
|
||||
test_parse_err::<f64>([
|
||||
("+", SyntaxError(InvalidSyntax, 1, 1)),
|
||||
(".", SyntaxError(InvalidSyntax, 1, 1)),
|
||||
("-", SyntaxError(InvalidNumber, 1, 2)),
|
||||
@ -2985,14 +3148,9 @@ mod tests {
|
||||
("1e", SyntaxError(InvalidNumber, 1, 3)),
|
||||
("1e+", SyntaxError(InvalidNumber, 1, 4)),
|
||||
("1a", SyntaxError(TrailingCharacters, 1, 2)),
|
||||
];
|
||||
]);
|
||||
|
||||
for &(s, err) in errors.iter() {
|
||||
let v: Result<f64, ParserError> = from_iter(s.chars());
|
||||
assert_eq!(v, Err(err));
|
||||
}
|
||||
|
||||
let values = [
|
||||
test_parse_ok([
|
||||
("3", 3.0),
|
||||
("3.1", 3.1),
|
||||
("-1.2", -1.2),
|
||||
@ -3000,12 +3158,20 @@ mod tests {
|
||||
("0.4e5", 0.4e5),
|
||||
("0.4e15", 0.4e15),
|
||||
("0.4e-01", 0.4e-01),
|
||||
];
|
||||
]);
|
||||
}
|
||||
|
||||
for &(s, value) in values.iter() {
|
||||
let v: Result<f64, ParserError> = from_iter(s.chars());
|
||||
assert_eq!(v, Ok(value));
|
||||
}
|
||||
#[test]
|
||||
fn test_json_deserialize_numbers() {
|
||||
test_json_deserialize_ok([
|
||||
3.0,
|
||||
3.1,
|
||||
-1.2,
|
||||
0.4,
|
||||
0.4e5,
|
||||
0.4e15,
|
||||
0.4e-01,
|
||||
]);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3028,33 +3194,39 @@ mod tests {
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn test_decode_str() {
|
||||
let errors = [
|
||||
fn test_parse_str() {
|
||||
test_parse_err::<String>([
|
||||
("\"", SyntaxError(EOFWhileParsingString, 1, 2)),
|
||||
("\"lol", SyntaxError(EOFWhileParsingString, 1, 5)),
|
||||
("\"lol\"a", SyntaxError(TrailingCharacters, 1, 6)),
|
||||
];
|
||||
]);
|
||||
|
||||
for &(s, err) in errors.iter() {
|
||||
let v: Result<String, ParserError> = from_iter(s.chars());
|
||||
assert_eq!(v, Err(err));
|
||||
}
|
||||
test_parse_ok([
|
||||
("\"\"", "".to_string()),
|
||||
("\"foo\"", "foo".to_string()),
|
||||
("\"\\\"\"", "\"".to_string()),
|
||||
("\"\\b\"", "\x08".to_string()),
|
||||
("\"\\n\"", "\n".to_string()),
|
||||
("\"\\r\"", "\r".to_string()),
|
||||
("\"\\t\"", "\t".to_string()),
|
||||
("\"\\u12ab\"", "\u12ab".to_string()),
|
||||
("\"\\uAB12\"", "\uAB12".to_string()),
|
||||
]);
|
||||
}
|
||||
|
||||
let s = [("\"\"", ""),
|
||||
("\"foo\"", "foo"),
|
||||
("\"\\\"\"", "\""),
|
||||
("\"\\b\"", "\x08"),
|
||||
("\"\\n\"", "\n"),
|
||||
("\"\\r\"", "\r"),
|
||||
("\"\\t\"", "\t"),
|
||||
("\"\\u12ab\"", "\u12ab"),
|
||||
("\"\\uAB12\"", "\uAB12")];
|
||||
|
||||
for &(i, o) in s.iter() {
|
||||
let mut parser = Parser::new(i.chars());
|
||||
let v: String = de::Deserializable::deserialize(&mut parser).unwrap();
|
||||
assert_eq!(v.as_slice(), o);
|
||||
}
|
||||
#[test]
|
||||
fn test_json_deserialize_str() {
|
||||
test_json_deserialize_ok([
|
||||
"".to_string(),
|
||||
"foo".to_string(),
|
||||
"\"".to_string(),
|
||||
"\x08".to_string(),
|
||||
"\n".to_string(),
|
||||
"\r".to_string(),
|
||||
"\t".to_string(),
|
||||
"\u12ab".to_string(),
|
||||
"\uAB12".to_string(),
|
||||
]);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3081,44 +3253,56 @@ mod tests {
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn test_decode_list() {
|
||||
let errors = [
|
||||
("[", SyntaxError(EOFWhileParsingValue, 1, 2)),
|
||||
("[ ", SyntaxError(EOFWhileParsingValue, 1, 3)),
|
||||
("[1", SyntaxError(EOFWhileParsingList, 1, 3)),
|
||||
("[1,", SyntaxError(EOFWhileParsingValue, 1, 4)),
|
||||
("[1,]", SyntaxError(InvalidSyntax, 1, 4)),
|
||||
("[1 2]", SyntaxError(InvalidSyntax, 1, 4)),
|
||||
fn test_parse_list() {
|
||||
test_parse_err::<Vec<f64>>([
|
||||
("[", SyntaxError(EOFWhileParsingValue, 1, 2)),
|
||||
("[ ", SyntaxError(EOFWhileParsingValue, 1, 3)),
|
||||
("[1", SyntaxError(EOFWhileParsingList, 1, 3)),
|
||||
("[1,", SyntaxError(EOFWhileParsingValue, 1, 4)),
|
||||
("[1,]", SyntaxError(InvalidSyntax, 1, 4)),
|
||||
("[1 2]", SyntaxError(InvalidSyntax, 1, 4)),
|
||||
("[]a", SyntaxError(TrailingCharacters, 1, 3)),
|
||||
];
|
||||
for &(s, err) in errors.iter() {
|
||||
let v: Result<Vec<f64>, ParserError> = from_iter(s.chars());
|
||||
assert_eq!(v, Err(err));
|
||||
}
|
||||
]);
|
||||
|
||||
let v: Vec<()> = from_iter("[]".chars()).unwrap();
|
||||
assert_eq!(v, vec![]);
|
||||
test_parse_ok([
|
||||
("[]", vec!()),
|
||||
("[ ]", vec!()),
|
||||
("[null]", vec!(())),
|
||||
("[ null ]", vec!(())),
|
||||
]);
|
||||
|
||||
let v: Vec<()> = from_iter("[ ]".chars()).unwrap();
|
||||
assert_eq!(v, vec![]);
|
||||
test_parse_ok([
|
||||
("[true]", vec!(true)),
|
||||
]);
|
||||
|
||||
let v: Vec<()> = from_iter("[null]".chars()).unwrap();
|
||||
assert_eq!(v, vec![()]);
|
||||
test_parse_ok([
|
||||
("[3,1]", vec!(3, 1)),
|
||||
("[ 3 , 1 ]", vec!(3, 1)),
|
||||
]);
|
||||
|
||||
let v: Vec<()> = from_iter("[ null ]".chars()).unwrap();
|
||||
assert_eq!(v, vec![()]);
|
||||
test_parse_ok([
|
||||
("[[3], [1, 2]]", vec!(vec!(3), vec!(1, 2))),
|
||||
]);
|
||||
}
|
||||
|
||||
let v: Vec<bool> = from_iter("[true]".chars()).unwrap();
|
||||
assert_eq!(v, vec![true]);
|
||||
#[test]
|
||||
fn test_json_deserialize_list() {
|
||||
test_json_deserialize_ok([
|
||||
vec!(),
|
||||
vec!(()),
|
||||
]);
|
||||
|
||||
let v: Vec<int> = from_iter("[3,1]".chars()).unwrap();
|
||||
assert_eq!(v, vec![3, 1]);
|
||||
test_json_deserialize_ok([
|
||||
vec!(true),
|
||||
]);
|
||||
|
||||
let v: Vec<int> = from_iter("[ 3 , 1 ]".chars()).unwrap();
|
||||
assert_eq!(v, vec![3, 1]);
|
||||
test_json_deserialize_ok([
|
||||
vec!(3, 1),
|
||||
]);
|
||||
|
||||
let v: Vec<Vec<uint>> = from_iter("[[3], [1, 2]]".chars()).unwrap();
|
||||
assert_eq!(v, vec![vec![3], vec![1, 2]]);
|
||||
test_json_deserialize_ok([
|
||||
vec!(vec!(3), vec!(1, 2)),
|
||||
]);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3179,8 +3363,8 @@ mod tests {
|
||||
*/
|
||||
|
||||
#[test]
|
||||
fn test_decode_object() {
|
||||
let errors = [
|
||||
fn test_parse_object() {
|
||||
test_parse_err::<TreeMap<String, int>>([
|
||||
("{", SyntaxError(EOFWhileParsingString, 1, 2)),
|
||||
("{ ", SyntaxError(EOFWhileParsingString, 1, 3)),
|
||||
("{1", SyntaxError(KeyMustBeAString, 1, 2)),
|
||||
@ -3193,82 +3377,101 @@ mod tests {
|
||||
("{\"a\":1 1", SyntaxError(InvalidSyntax, 1, 8)),
|
||||
("{\"a\":1,", SyntaxError(EOFWhileParsingString, 1, 8)),
|
||||
("{}a", SyntaxError(TrailingCharacters, 1, 3)),
|
||||
];
|
||||
]);
|
||||
|
||||
for &(s, err) in errors.iter() {
|
||||
let v: Result<TreeMap<String, int>, ParserError> = from_iter(s.chars());
|
||||
assert_eq!(v, Err(err));
|
||||
}
|
||||
test_parse_ok([
|
||||
("{}", treemap!()),
|
||||
("{ }", treemap!()),
|
||||
(
|
||||
"{\"a\":3}",
|
||||
treemap!("a".to_string() => 3)
|
||||
),
|
||||
(
|
||||
"{ \"a\" : 3 }",
|
||||
treemap!("a".to_string() => 3)
|
||||
),
|
||||
(
|
||||
"{\"a\":3,\"b\":4}",
|
||||
treemap!("a".to_string() => 3, "b".to_string() => 4)
|
||||
),
|
||||
(
|
||||
"{ \"a\" : 3 , \"b\" : 4 }",
|
||||
treemap!("a".to_string() => 3, "b".to_string() => 4),
|
||||
),
|
||||
]);
|
||||
|
||||
let v: TreeMap<String, int> = from_iter("{}".chars()).unwrap();
|
||||
let m = TreeMap::new();
|
||||
assert!(v == m);
|
||||
|
||||
let v: TreeMap<String, int> = from_iter("{ }".chars()).unwrap();
|
||||
let m = TreeMap::new();
|
||||
assert!(v == m);
|
||||
|
||||
let v: TreeMap<String, int> = from_iter("{\"a\":3}".chars()).unwrap();
|
||||
let mut m = TreeMap::new();
|
||||
m.insert("a".to_str(), 3);
|
||||
assert!(v == m);
|
||||
|
||||
let v: TreeMap<String, int> = from_iter("{\"a\" :3}".chars()).unwrap();
|
||||
let mut m = TreeMap::new();
|
||||
m.insert("a".to_str(), 3);
|
||||
assert!(v == m);
|
||||
|
||||
let v: TreeMap<String, int> = from_iter("{\"a\" : 3}".chars()).unwrap();
|
||||
let mut m = TreeMap::new();
|
||||
m.insert("a".to_str(), 3);
|
||||
assert!(v == m);
|
||||
|
||||
let v: TreeMap<String, int> = from_iter("{\"a\": 3, \"b\": 4}".chars()).unwrap();
|
||||
let mut m = TreeMap::new();
|
||||
m.insert("a".to_str(), 3);
|
||||
m.insert("b".to_str(), 4);
|
||||
assert!(v == m);
|
||||
|
||||
let v: TreeMap<String, int> = from_iter("{ \"a\": 3, \"b\": 4 }".chars()).unwrap();
|
||||
let mut m = TreeMap::new();
|
||||
m.insert("a".to_str(), 3);
|
||||
m.insert("b".to_str(), 4);
|
||||
assert!(v == m);
|
||||
|
||||
let v: TreeMap<String, TreeMap<String, int>> = from_iter("{\"a\": {\"b\": 3, \"c\": 4}}".chars()).unwrap();
|
||||
let mut mm = TreeMap::new();
|
||||
mm.insert("b".to_str(), 3);
|
||||
mm.insert("c".to_str(), 4);
|
||||
let mut m = TreeMap::new();
|
||||
m.insert("a".to_str(), mm);
|
||||
assert!(v == m);
|
||||
test_parse_ok([
|
||||
(
|
||||
"{\"a\": {\"b\": 3, \"c\": 4}}",
|
||||
treemap!("a".to_string() => treemap!("b".to_string() => 3, "c".to_string() => 4)),
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_struct() {
|
||||
let s = "{
|
||||
\"inner\": [
|
||||
{ \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] }
|
||||
]
|
||||
}";
|
||||
let v: Outer = from_iter(s.chars()).unwrap();
|
||||
assert_eq!(
|
||||
v,
|
||||
fn test_json_deserialize_object() {
|
||||
test_json_deserialize_ok([
|
||||
treemap!(),
|
||||
treemap!("a".to_string() => 3),
|
||||
treemap!("a".to_string() => 3, "b".to_string() => 4),
|
||||
]);
|
||||
|
||||
test_json_deserialize_ok([
|
||||
treemap!("a".to_string() => treemap!("b".to_string() => 3, "c".to_string() => 4)),
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_struct() {
|
||||
test_parse_ok([
|
||||
(
|
||||
"{
|
||||
\"inner\": []
|
||||
}",
|
||||
Outer {
|
||||
inner: vec![]
|
||||
},
|
||||
),
|
||||
(
|
||||
"{
|
||||
\"inner\": [
|
||||
{ \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] }
|
||||
]
|
||||
}",
|
||||
Outer {
|
||||
inner: vec![
|
||||
Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] }
|
||||
]
|
||||
},
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_deserialize_struct() {
|
||||
test_json_deserialize_ok([
|
||||
Outer {
|
||||
inner: vec![
|
||||
Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] }
|
||||
]
|
||||
}
|
||||
);
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode_option() {
|
||||
let value: Result<Option<String>, ParserError> = from_iter("null".chars());
|
||||
assert_eq!(value, Ok(None));
|
||||
fn test_parse_option() {
|
||||
test_parse_ok([
|
||||
("null", None),
|
||||
("\"jodhpurs\"", Some("jodhpurs".to_string())),
|
||||
]);
|
||||
}
|
||||
|
||||
let value: Result<Option<String>, ParserError> = from_iter("\"jodhpurs\"".chars());
|
||||
assert_eq!(value, Ok(Some("jodhpurs".to_string())));
|
||||
#[test]
|
||||
fn test_json_deserialize_option() {
|
||||
test_json_deserialize_ok([
|
||||
None,
|
||||
Some("jodhpurs".to_string()),
|
||||
]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user