Skip to content

Instantly share code, notes, and snippets.

@decatur
Last active March 27, 2024 12:53
Show Gist options
  • Save decatur/887d55904a9699283bf22b63e00133b5 to your computer and use it in GitHub Desktop.
Save decatur/887d55904a9699283bf22b63e00133b5 to your computer and use it in GitHub Desktop.
rust merge multiple yaml docs
// See https://stackoverflow.com/questions/67727239/how-to-combine-including-nested-array-values-two-serde-yamlvalue-objects
// Note this is not https://docs.rs/serde_yaml/latest/serde_yaml/value/enum.Value.html#method.apply_merge
use serde::{Serialize, Deserialize};
use serde_yaml::Value;
fn merge_yaml(a: &mut serde_yaml::Value, b: serde_yaml::Value) {
match (a, b) {
(a @ &mut serde_yaml::Value::Mapping(_), serde_yaml::Value::Mapping(b)) => {
let a = a.as_mapping_mut().unwrap();
for (k, v) in b {
/*if v.is_sequence() && a.contains_key(&k) && a[&k].is_sequence() {
let mut _b = a.get(&k).unwrap().as_sequence().unwrap().to_owned();
_b.append(&mut v.as_sequence().unwrap().to_owned());
a[&k] = serde_yaml::Value::from(_b);
continue;
}*/
if !a.contains_key(&k) {a.insert(k.to_owned(), v.to_owned());}
else { merge_yaml(&mut a[&k], v); }
}
}
(a, b) => *a = b,
}
}
fn main() -> Result<(), serde_yaml::Error> {
let s_a = "x: 1.0\ny_z:\n r: 2.0\n";
let s_b = "y_z:\n alpha: 45.0";
let mut yaml_a: Value = serde_yaml::from_str(&s_a)?;
let yaml_b: Value = serde_yaml::from_str(&s_b)?;
merge_yaml(&mut yaml_a, yaml_b);
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Point {
x: f32,
y_z: Radial,
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Radial {
r: f32,
alpha: f32,
}
println!("{yaml_a:?}");
let p: Point = serde_yaml::from_value(yaml_a).unwrap();
println!("{p:?}");
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment