struct_patch/traits.rs
1/// A struct that a patch can be applied to
2///
3/// Deriving [`Patch`] will generate a patch struct and an accompanying trait impl so that it can be applied to the original struct.
4/// ```rust
5/// # use struct_patch::Patch;
6/// #[derive(Patch)]
7/// struct Item {
8/// field_bool: bool,
9/// field_int: usize,
10/// field_string: String,
11/// }
12///
13/// // Generated struct
14/// // struct ItemPatch {
15/// // field_bool: Option<bool>,
16/// // field_int: Option<usize>,
17/// // field_string: Option<String>,
18/// // }
19/// ```
20/// ## Container attributes
21/// ### `#[patch(attribute(derive(...)))]`
22/// Use this attribute to derive traits on the generated patch struct
23/// ```rust
24/// # use struct_patch::Patch;
25/// # use serde::{Serialize, Deserialize};
26/// #[derive(Patch)]
27/// #[patch(attribute(derive(Debug, Default, Deserialize, Serialize)))]
28/// struct Item;
29///
30/// // Generated struct
31/// // #[derive(Debug, Default, Deserialize, Serialize)]
32/// // struct ItemPatch {}
33/// ```
34///
35/// ### `#[patch(attribute(...))]`
36/// Use this attribute to pass the attributes on the generated patch struct
37/// ```compile_fail
38/// // This example need `serde` and `serde_with` crates
39/// # use struct_patch::Patch;
40/// #[derive(Patch, Debug)]
41/// #[patch(attribute(derive(Serialize, Deserialize, Default)))]
42/// #[patch(attribute(skip_serializing_none))]
43/// struct Item;
44///
45/// // Generated struct
46/// // #[derive(Default, Deserialize, Serialize)]
47/// // #[skip_serializing_none]
48/// // struct ItemPatch {}
49/// ```
50///
51/// ### `#[patch(name = "...")]`
52/// Use this attribute to change the name of the generated patch struct
53/// ```rust
54/// # use struct_patch::Patch;
55/// #[derive(Patch)]
56/// #[patch(name = "ItemOverlay")]
57/// struct Item { }
58///
59/// // Generated struct
60/// // struct ItemOverlay {}
61/// ```
62///
63/// ## Field attributes
64/// ### `#[patch(skip)]`
65/// If you want certain fields to be unpatchable, you can let the derive macro skip certain fields when creating the patch struct
66/// ```rust
67/// # use struct_patch::Patch;
68/// #[derive(Patch)]
69/// struct Item {
70/// #[patch(skip)]
71/// id: String,
72/// data: String,
73/// }
74///
75/// // Generated struct
76/// // struct ItemPatch {
77/// // data: Option<String>,
78/// // }
79/// ```
80pub trait Patch<P> {
81 /// Apply a patch
82 fn apply(&mut self, patch: P);
83
84 /// Returns a patch that when applied turns any struct of the same type into `Self`
85 fn into_patch(self) -> P;
86
87 /// Returns a patch that when applied turns `previous_struct` into `Self`
88 fn into_patch_by_diff(self, previous_struct: Self) -> P;
89
90 /// Get an empty patch instance
91 fn new_empty_patch() -> P;
92}
93
94pub trait Filler<F> {
95 /// Apply a filler
96 fn apply(&mut self, filler: F);
97
98 /// Get an empty filler instance
99 fn new_empty_filler() -> F;
100}
101
102#[cfg(feature = "status")]
103/// A patch struct with extra status information
104pub trait Status {
105 /// Returns `true` if all fields are `None`, `false` otherwise.
106 fn is_empty(&self) -> bool;
107}
108
109#[cfg(feature = "merge")]
110/// A patch struct that can be merged to another one
111pub trait Merge {
112 fn merge(self, other: Self) -> Self;
113}