mutable/
lib.rs

1#![doc = include_str!("../README.md")]
2
3pub mod default_impl;
4pub mod holder;
5pub mod cmp;
6pub use mutable_derive::*;
7
8/// An item which state may change
9///
10/// Allows to keep track of the changes of the item
11///
12/// # Simple Mutation
13/// ```
14/// # use mutable::Mutable;
15/// # use mutable_derive::Mutable;
16/// #[derive(Mutable, Clone, Debug, PartialEq)]
17///  struct Item {
18///      size: usize,
19/// }
20///
21/// let a0 = Item{ size: 0};
22/// let a1 = Item{ size: 1};
23///
24/// assert_eq!(a0.cmp(&a1), vec![ItemMutation::Size((0, 1))]);
25/// ```
26///
27/// # Nested mutation
28/// ```
29/// # use mutable::Mutable;
30/// # use mutable_derive::Mutable;
31/// #[derive(Mutable)]
32/// struct Simple {
33///     size: usize,
34/// }
35///
36/// #[derive(Mutable)]
37/// struct Complex{
38///     id: String,
39///     value: Simple,
40/// }
41///
42/// # fn main(){
43/// let mut c0 = Complex{ id: "a".to_string(), value: Simple { size: 32 } };
44/// let c1 = Complex{ id: "b".to_string(), value: Simple { size: 64 } };
45///
46/// assert_eq!(c0.update(c1), vec![
47///     ComplexMutation::Id(("a".to_string(), "b".to_string())),
48///     ComplexMutation::Value(SimpleMutation::Size((32, 64)))
49/// ]);
50/// # }
51/// ```
52///
53/// # Vec mutation
54/// ```
55/// # use mutable::Mutable;
56/// # use mutable::cmp::SoftEq;
57/// # use mutable_derive::{Mutable, SoftEq};
58/// # use mutable::default_impl::VecMutation;
59/// #[derive(Mutable, PartialEq, SoftEq, Debug, Clone)]
60/// struct Item {
61///     #[softeq(uid)]
62///     id: String,
63///     value: u32,
64/// }
65///
66/// # fn main(){
67/// let a0 = Item{id: "a".to_string(), value: 0};
68/// let a1 = Item{id: "a".to_string(), value: 1};
69/// let b = Item{id: "b".to_string(), value: 0};
70///
71/// let mut v0 = vec![a0];
72/// let v1 = vec![a1, b];
73///
74/// assert_eq!(v0.update(v1), vec![
75///     VecMutation::Update("a".to_string(), ItemMutation::Value((0, 1))),
76///     VecMutation::Insertion("b".to_string())
77/// ])
78/// # }
79/// ```
80///
81/// # Mutation generation
82/// When derived through [mutable_derive::Mutable](../mutable_derive/derive.Mutable.html), the mutation type is generated as follow:
83///
84/// The mutation type is an enum, for which each variant correspond to a field of the struct.
85/// Each of them as only one element, which is the mutation type of the attribute type
86///
87/// Example of result:
88/// ```
89/// struct Foo{
90///     size: usize
91/// }
92///
93/// // Generated
94/// enum FooMutation{
95///     Size((usize, usize)),
96/// }
97///
98/// struct Item{
99///     id: u32,
100///     name: String,
101///     value: Foo,
102/// }
103///
104/// // Generated
105/// enum ItemMutation{
106///     Id((u32, u32)),
107///     Name((String, String)),
108///     Value(FooMutation),
109/// }
110/// ```
111
112pub trait Mutable where Self: Sized {
113    /// Type describing any changes that may happen to the item
114    type Mutation: Clone;
115
116    /// Compare self and other, and returns the list of changes to go from self to other. The order of the mutation in the returned vec is undefined\
117    /// This should not be used outside of the Mutable implementation
118    fn cmp(&self, other: &Self) -> Vec<Self::Mutation>;
119
120    /// Mutate self into other, and returns the list of all mutations. The order of the mutation in the returned vec is undefined
121    fn update(&mut self, other: Self) -> Vec<Self::Mutation> {
122        let res = self.cmp(&other);
123        *self = other;
124        res
125    }
126}