Merge pull request #115 from erickt/fix-json
Fix serializing maps/sequences with no size hint
This commit is contained in:
commit
327990bc5f
@ -206,9 +206,11 @@ impl<W, F> ser::Serializer for Serializer<W, F>
|
|||||||
where T: ser::Serialize,
|
where T: ser::Serialize,
|
||||||
{
|
{
|
||||||
try!(self.formatter.comma(&mut self.writer, self.first));
|
try!(self.formatter.comma(&mut self.writer, self.first));
|
||||||
|
try!(value.serialize(self));
|
||||||
|
|
||||||
self.first = false;
|
self.first = false;
|
||||||
|
|
||||||
value.serialize(self)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -250,11 +252,14 @@ impl<W, F> ser::Serializer for Serializer<W, F>
|
|||||||
V: ser::Serialize,
|
V: ser::Serialize,
|
||||||
{
|
{
|
||||||
try!(self.formatter.comma(&mut self.writer, self.first));
|
try!(self.formatter.comma(&mut self.writer, self.first));
|
||||||
self.first = false;
|
|
||||||
|
|
||||||
try!(key.serialize(self));
|
try!(key.serialize(self));
|
||||||
try!(self.formatter.colon(&mut self.writer));
|
try!(self.formatter.colon(&mut self.writer));
|
||||||
value.serialize(self)
|
try!(value.serialize(self));
|
||||||
|
|
||||||
|
self.first = false;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::fmt::Debug;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use serde::de;
|
use serde::de;
|
||||||
use serde::ser;
|
use serde::ser;
|
||||||
@ -1079,3 +1080,174 @@ fn test_lookup() {
|
|||||||
assert!(obj.lookup("y").unwrap() == &Value::U64(2));
|
assert!(obj.lookup("y").unwrap() == &Value::U64(2));
|
||||||
assert!(obj.lookup("z").is_none());
|
assert!(obj.lookup("z").is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize_seq_with_no_len() {
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
struct MyVec<T>(Vec<T>);
|
||||||
|
|
||||||
|
impl<T> ser::Serialize for MyVec<T>
|
||||||
|
where T: ser::Serialize,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
|
where S: ser::Serializer,
|
||||||
|
{
|
||||||
|
serializer.visit_seq(ser::impls::SeqIteratorVisitor::new(self.0.iter(), None))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Visitor<T> {
|
||||||
|
marker: PhantomData<MyVec<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> de::Visitor for Visitor<T>
|
||||||
|
where T: de::Deserialize,
|
||||||
|
{
|
||||||
|
type Value = MyVec<T>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_unit<E>(&mut self) -> Result<MyVec<T>, E>
|
||||||
|
where E: de::Error,
|
||||||
|
{
|
||||||
|
Ok(MyVec(Vec::new()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<MyVec<T>, V::Error>
|
||||||
|
where V: de::SeqVisitor,
|
||||||
|
{
|
||||||
|
let mut values = Vec::new();
|
||||||
|
|
||||||
|
while let Some(value) = try!(visitor.visit()) {
|
||||||
|
values.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
try!(visitor.end());
|
||||||
|
|
||||||
|
Ok(MyVec(values))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> de::Deserialize for MyVec<T>
|
||||||
|
where T: de::Deserialize,
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<MyVec<T>, D::Error>
|
||||||
|
where D: de::Deserializer,
|
||||||
|
{
|
||||||
|
deserializer.visit_map(Visitor { marker: PhantomData })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
vec.push(MyVec(Vec::new()));
|
||||||
|
vec.push(MyVec(Vec::new()));
|
||||||
|
let vec: MyVec<MyVec<u32>> = MyVec(vec);
|
||||||
|
|
||||||
|
test_encode_ok(&[
|
||||||
|
(
|
||||||
|
vec.clone(),
|
||||||
|
"[[],[]]",
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let s = json::to_string_pretty(&vec).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
s,
|
||||||
|
concat!(
|
||||||
|
"[\n",
|
||||||
|
" [\n",
|
||||||
|
" ],\n",
|
||||||
|
" [\n",
|
||||||
|
" ]\n",
|
||||||
|
"]"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_serialize_map_with_no_len() {
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
struct Map<K, V>(BTreeMap<K, V>);
|
||||||
|
|
||||||
|
impl<K, V> ser::Serialize for Map<K, V>
|
||||||
|
where K: ser::Serialize + Ord,
|
||||||
|
V: ser::Serialize,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||||
|
where S: ser::Serializer,
|
||||||
|
{
|
||||||
|
serializer.visit_map(ser::impls::MapIteratorVisitor::new(self.0.iter(), None))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Visitor<K, V> {
|
||||||
|
marker: PhantomData<Map<K, V>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V> de::Visitor for Visitor<K, V>
|
||||||
|
where K: de::Deserialize + Eq + Ord,
|
||||||
|
V: de::Deserialize,
|
||||||
|
{
|
||||||
|
type Value = Map<K, V>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_unit<E>(&mut self) -> Result<Map<K, V>, E>
|
||||||
|
where E: de::Error,
|
||||||
|
{
|
||||||
|
Ok(Map(BTreeMap::new()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_map<Visitor>(&mut self, mut visitor: Visitor) -> Result<Map<K, V>, Visitor::Error>
|
||||||
|
where Visitor: de::MapVisitor,
|
||||||
|
{
|
||||||
|
let mut values = BTreeMap::new();
|
||||||
|
|
||||||
|
while let Some((key, value)) = try!(visitor.visit()) {
|
||||||
|
values.insert(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
try!(visitor.end());
|
||||||
|
|
||||||
|
Ok(Map(values))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V> de::Deserialize for Map<K, V>
|
||||||
|
where K: de::Deserialize + Eq + Ord,
|
||||||
|
V: de::Deserialize,
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> Result<Map<K, V>, D::Error>
|
||||||
|
where D: de::Deserializer,
|
||||||
|
{
|
||||||
|
deserializer.visit_map(Visitor { marker: PhantomData })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut map = BTreeMap::new();
|
||||||
|
map.insert("a", Map(BTreeMap::new()));
|
||||||
|
map.insert("b", Map(BTreeMap::new()));
|
||||||
|
let map: Map<_, Map<u32, u32>> = Map(map);
|
||||||
|
|
||||||
|
test_encode_ok(&[
|
||||||
|
(
|
||||||
|
map.clone(),
|
||||||
|
"{\"a\":{},\"b\":{}}",
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
let s = json::to_string_pretty(&map).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
s,
|
||||||
|
concat!(
|
||||||
|
"{\n",
|
||||||
|
" \"a\": {\n",
|
||||||
|
" },\n",
|
||||||
|
" \"b\": {\n",
|
||||||
|
" }\n",
|
||||||
|
"}"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user