diff --git a/src/schema/document/de.rs b/src/schema/document/de.rs index 657ad1430b..aab2b070ef 100644 --- a/src/schema/document/de.rs +++ b/src/schema/document/de.rs @@ -960,13 +960,19 @@ mod tests { "my-third-key".to_string(), crate::schema::OwnedValue::F64(123.0), ); - assert_eq!(value, crate::schema::OwnedValue::Object(expected_object)); + assert_eq!( + value, + crate::schema::OwnedValue::Object(expected_object.into_iter().collect()) + ); let object = serde_json::Map::new(); let result = serialize_value(ReferenceValue::Object(JsonObjectIter(object.iter()))); let value = deserialize_value(result); let expected_object = BTreeMap::new(); - assert_eq!(value, crate::schema::OwnedValue::Object(expected_object)); + assert_eq!( + value, + crate::schema::OwnedValue::Object(expected_object.into_iter().collect()) + ); let mut object = serde_json::Map::new(); object.insert("my-first-key".into(), serde_json::Value::Null); @@ -978,7 +984,10 @@ mod tests { expected_object.insert("my-first-key".to_string(), crate::schema::OwnedValue::Null); expected_object.insert("my-second-key".to_string(), crate::schema::OwnedValue::Null); expected_object.insert("my-third-key".to_string(), crate::schema::OwnedValue::Null); - assert_eq!(value, crate::schema::OwnedValue::Object(expected_object)); + assert_eq!( + value, + crate::schema::OwnedValue::Object(expected_object.into_iter().collect()) + ); } #[test] @@ -1055,7 +1064,10 @@ mod tests { .collect(), ), ); - assert_eq!(value, crate::schema::OwnedValue::Object(expected_object)); + assert_eq!( + value, + crate::schema::OwnedValue::Object(expected_object.into_iter().collect()) + ); // Some more extreme nesting that might behave weirdly let mut object = serde_json::Map::new(); @@ -1077,6 +1089,9 @@ mod tests { OwnedValue::Array(vec![OwnedValue::Null]), ])]), ); - assert_eq!(value, OwnedValue::Object(expected_object)); + assert_eq!( + value, + OwnedValue::Object(expected_object.into_iter().collect()) + ); } } diff --git a/src/schema/document/owned_value.rs b/src/schema/document/owned_value.rs index 3dc7a1f67d..926874ce98 100644 --- a/src/schema/document/owned_value.rs +++ b/src/schema/document/owned_value.rs @@ -1,4 +1,4 @@ -use std::collections::{btree_map, BTreeMap}; +use std::collections::BTreeMap; use std::fmt; use std::net::Ipv6Addr; @@ -45,7 +45,7 @@ pub enum OwnedValue { /// A set of values. Array(Vec), /// Dynamic object value. - Object(BTreeMap), + Object(Vec<(String, Self)>), /// IpV6 Address. Internally there is no IpV4, it needs to be converted to `Ipv6Addr`. IpAddr(Ipv6Addr), } @@ -148,10 +148,10 @@ impl ValueDeserialize for OwnedValue { fn visit_object<'de, A>(&self, mut access: A) -> Result where A: ObjectAccess<'de> { - let mut elements = BTreeMap::new(); + let mut elements = Vec::with_capacity(access.size_hint()); while let Some((key, value)) = access.next_entry()? { - elements.insert(key, value); + elements.push((key, value)); } Ok(OwnedValue::Object(elements)) @@ -167,6 +167,7 @@ impl Eq for OwnedValue {} impl serde::Serialize for OwnedValue { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { + use serde::ser::SerializeMap; match *self { OwnedValue::Null => serializer.serialize_unit(), OwnedValue::Str(ref v) => serializer.serialize_str(v), @@ -180,7 +181,13 @@ impl serde::Serialize for OwnedValue { } OwnedValue::Facet(ref facet) => facet.serialize(serializer), OwnedValue::Bytes(ref bytes) => serializer.serialize_str(&BASE64.encode(bytes)), - OwnedValue::Object(ref obj) => obj.serialize(serializer), + OwnedValue::Object(ref obj) => { + let mut map = serializer.serialize_map(Some(obj.len()))?; + for &(ref k, ref v) in obj { + map.serialize_entry(k, v)?; + } + map.end() + } OwnedValue::IpAddr(ref ip_v6) => { // Ensure IpV4 addresses get serialized as IpV4, but excluding IpV6 loopback. if let Some(ip_v4) = ip_v6.to_ipv4_mapped() { @@ -248,12 +255,10 @@ impl<'de> serde::Deserialize<'de> for OwnedValue { fn visit_map(self, mut map: A) -> Result where A: MapAccess<'de> { - let mut object = BTreeMap::new(); - + let mut object = map.size_hint().map(Vec::with_capacity).unwrap_or_default(); while let Some((key, value)) = map.next_entry()? { - object.insert(key, value); + object.push((key, value)); } - Ok(OwnedValue::Object(object)) } } @@ -363,7 +368,8 @@ impl From for OwnedValue { impl From> for OwnedValue { fn from(object: BTreeMap) -> OwnedValue { - OwnedValue::Object(object) + let key_values = object.into_iter().collect(); + OwnedValue::Object(key_values) } } @@ -417,18 +423,16 @@ impl From for OwnedValue { impl From> for OwnedValue { fn from(map: serde_json::Map) -> Self { - let mut object = BTreeMap::new(); - - for (key, value) in map { - object.insert(key, OwnedValue::from(value)); - } - + let object: Vec<(String, OwnedValue)> = map + .into_iter() + .map(|(key, value)| (key, OwnedValue::from(value))) + .collect(); OwnedValue::Object(object) } } /// A wrapper type for iterating over a serde_json object producing reference values. -pub struct ObjectMapIter<'a>(btree_map::Iter<'a, String, OwnedValue>); +pub struct ObjectMapIter<'a>(std::slice::Iter<'a, (String, OwnedValue)>); impl<'a> Iterator for ObjectMapIter<'a> { type Item = (&'a str, &'a OwnedValue);