fixed implementation of item.merge()
This commit is contained in:
@@ -45,11 +45,12 @@ impl<S: Store> Item<'_, S> {
|
|||||||
self.instance.store.get_value_data_full(self.id())
|
self.instance.store.get_value_data_full(self.id())
|
||||||
}
|
}
|
||||||
pub fn merge<V: Into<ItemData>>(&mut self, mut value: V) -> MizeResult<()> {
|
pub fn merge<V: Into<ItemData>>(&mut self, mut value: V) -> MizeResult<()> {
|
||||||
//trace!("[ {} ] Item.merge()", "CALL".yellow());
|
|
||||||
let mut old_data = self.instance.store.get_value_data_full(self.id())?;
|
let mut old_data = self.instance.store.get_value_data_full(self.id())?;
|
||||||
//trace!("old_data: {:?}", old_data);
|
|
||||||
old_data.merge(value.into());
|
let new_data = value.into();
|
||||||
//trace!("new_data: {:?}", old_data);
|
|
||||||
|
old_data.merge(new_data);
|
||||||
|
|
||||||
self.instance.store.set(self.id(), old_data)?;
|
self.instance.store.set(self.id(), old_data)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -69,7 +70,7 @@ impl ItemData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn merge(&mut self, other: ItemData) {
|
pub fn merge(&mut self, other: ItemData) {
|
||||||
item_data_merge(self, other)
|
item_data_merge(&mut self.0, &other.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn null() -> CborValue {
|
pub fn null() -> CborValue {
|
||||||
@@ -176,39 +177,60 @@ fn item_data_set_path(data: &mut CborValue, path: Vec<String>, data_to_set: &Cbo
|
|||||||
return Err(MizeError::new().msg("unreachable"));
|
return Err(MizeError::new().msg("unreachable"));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_data_merge(first: &mut ItemData, other: ItemData){
|
fn item_data_merge(merge_into: &mut CborValue, other: &CborValue){
|
||||||
//trace!("[ {} ] item_data_merge()", "CALL".yellow());
|
// needs to be recursive
|
||||||
//trace!("[ {} ] first: {}", "ARG".yellow(), first.clone().into_item_data());
|
|
||||||
//trace!("[ {} ] other: {}", "ARG".yellow(), other.clone().into_item_data());
|
|
||||||
|
|
||||||
match first.0 {
|
match (merge_into, other) {
|
||||||
CborValue::Map(ref mut map) => {
|
// if both are maps
|
||||||
//trace!("data is a map: {:?}", map);
|
// merge the keys/vals in the maps and call recursively on them
|
||||||
match other.0 {
|
(CborValue::Map(ref mut merge_into_map), CborValue::Map(ref other_map)) => {
|
||||||
CborValue::Map(mut other_map) => {
|
// go through other_map and merge those keys/values to merge_into
|
||||||
let mut to_add = Vec::new();
|
for (other_key, other_val) in other_map {
|
||||||
for (other_key, other_val) in other_map.clone() {
|
|
||||||
let mut key_found_in_old = false;
|
// so find that same vale in merge_into, if exists recursively merge, else just add to
|
||||||
for (key, mut val) in map.clone() {
|
// vec
|
||||||
if key == other_key {
|
let mut found_value = CborValue::Null;
|
||||||
val = other_val.clone();
|
let mut value_found = false;
|
||||||
key_found_in_old = true;
|
let mut new_value_for_merge_into: Vec<(CborValue, CborValue)> = Vec::new(); // here we collect the
|
||||||
}
|
// new contents of the
|
||||||
}
|
// map, to assign later
|
||||||
if key_found_in_old == false {
|
// to merge_into_map
|
||||||
to_add.push((other_key.clone(), other_val.clone()));
|
|
||||||
}
|
for (merge_into_key, merge_into_val) in merge_into_map.clone() {
|
||||||
|
if merge_into_key == *other_key {
|
||||||
|
value_found = true;
|
||||||
|
found_value = merge_into_val.to_owned();
|
||||||
|
// if we found it, also don't add it to new_value_for_merge_into
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//if not found push to new_value_for_merge_into
|
||||||
|
new_value_for_merge_into.push((merge_into_key.to_owned(), merge_into_val.to_owned()));
|
||||||
}
|
}
|
||||||
other_map.extend(to_add);
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
*first = other;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if value_found {
|
||||||
|
// we found it so merge and asign
|
||||||
|
item_data_merge(&mut found_value, other_val);
|
||||||
|
|
||||||
|
// to asign push to new_value_for_merge_into, because the old was removed already
|
||||||
|
new_value_for_merge_into.push((other_key.to_owned(), found_value));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// if not found, just add the other_key/val to new_value_for_merge_into
|
||||||
|
new_value_for_merge_into.push((other_key.to_owned(), other_val.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally, we need to asign the new_value_for_merge_into into merge_into
|
||||||
|
*merge_into_map = new_value_for_merge_into;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => {
|
|
||||||
*first = other;
|
|
||||||
},
|
// in any other case we just want to set merge_into to other
|
||||||
|
// also this is the base case
|
||||||
|
(merge_into, other) => {
|
||||||
|
*merge_into = other.to_owned();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ fn config_from_string(config_string: String) -> MizeResult<ItemData> {
|
|||||||
.ok_or(MizeError::new().msg(format!("Failed to parse Option: option '{}' has an empty value (thing after =)", option)))?;
|
.ok_or(MizeError::new().msg(format!("Failed to parse Option: option '{}' has an empty value (thing after =)", option)))?;
|
||||||
let mut path_vec = vec!["config"];
|
let mut path_vec = vec!["config"];
|
||||||
path_vec.extend(path.split("."));
|
path_vec.extend(path.split("."));
|
||||||
println!("path_vec: {:?}", path_vec);
|
|
||||||
|
|
||||||
config.set_path(path_vec, ItemData::parse(value))?;
|
config.set_path(path_vec, ItemData::parse(value))?;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user