pub trait Merge<Partial>: Sized {
// Required method
fn merge_in_place(&mut self, other: Partial);
// Provided method
fn merge(self, other: Partial) -> Self { ... }
}Expand description
A trait for two types that can be merged into one.
The Partial type is the type being merged into Self. It is intended to represent a subset
of the data in Self, though it is not a strict requirement.
§Examples
This is an example using the Merge derive macro. Please see
its documentation for further details.
#[derive(Merge)]
// Name the partial version of this type `PartialPerson`. This attribute is required.
#[partial(PartialPerson)]
struct Person {
name: String,
age: u16,
// Instead of overwriting the list of friends when merged, combine them together.
#[strategy(merge)]
friends: Vec<String>,
}
let person = Person {
name: "Janette".to_string(),
age: 19,
friends: vec!["Lou".to_string()],
};
// Change Janette's age to be 25 and add a friend, but preserve her original name.
let partial = PartialPerson {
name: None,
age: Some(25),
friends: Some(vec!["Kylie".to_string()]),
};
let merged = person.merge(partial);
assert_eq!(merged.name, "Janette");
assert_eq!(merged.age, 25);
assert_eq!(merged.friends, ["Lou", "Kylie"]);This is an example implementing Merge from scratch. It is equivalent to the prior example.
struct Person {
name: String,
age: u16,
friends: Vec<String>,
}
// This represents a subset of `Person` and can be merged with it. When a field is `Some`, it
// will overwrite the `Person`'s value. When a field is `None`, it will preserve the original
// value.
struct PartialPerson {
name: Option<String>,
age: Option<u16>,
friends: Option<Vec<String>>,
}
impl Merge<PartialPerson> for Person {
fn merge_in_place(&mut self, other: PartialPerson) {
if let Some(name) = other.name {
self.name = name;
}
if let Some(age) = other.age {
self.age = age;
}
// Instead of overwriting the list of friends, merge the two together.
if let Some(friends) = other.friends {
self.friends.merge_in_place(friends);
}
}
}
let person = Person {
name: "Janette".to_string(),
age: 19,
friends: vec!["Lou".to_string()],
};
// Change Janette's age to be 25 and add a friend, but preserve her original name.
let partial = PartialPerson {
name: None,
age: Some(25),
friends: Some(vec!["Kylie".to_string()]),
};
let merged = person.merge(partial);
assert_eq!(merged.name, "Janette");
assert_eq!(merged.age, 25);
assert_eq!(merged.friends, ["Lou", "Kylie"]);Required Methods§
Sourcefn merge_in_place(&mut self, other: Partial)
fn merge_in_place(&mut self, other: Partial)
Merges Self and Partial together, mutating Self in place.
§Examples
#[derive(Merge)]
#[partial(PartialCat)]
struct Cat {
name: String,
age: u16,
}
let mut whiskers = Cat {
name: "Whiskers".to_string(),
age: 4,
};
let partial = PartialCat {
name: None,
age: Some(5),
};
whiskers.merge_in_place(partial);
assert_eq!(whiskers.name, "Whiskers");
assert_eq!(whiskers.age, 5);Provided Methods§
Sourcefn merge(self, other: Partial) -> Self
fn merge(self, other: Partial) -> Self
Merges Self and Partial together, returning a new Self.
§Examples
#[derive(Merge)]
#[partial(PartialCat)]
struct Cat {
name: String,
age: u16,
}
let mut whiskers = Cat {
name: "Whiskers".to_string(),
age: 4,
};
let partial = PartialCat {
name: Some("Toast".to_string()),
age: None,
};
let toast = whiskers.merge(partial);
assert_eq!(toast.name, "Toast");
assert_eq!(toast.age, 4);Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Implementors§
impl<Base, Partial, Item> Merge<Partial> for Basewhere
Base: Extend<Item>,
Partial: IntoIterator<Item = Item>,
This means that most standard library collection types can be merged with anything iterable over the same type. Some highlights include:
Vec<T>withIntoIterator<Item = T>StringwithIntoIterator<Item = &str>orIntoIterator<Item = char>HashMap<K, V>withIntoIterator<Item = (K, V)>HashSet<T>withIntoIterator<Item = T>BTreeMap<K, V>withIntoIterator<Item = (K, V)>BTreeSet<T>withIntoIterator<Item = T>PathBufwithIntoIterator<Item = Path>
§Examples
let a = vec![1, 2];
let b = &[3, 4, 5];
assert_eq!(a.merge(b), [1, 2, 3, 4, 5]);let c = String::from("Hello, ");
let d = ['w', 'o', 'r', 'l', 'd', '!'];
assert_eq!(c.merge(d), "Hello, world!");let mut e = HashMap::from([
("Hello", "Bonjour"),
("Goodbye", "Au revoir"),
]);
let f = [
("Apple", "Pomme"),
("Potato", "Pomme de terre"),
];
assert_eq!(
e.merge(f),
HashMap::from([
("Hello", "Bonjour"),
("Goodbye", "Au revoir"),
("Apple", "Pomme"),
("Potato", "Pomme de terre"),
]),
);let g = vec![2, 4, 8];
let h = std::iter::successors(Some(16), |n| Some(n * 2)).take(3);
assert_eq!(g.merge(h), [2, 4, 8, 16, 32, 64]);