struct_merge/lib.rs
1pub use struct_merge_codegen::*;
2
3/// Merge another struct into `Self`.
4pub trait StructMerge<Src> {
5 /// Merge the given struct into `Self` whilst consuming it.
6 fn merge(&mut self, src: Src);
7
8 /// Merge the given struct into `Self` whilst consuming it.
9 ///
10 /// Nearly the same as `merge`, but any `Self::Option<T>` fields will only get merged if the
11 /// value of the field is `None`.
12 ///
13 /// For example:
14 /// ```ignore
15 /// struct Target { a: Option<String> };
16 /// struct Src { a: String };
17 ///
18 /// let target = Target { a: Some("test".to_string()) };
19 /// let src = Src { a: "test2".to_string() };
20 ///
21 /// target.merge_soft(src);
22 /// // Value didn't get merged as `target.a` was `Some`
23 /// assert_eq!(target.a, "test".to_string());
24 /// ```
25 fn merge_soft(&mut self, src: Src);
26}
27
28/// Counterpart of [StructMerge].
29/// This will merge `Self` into a given target.
30pub trait StructMergeInto<Target: ?Sized> {
31 /// Check the [StructMerge::merge] docs.
32 fn merge_into(self, target: &mut Target);
33
34 /// Check the [StructMerge::merge_soft] docs.
35 fn merge_into_soft(self, target: &mut Target);
36}
37
38/// Implement the [StructMerge] trait for all types that provide [StructMergeInto] for it.
39impl<Target, Src: StructMergeInto<Target>> StructMerge<Src> for Target {
40 fn merge(&mut self, src: Src) {
41 src.merge_into(self);
42 }
43
44 fn merge_soft(&mut self, src: Src) {
45 src.merge_into_soft(self);
46 }
47}
48
49/// Merge another borrowed struct into `Self`.
50///
51/// All fields to be merged on the borrowed struct have to implement [Clone].
52pub trait StructMergeRef<Src> {
53 /// Merge the given struct into `Self`.
54 fn merge_ref(&mut self, src: &Src);
55
56 /// Merge the given struct into `Self`.
57 ///
58 /// Nearly the same as `merge_ref`, but any `Self::Option<T>` fields will only get merged if the
59 /// value of the field is `None`.
60 ///
61 /// For example:
62 /// ```ignore
63 /// struct Target { a: Option<String> };
64 /// struct Src { a: String };
65 ///
66 /// let target = Target { a: Some("test".to_string()) };
67 /// let src = Src { a: "test2".to_string() };
68 ///
69 /// target.merge_ref_soft(&src);
70 /// // Value didn't get merged as `target.a` was `Some`
71 /// assert_eq!(target.a, "test".to_string());
72 /// ```
73 fn merge_ref_soft(&mut self, src: &Src);
74}
75
76/// Counterpart of [StructMergeRef].
77/// This will merge `&Self` into a given target.
78pub trait StructMergeIntoRef<Target: ?Sized> {
79 /// Check the [StructMergeRef::merge_ref] docs.
80 fn merge_into_ref(&self, target: &mut Target);
81
82 /// Check the [StructMergeRef::merge_ref_soft] docs.
83 fn merge_into_ref_soft(&self, target: &mut Target);
84}
85
86/// Implement the [StructMergeRef] trait for all types that provide [StructMergeInto] for it.
87impl<Target, Src: StructMergeIntoRef<Target>> StructMergeRef<Src> for Target {
88 fn merge_ref(&mut self, src: &Src) {
89 src.merge_into_ref(self);
90 }
91
92 fn merge_ref_soft(&mut self, src: &Src) {
93 src.merge_into_ref_soft(self);
94 }
95}
96
97pub mod prelude {
98 pub use super::{StructMerge, StructMergeRef};
99}