preserves 5.0.0-rc.9

Implementation of the Preserves serialization format.
Documentation
use crate::Annotations;
use crate::CompoundClass;
use crate::Domain;
use crate::Map;
use crate::Value;
use crate::ValueClass;
use crate::ValueImpl;

pub fn merge_seqs<D: Domain>(
    mut a: Vec<Value<D>>,
    mut b: Vec<Value<D>>,
) -> Option<Vec<Value<D>>> {
    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);
    Some(r)
}

pub fn merge2<D: Domain>(v: Value<D>, w: Value<D>) -> Option<Value<D>> {
    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())
    } else {
        match v.value_class() {
            ValueClass::Atomic(_) => None,
            ValueClass::Embedded => None,
            ValueClass::Compound(CompoundClass::Record) => if w.is_record() {
                Some(Value::record(merge2(v.label(), w.label())?,
                                   merge_seqs(v.iter().collect(), w.iter().collect())?))
            } else {
                None
            }
            ValueClass::Compound(CompoundClass::Sequence) => if w.is_sequence() {
                Some(Value::new(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, merge2(vv, wv)?); }
                        None => { rs.insert(k, vv); }
                    }
                }
                rs.extend(ws.into_iter());
                Some(Value::new(rs))
            } else {
                None
            }
        }
    };

    r.map(|r| if anns.is_empty() {
        r
    } else {
        Value::new(Annotations::new(r, anns))
    })
}

pub fn merge<D: Domain, I: IntoIterator<Item = Value<D>>>(vs: I) -> Option<Value<D>> {
    let mut vs = vs.into_iter();
    let mut v = vs.next().expect("at least one value in merge()");
    for w in vs {
        match merge2(v, w) {
            Some(merged) => v = merged,
            None => return None,
        }
    }
    Some(v)
}