From: Ian Jackson Date: Sun, 31 Jan 2021 16:45:43 +0000 (+0000) Subject: utils: Provide toml_merge X-Git-Tag: otter-0.4.0~611 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=f61c0818c0da46b8bc4f2a9ed06b12c40030b891;p=otter.git utils: Provide toml_merge Signed-off-by: Ian Jackson --- diff --git a/src/utils.rs b/src/utils.rs index 0980584d..ae8bffb6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -141,3 +141,42 @@ impl Result> } // todo: DerefMut + +pub fn toml_merge<'u, + S: 'u + AsRef, + KV: IntoIterator + >( + table: &mut toml::value::Table, + updates: KV, +) { + use toml::value::{Table, Value}; + type TME<'e> = toml::map::Entry<'e>; + + let mut kv = updates.into_iter().map(|(k, v)| (k.as_ref(), v)); + inner(table, &mut kv); + + fn inner<'u>( + table: &mut Table, + updates: &'u mut dyn Iterator + ) { + for (k, v) in updates { + let e = table.entry(k); + match e { + TME::Vacant(ve) => { + ve.insert(v.clone()); + } + TME::Occupied(mut oe) => match (oe.get_mut(), v) { + (Value::Table(old), Value::Table(new)) => { + toml_merge(old, new); + } + (Value::Array(old), Value::Array(new)) => { + old.extend(new.iter().cloned()); + } + (old, new) => { + *old = new.clone(); + } + } + } + } + } +}