derive_merge_struct/
lib.rs

1pub use derive_merge::Merge;
2
3/// The trait is designed for named struct. Can be used to partially update configuration.
4///
5/// - If the field of struct has attribute `#[exclude]`, `this.field` remain the same.
6/// - ElIf the field of struct is not `Option`: `this.field = that.field.clone()`
7/// - ElIf the field of struct has attribute `#[force]`: `this.field = that.field.clone()`
8/// - ElIf the field of struct is `Option` and doesn't have attribute `#[force]`:
9///     - If `that.field.is_some()`: `this.field = that.field.clone()`
10///     - If `that.field.is_none()`: `this.field` remain the same.
11///
12/// # Example
13///
14/// ```rust
15/// use derive_merge_struct::Merge;
16/// #[derive(Merge)]
17/// #[exclude]
18/// struct TestStruct {
19///     a: Option<i32>,
20///     b: Option<String>,
21///     c: Option<u32>,
22///     #[force]
23///     d: Option<i32>,
24///     #[exclude]
25///     e: Option<i32>,
26///     f: i32
27/// }
28/// let mut this = TestStruct {
29///     a: Some(1),
30///     b: None,
31///     c: Some(1),
32///     d: Some(1),
33///     e: None,
34///     f: 1
35/// };
36/// let that = TestStruct {
37///     a: Some(2),
38///     b: Some("hello".to_string()),
39///     c: None,
40///     d: None,
41///     e: Some(1),
42///     f: 2
43/// };
44/// this.merge(that);
45/// assert_eq!(this.a, Some(2));
46/// assert_eq!(this.b, Some("hello".to_string()));
47/// assert_eq!(this.c, Some(1));
48/// assert_eq!(this.d, None);
49/// assert_eq!(this.e, None);
50/// assert_eq!(this.f, 2);
51/// ```
52pub trait Merge {
53    fn merge(&mut self, another: Self);
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[derive(Merge)]
61    struct TestStruct {
62        a: Option<i32>,
63        b: Option<String>,
64        c: Option<u32>,
65        #[force]
66        d: Option<i32>,
67        #[exclude]
68        e: Option<i32>,
69        f: i32,
70    }
71    #[test]
72    fn test_merge() {
73        let mut this = TestStruct {
74            a: Some(1),
75            b: None,
76            c: Some(1),
77            d: Some(1),
78            e: None,
79            f: 1,
80        };
81        let that = TestStruct {
82            a: Some(2),
83            b: Some("hello".to_string()),
84            c: None,
85            d: None,
86            e: Some(1),
87            f: 2,
88        };
89        this.merge(that);
90        assert_eq!(this.a, Some(2));
91        assert_eq!(this.b, Some("hello".to_string()));
92        assert_eq!(this.c, Some(1));
93        assert_eq!(this.d, None);
94        assert_eq!(this.e, None);
95        assert_eq!(this.f, 2);
96    }
97}