use struct_patch::Patch;
fn concat_list(original: &mut Vec<i32>, additional: Vec<i32>) {
original.extend(additional);
}
fn merge_tags(original: &mut String, additional: String) {
for c in additional.chars() {
if !original.contains(c) {
original.push(c);
}
}
}
#[derive(Debug, Default, Patch)]
#[patch(attribute(derive(Debug, Default)))]
struct Config {
#[patch(apply_by(concat_list))]
items: Vec<i32>,
name: String,
#[patch(skip_wrap, apply_by(merge_tags))]
tags: String,
}
fn main() {
let mut config = Config {
items: vec![1, 2, 3],
name: "base".to_string(),
tags: "a".to_string(),
};
config.apply(ConfigPatch {
items: Some(vec![4, 5, 6]),
name: None,
tags: "ab".to_string(),
});
assert_eq!(config.items, vec![1, 2, 3, 4, 5, 6]);
assert_eq!(config.tags, "ab");
println!("After first patch: {:?}", config.items);
println!("Tags after merge: {:?}", config.tags);
config.apply(ConfigPatch {
items: Some(vec![7, 8]),
name: Some("updated".to_string()),
tags: "c".to_string(),
});
assert_eq!(config.items, vec![1, 2, 3, 4, 5, 6, 7, 8]);
assert_eq!(config.tags, "abc");
println!("After second patch: {:?}", config.items);
println!("Tags after second merge: {:?}", config.tags);
println!("Name: {}", config.name);
}