Skip to content

Commit

Permalink
Owned value relying on Vec instead of BTreeMap (#2364)
Browse files Browse the repository at this point in the history
* Owned value relying on Vec instead of BTreeMap

* fmt

* fix build

* fix serialization

---------

Co-authored-by: Pascal Seitz <[email protected]>
  • Loading branch information
fulmicoton and PSeitz authored Apr 22, 2024
1 parent 0e9fced commit 8861366
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 22 deletions.
25 changes: 20 additions & 5 deletions src/schema/document/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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]
Expand Down Expand Up @@ -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();
Expand All @@ -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())
);
}
}
38 changes: 21 additions & 17 deletions src/schema/document/owned_value.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::{btree_map, BTreeMap};
use std::collections::BTreeMap;
use std::fmt;
use std::net::Ipv6Addr;

Expand Down Expand Up @@ -45,7 +45,7 @@ pub enum OwnedValue {
/// A set of values.
Array(Vec<Self>),
/// Dynamic object value.
Object(BTreeMap<String, Self>),
Object(Vec<(String, Self)>),
/// IpV6 Address. Internally there is no IpV4, it needs to be converted to `Ipv6Addr`.
IpAddr(Ipv6Addr),
}
Expand Down Expand Up @@ -148,10 +148,10 @@ impl ValueDeserialize for OwnedValue {

fn visit_object<'de, A>(&self, mut access: A) -> Result<Self::Value, DeserializeError>
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))
Expand All @@ -167,6 +167,7 @@ impl Eq for OwnedValue {}
impl serde::Serialize for OwnedValue {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer {
use serde::ser::SerializeMap;
match *self {
OwnedValue::Null => serializer.serialize_unit(),
OwnedValue::Str(ref v) => serializer.serialize_str(v),
Expand All @@ -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 {

Check warning on line 186 in src/schema/document/owned_value.rs

View workflow job for this annotation

GitHub Actions / clippy

dereferencing a tuple pattern where every element takes a reference

warning: dereferencing a tuple pattern where every element takes a reference --> src/schema/document/owned_value.rs:186:21 | 186 | for &(ref k, ref v) in obj { | ^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference = note: `#[warn(clippy::needless_borrowed_reference)]` on by default help: try removing the `&` and `ref` parts | 186 - for &(ref k, ref v) in obj { 186 + for (k, 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() {
Expand Down Expand Up @@ -248,12 +255,10 @@ impl<'de> serde::Deserialize<'de> for OwnedValue {

fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
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))
}
}
Expand Down Expand Up @@ -363,7 +368,8 @@ impl From<PreTokenizedString> for OwnedValue {

impl From<BTreeMap<String, OwnedValue>> for OwnedValue {
fn from(object: BTreeMap<String, OwnedValue>) -> OwnedValue {
OwnedValue::Object(object)
let key_values = object.into_iter().collect();
OwnedValue::Object(key_values)
}
}

Expand Down Expand Up @@ -417,18 +423,16 @@ impl From<serde_json::Value> for OwnedValue {

impl From<serde_json::Map<String, serde_json::Value>> for OwnedValue {
fn from(map: serde_json::Map<String, serde_json::Value>) -> 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);
Expand Down

0 comments on commit 8861366

Please sign in to comment.