Add json value deserializer

This commit is contained in:
Erick Tryzelaar 2015-03-04 09:12:32 -08:00
parent cd3cad8ef5
commit e9f356755f
3 changed files with 124 additions and 125 deletions

View File

@ -518,10 +518,18 @@ impl<T> Deserialize for Option<T> where T: Deserialize {
///////////////////////////////////////////////////////////////////////////////
struct VecVisitor<T> {
pub struct VecVisitor<T> {
marker: PhantomData<T>,
}
impl<T> VecVisitor<T> {
pub fn new() -> Self {
VecVisitor {
marker: PhantomData,
}
}
}
impl<T> Visitor for VecVisitor<T> where T: Deserialize {
type Value = Vec<T>;
@ -544,7 +552,7 @@ impl<T: Deserialize> Deserialize for Vec<T> {
fn deserialize<D>(deserializer: &mut D) -> Result<Vec<T>, D::Error>
where D: Deserializer,
{
deserializer.visit(VecVisitor { marker: PhantomData })
deserializer.visit(VecVisitor::new())
}
}
@ -612,10 +620,19 @@ tuple_impls! {
///////////////////////////////////////////////////////////////////////////////
struct HashMapVisitor<K, V> {
pub struct HashMapVisitor<K, V> {
marker: PhantomData<HashMap<K, V>>,
}
impl<K, V> HashMapVisitor<K, V> {
#[inline]
pub fn new() -> Self {
HashMapVisitor {
marker: PhantomData,
}
}
}
impl<K, V> Visitor for HashMapVisitor<K, V>
where K: Deserialize + Eq + Hash,
V: Deserialize,
@ -644,16 +661,25 @@ impl<K, V> Deserialize for HashMap<K, V>
fn deserialize<D>(deserializer: &mut D) -> Result<HashMap<K, V>, D::Error>
where D: Deserializer,
{
deserializer.visit(HashMapVisitor { marker: PhantomData })
deserializer.visit(HashMapVisitor::new())
}
}
///////////////////////////////////////////////////////////////////////////////
struct BTreeMapVisitor<K, V> {
pub struct BTreeMapVisitor<K, V> {
marker: PhantomData<BTreeMap<K, V>>,
}
impl<K, V> BTreeMapVisitor<K, V> {
#[inline]
pub fn new() -> Self {
BTreeMapVisitor {
marker: PhantomData,
}
}
}
impl<K, V> Visitor for BTreeMapVisitor<K, V>
where K: Deserialize + Ord,
V: Deserialize
@ -681,6 +707,6 @@ impl<
fn deserialize<D>(deserializer: &mut D) -> Result<BTreeMap<K, V>, D::Error>
where D: Deserializer,
{
deserializer.visit(BTreeMapVisitor { marker: PhantomData })
deserializer.visit(BTreeMapVisitor::new())
}
}

View File

@ -36,6 +36,69 @@ impl ser::Serialize for Value {
}
}
impl de::Deserialize for Value {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<Value, D::Error>
where D: de::Deserializer,
{
struct ValueVisitor;
impl de::Visitor for ValueVisitor {
type Value = Value;
#[inline]
fn visit_unit<E>(&mut self) -> Result<Value, E> {
Ok(Value::Null)
}
#[inline]
fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
Ok(Value::Bool(value))
}
#[inline]
fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
Ok(Value::I64(value))
}
#[inline]
fn visit_f64<E>(&mut self, value: f64) -> Result<Value, E> {
Ok(Value::F64(value))
}
#[inline]
fn visit_str<E>(&mut self, value: &str) -> Result<Value, E>
where E: de::Error,
{
self.visit_string(value.to_string())
}
#[inline]
fn visit_string<E>(&mut self, value: String) -> Result<Value, E> {
Ok(Value::String(value))
}
#[inline]
fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
where V: de::SeqVisitor,
{
let values = try!(de::VecVisitor::new().visit_seq(visitor));
Ok(Value::Array(values))
}
#[inline]
fn visit_map<V>(&mut self, visitor: V) -> Result<Value, V::Error>
where V: de::MapVisitor,
{
let values = try!(de::BTreeMapVisitor::new().visit_map(visitor));
Ok(Value::Object(values))
}
}
deserializer.visit(ValueVisitor)
}
}
struct WriterFormatter<'a, 'b: 'a> {
inner: &'a mut fmt::Formatter<'b>,
}

View File

@ -198,12 +198,12 @@ fn test_write_list() {
(long_test_list, "[false,null,[\"foo\\nbar\",3.5]]"),
]);
/*
let long_test_list = Value::Array(vec![
Value::Bool(false),
Value::Null,
Value::Array(vec![Value::String("foo\nbar".to_string()), Value::F64(3.5)])]);
/*
test_pretty_encode_ok(&[
(
long_test_list,
@ -425,7 +425,6 @@ fn test_write_enum() {
*/
}
/*
#[test]
fn test_write_option() {
test_encode_ok(&[
@ -460,39 +459,33 @@ fn test_write_option() {
}
// FIXME (#5527): these could be merged once UFCS is finished.
fn test_parse_err<
'a,
T: Debug + de::Deserialize
>(errors: &[(&'a str, Error)]) {
fn test_parse_err<'a, T>(errors: &[(&'a str, Error)])
where T: Debug + de::Deserialize,
{
for &(s, ref err) in errors {
let v: Result<T, Error> = from_str(s);
assert_eq!(v.unwrap_err(), *err);
}
}
fn test_parse_ok<
'a,
T: PartialEq + Debug + de::Deserialize
>(errors: &[(&'a str, T)]) {
fn test_parse_ok<'a, T>(errors: &[(&'a str, T)])
where T: PartialEq + Debug + ser::Serialize + de::Deserialize,
{
for &(s, ref value) in errors {
let v: T = from_str(s).unwrap();
assert_eq!(v, *value);
let v: Value = from_str(s).unwrap();
assert_eq!(v, value.to_json());
}
}
// Make sure we can deserialize into a `Value`.
let json_value: Value = from_str(s).unwrap();
assert_eq!(json_value, to_value(&value));
fn test_json_deserialize_ok<
T: PartialEq + Debug + de::Deserialize
>(errors: &[T]) {
for value in errors {
let v: T = from_value(value.to_json()).unwrap();
// Make sure we can deserialize from a `Value`.
let v: T = from_value(json_value.clone()).unwrap();
assert_eq!(v, *value);
// Make sure we can round trip back to `Json`.
let v: Value = from_value(value.to_json()).unwrap();
assert_eq!(v, value.to_json());
// Make sure we can round trip back to `Value`.
let json_value2: Value = from_value(json_value.clone()).unwrap();
assert_eq!(json_value, json_value2);
}
}
@ -509,13 +502,6 @@ fn test_parse_null() {
]);
}
#[test]
fn test_json_deserialize_null() {
test_json_deserialize_ok(&[
(),
]);
}
#[test]
fn test_parse_bool() {
test_parse_err::<bool>(&[
@ -533,14 +519,6 @@ fn test_parse_bool() {
]);
}
#[test]
fn test_json_deserialize_bool() {
test_json_deserialize_ok(&[
true,
false,
]);
}
#[test]
fn test_parse_number_errors() {
test_parse_err::<f64>(&[
@ -558,7 +536,7 @@ fn test_parse_number_errors() {
#[test]
fn test_parse_i64() {
test_parse_ok(&[
("3", 3i64),
("3", 3),
("-2", -2),
("-1234", -1234),
]);
@ -578,26 +556,16 @@ fn test_parse_f64() {
}
#[test]
fn test_json_deserialize_numbers() {
test_json_deserialize_ok(&[
3.0f64,
3.1,
-1.2,
0.4,
0.4e5,
0.4e15,
0.4e-01,
]);
}
#[test]
fn test_parse_string() {
fn test_parse_string_errors() {
test_parse_err::<string::String>(&[
("\"", SyntaxError(EOFWhileParsingString, 1, 2)),
("\"lol", SyntaxError(EOFWhileParsingString, 1, 5)),
("\"lol\"a", SyntaxError(TrailingCharacters, 1, 6)),
]);
}
#[test]
fn test_parse_string() {
test_parse_ok(&[
("\"\"", "".to_string()),
("\"foo\"", "foo".to_string()),
@ -611,21 +579,6 @@ fn test_parse_string() {
]);
}
#[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(),
"\u{12ab}".to_string(),
"\u{AB12}".to_string(),
]);
}
#[test]
fn test_parse_list() {
test_parse_err::<Vec<f64>>(&[
@ -655,42 +608,22 @@ fn test_parse_list() {
]);
test_parse_ok(&[
("[[3], [1, 2]]", vec!(vec!(3is), vec!(1, 2))),
("[[3], [1, 2]]", vec!(vec!(3), vec!(1, 2))),
]);
let v: () = from_str("[]").unwrap();
assert_eq!(v, ());
test_parse_ok(&[
("[1, 2, 3]", (1us, 2us, 3us)),
]);
}
#[test]
fn test_json_deserialize_list() {
test_json_deserialize_ok(&[
vec!(),
vec!(()),
]);
test_json_deserialize_ok(&[
vec!(true),
]);
test_json_deserialize_ok(&[
vec!(3, 1),
]);
test_json_deserialize_ok(&[
vec!(vec!(3is), vec!(1, 2)),
("[1, 2, 3]", (1, 2, 3)),
]);
}
#[test]
fn test_parse_object() {
test_parse_err::<BTreeMap<string::String, isize>>(&[
("{", SyntaxError(EOFWhileParsingString, 1, 2)),
("{ ", SyntaxError(EOFWhileParsingString, 1, 3)),
("{", SyntaxError(EOFWhileParsingValue, 1, 2)),
("{ ", SyntaxError(EOFWhileParsingValue, 1, 3)),
("{1", SyntaxError(KeyMustBeAString, 1, 2)),
("{ \"a\"", SyntaxError(EOFWhileParsingObject, 1, 6)),
("{\"a\"", SyntaxError(EOFWhileParsingObject, 1, 5)),
@ -699,7 +632,7 @@ fn test_parse_object() {
("{\"a\":", SyntaxError(EOFWhileParsingValue, 1, 6)),
("{\"a\":1", SyntaxError(EOFWhileParsingObject, 1, 7)),
("{\"a\":1 1", SyntaxError(ExpectedObjectCommaOrEnd, 1, 8)),
("{\"a\":1,", SyntaxError(EOFWhileParsingString, 1, 8)),
("{\"a\":1,", SyntaxError(EOFWhileParsingValue, 1, 8)),
("{}a", SyntaxError(TrailingCharacters, 1, 3)),
]);
@ -708,11 +641,11 @@ fn test_parse_object() {
("{ }", treemap!()),
(
"{\"a\":3}",
treemap!("a".to_string() => 3is)
treemap!("a".to_string() => 3)
),
(
"{ \"a\" : 3 }",
treemap!("a".to_string() => 3is)
treemap!("a".to_string() => 3)
),
(
"{\"a\":3,\"b\":4}",
@ -727,24 +660,11 @@ fn test_parse_object() {
test_parse_ok(&[
(
"{\"a\": {\"b\": 3, \"c\": 4}}",
treemap!("a".to_string() => treemap!("b".to_string() => 3, "c".to_string() => 4is)),
treemap!("a".to_string() => treemap!("b".to_string() => 3, "c".to_string() => 4)),
),
]);
}
#[test]
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(&[
@ -771,17 +691,7 @@ fn test_parse_struct() {
]);
}
#[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_parse_option() {
test_parse_ok(&[