93 lines
3.0 KiB
Rust
93 lines
3.0 KiB
Rust
use crate::Annotations;
|
|
use crate::ArcValue;
|
|
use crate::CompoundClass;
|
|
use crate::Map;
|
|
use crate::Record;
|
|
use crate::Value;
|
|
use crate::ValueClass;
|
|
use crate::ValueImpl;
|
|
|
|
pub fn merge_seqs<V: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(
|
|
mut a: Vec<Value<V>>,
|
|
mut b: Vec<Value<W>>,
|
|
) -> Option<Vec<ArcValue<V::Embedded>>> {
|
|
if a.len() > b.len() {
|
|
std::mem::swap(&mut a, &mut b);
|
|
}
|
|
let mut r = vec![];
|
|
let mut bi = b.into_iter();
|
|
for av in a.into_iter() {
|
|
r.push(merge2(&*av, &*bi.next().unwrap())?);
|
|
}
|
|
r.extend(bi.map(|bv| bv.value_clone()));
|
|
Some(r)
|
|
}
|
|
|
|
pub fn merge2<V: ValueImpl, W: ValueImpl<Embedded = V::Embedded>>(v: &Value<V>, w: &Value<W>) -> Option<ArcValue<V::Embedded>> {
|
|
let anns = match (v.annotations(), w.annotations()) {
|
|
(Some(va), Some(wa)) => {
|
|
let mut a = va.to_vec();
|
|
a.extend(wa.to_vec());
|
|
a
|
|
}
|
|
(Some(va), None) => va.to_vec(),
|
|
(None, Some(wa)) => wa.to_vec(),
|
|
(None, None) => vec![],
|
|
};
|
|
|
|
let r = if v == w {
|
|
Some(v.peeled().value_clone())
|
|
} else {
|
|
match v.value_class() {
|
|
ValueClass::Atomic(_) => None,
|
|
ValueClass::Embedded => None,
|
|
ValueClass::Compound(CompoundClass::Record) => if w.is_record() {
|
|
todo!()
|
|
// Some(owned(Record::new(merge2(&*v.label(), &*w.label())?,
|
|
// merge_seqs(v.iter().collect(), w.iter().collect())?)))
|
|
} else {
|
|
None
|
|
}
|
|
ValueClass::Compound(CompoundClass::Sequence) => if w.is_sequence() {
|
|
Some(owned(merge_seqs(v.iter().collect(), w.iter().collect())?))
|
|
} else {
|
|
None
|
|
}
|
|
ValueClass::Compound(CompoundClass::Set) =>
|
|
None, // unsure how to merge sets
|
|
ValueClass::Compound(CompoundClass::Dictionary) => if w.is_dictionary() {
|
|
let mut ws: Map<_, _> = w.entries().collect();
|
|
let mut rs = Map::new();
|
|
for (k, vv) in v.entries() {
|
|
match ws.remove(&k) {
|
|
Some(wv) => { rs.insert(k.value_clone(), merge2(&*vv, &*wv)?); }
|
|
None => { rs.insert(k.value_clone(), vv.value_clone()); }
|
|
}
|
|
}
|
|
rs.extend(ws.into_iter().map(|(k, wv)| (k.value_clone(), wv.value_clone())));
|
|
Some(owned(rs))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
};
|
|
|
|
r.map(|r| if anns.is_empty() {
|
|
r
|
|
} else {
|
|
owned(Annotations::new(r, anns))
|
|
})
|
|
}
|
|
|
|
pub fn merge<V: ValueImpl, I: IntoIterator<Item = Value<V>>>(vs: I) -> Option<ArcValue<V::Embedded>> {
|
|
let mut vs = vs.into_iter();
|
|
let mut v = vs.next().expect("at least one value in merge()").value_clone();
|
|
for w in vs {
|
|
match merge2(&*v, &*w) {
|
|
Some(merged) => v = merged,
|
|
None => return None,
|
|
}
|
|
}
|
|
Some(v)
|
|
}
|