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