parent
70bc9c4512
commit
35b6643bad
2 changed files with 53 additions and 35 deletions
|
@ -617,5 +617,41 @@ where
|
|||
|
||||
/// Merges `response_name`/`value` pair into `result`
|
||||
pub(crate) fn merge_key_into<S>(result: &mut Object<S>, response_name: &str, value: Value<S>) {
|
||||
if let Some(v) = result.get_mut_field_value(response_name) {
|
||||
match v {
|
||||
Value::Object(dest_obj) => {
|
||||
if let Value::Object(src_obj) = value {
|
||||
merge_maps(dest_obj, src_obj);
|
||||
}
|
||||
}
|
||||
Value::List(dest_list) => {
|
||||
if let Value::List(src_list) = value {
|
||||
dest_list
|
||||
.iter_mut()
|
||||
.zip(src_list.into_iter())
|
||||
.for_each(|(d, s)| {
|
||||
if let Value::Object(d_obj) = d {
|
||||
if let Value::Object(s_obj) = s {
|
||||
merge_maps(d_obj, s_obj);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
return;
|
||||
}
|
||||
result.add_field(response_name, value);
|
||||
}
|
||||
|
||||
/// Merges `src` object's fields into `dest`
|
||||
fn merge_maps<S>(dest: &mut Object<S>, src: Object<S>) {
|
||||
for (key, value) in src {
|
||||
if dest.contains_field(&key) {
|
||||
merge_key_into(dest, &key, value);
|
||||
} else {
|
||||
dest.add_field(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,14 @@
|
|||
use std::iter::FromIterator;
|
||||
use std::{iter::FromIterator, mem};
|
||||
|
||||
use super::Value;
|
||||
use indexmap::map::{IndexMap, IntoIter};
|
||||
|
||||
/// A Object value
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Object<S> {
|
||||
key_value_list: IndexMap<String, Value<S>>,
|
||||
}
|
||||
|
||||
impl<S: PartialEq> PartialEq for Object<S> {
|
||||
fn eq(&self, _: &Object<S>) -> bool {
|
||||
match self {
|
||||
Object { key_value_list } => self.key_value_list == *key_value_list,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Object<S> {
|
||||
/// Create a new Object value with a fixed number of
|
||||
/// preallocated slots for field-value pairs
|
||||
|
@ -35,28 +27,18 @@ impl<S> Object<S> {
|
|||
/// returned.
|
||||
pub fn add_field<K>(&mut self, k: K, value: Value<S>) -> Option<Value<S>>
|
||||
where
|
||||
K: Into<String>,
|
||||
for<'a> &'a str: PartialEq<K>,
|
||||
K: AsRef<str> + Into<String>,
|
||||
{
|
||||
let key: String = k.into();
|
||||
match (value, self.key_value_list.get_mut(&key)) {
|
||||
(Value::<S>::Object(obj_val), Some(Value::<S>::Object(existing_obj))) => {
|
||||
for (key, val) in obj_val.into_iter() {
|
||||
existing_obj.add_field::<String>(key, val);
|
||||
}
|
||||
None
|
||||
}
|
||||
(non_obj_val, _) => self.key_value_list.insert(key, non_obj_val),
|
||||
if let Some(v) = self.key_value_list.get_mut(k.as_ref()) {
|
||||
Some(mem::replace(v, value))
|
||||
} else {
|
||||
self.key_value_list.insert(k.into(), value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the object already contains a field with the given name
|
||||
pub fn contains_field<K>(&self, f: K) -> bool
|
||||
where
|
||||
K: Into<String>,
|
||||
for<'a> &'a str: PartialEq<K>,
|
||||
{
|
||||
self.key_value_list.contains_key(&f.into())
|
||||
pub fn contains_field<K: AsRef<str>>(&self, k: K) -> bool {
|
||||
self.key_value_list.contains_key(k.as_ref())
|
||||
}
|
||||
|
||||
/// Get a iterator over all field value pairs
|
||||
|
@ -75,12 +57,13 @@ impl<S> Object<S> {
|
|||
}
|
||||
|
||||
/// Get the value for a given field
|
||||
pub fn get_field_value<K>(&self, key: K) -> Option<&Value<S>>
|
||||
where
|
||||
K: Into<String>,
|
||||
for<'a> &'a str: PartialEq<K>,
|
||||
{
|
||||
self.key_value_list.get(&key.into())
|
||||
pub fn get_field_value<K: AsRef<str>>(&self, key: K) -> Option<&Value<S>> {
|
||||
self.key_value_list.get(key.as_ref())
|
||||
}
|
||||
|
||||
/// Get the mutable value for a given field
|
||||
pub fn get_mut_field_value<K: AsRef<str>>(&mut self, key: K) -> Option<&mut Value<S>> {
|
||||
self.key_value_list.get_mut(key.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,8 +84,7 @@ impl<S> From<Object<S>> for Value<S> {
|
|||
|
||||
impl<K, S> FromIterator<(K, Value<S>)> for Object<S>
|
||||
where
|
||||
K: Into<String>,
|
||||
for<'a> &'a str: PartialEq<K>,
|
||||
K: AsRef<str> + Into<String>,
|
||||
{
|
||||
fn from_iter<I>(iter: I) -> Self
|
||||
where
|
||||
|
|
Loading…
Reference in a new issue