inter_struct/merge.rs
1//! # Merge Behavior
2//!
3//! The following will explain the merge behavior on the example of a single field.
4//!
5//! ## Merge behavior of `merge` and `merge_ref`
6//!
7//! #### Same Type
8//!
9//! ```rust,ignore
10//! struct Src {
11//! test: T
12//! }
13//! struct Target {
14//! test: T
15//! }
16//! ```
17//!
18//! This will simply merge `src.test` into `target.test`: \
19//! `target.test = src.test`
20//!
21//! #### Target is Optional
22//!
23//! ```rust,ignore
24//! struct Src {
25//! test: T
26//! }
27//! struct Target {
28//! test: Option<T>
29//! }
30//! ```
31//!
32//! This will wrap `src.test` into an `Option` and merge it into `target.test`: \
33//! `target.test = Some(src.test);`
34//!
35//! #### Source is Optional
36//!
37//! ```rust,ignore
38//! struct Src {
39//! test: Option<T>
40//! }
41//! struct Target {
42//! test: T
43//! }
44//! ```
45//!
46//! This will only merge `src.test` into `target.test` if `src.test` is `Some`: \
47//! ```rust,ignore
48//! if let Some(value) = src.test {
49//! target.test = value;
50//! }
51//! ```
52
53/// Merge another struct into `Self`.
54pub trait StructMerge<Src> {
55 /// Merge the given struct into `Self` whilst consuming it.
56 fn merge(&mut self, src: Src);
57}
58
59/// Counterpart of [StructMerge].
60/// This will merge `Self` into a given target.
61pub trait StructMergeInto<Target: ?Sized> {
62 /// Check the [StructMerge::merge] docs.
63 fn merge_into(self, target: &mut Target);
64}
65
66/// Implement the [StructMerge] trait for all types that provide [StructMergeInto] for it.
67impl<Target, Src: StructMergeInto<Target>> StructMerge<Src> for Target {
68 fn merge(&mut self, src: Src) {
69 src.merge_into(self);
70 }
71}
72
73/// Merge another borrowed struct into `Self`.
74///
75/// All fields to be merged on the borrowed struct have to implement [Clone].
76pub trait StructMergeRef<Src> {
77 /// Merge the given struct into `Self`.
78 fn merge_ref(&mut self, src: &Src);
79}
80
81/// Counterpart of [StructMergeRef].
82/// This will merge `&Self` into a given target.
83pub trait StructMergeIntoRef<Target: ?Sized> {
84 /// Check the [StructMergeRef::merge_ref] docs.
85 fn merge_into_ref(&self, target: &mut Target);
86}
87
88/// Implement the [StructMergeRef] trait for all types that provide [StructMergeInto] for it.
89impl<Target, Src: StructMergeIntoRef<Target>> StructMergeRef<Src> for Target {
90 fn merge_ref(&mut self, src: &Src) {
91 src.merge_into_ref(self);
92 }
93}