pub fn diff_changes<'a, T: HasChanges>(
old: &'a T,
new: &'a T,
) -> Vec<T::Change<'a>>Expand description
Convenience helper.
Examples found in repository?
examples/vec-changes.rs (line 35)
27fn main() {
28 // 1. Tail-removal of a duplicate
29 let old = Bag {
30 items: vec!['A', 'A', 'A', 'A'],
31 };
32 let new = Bag {
33 items: vec!['A', 'A', 'A'],
34 };
35 dump("[A, A, A, A] -> [A, A, A]", &diff_changes(&old, &new));
36
37 // 2. Remove first element ⇒ everything shifts left
38 let old = Bag {
39 items: vec!['A', 'B', 'C'],
40 };
41 let new = Bag {
42 items: vec!['B', 'C'],
43 };
44 dump("[A, B, C] -> [B, C]", &diff_changes(&old, &new));
45
46 // 3. Mixed removal + moves with duplicates
47 let old = Bag {
48 items: vec!['A', 'B', 'A', 'A'],
49 };
50 let new = Bag {
51 items: vec!['B', 'A', 'A'],
52 };
53 dump("[A, B, A, A] -> [B, A, A]", &diff_changes(&old, &new));
54
55 // 4. Pure insertions (one value appears for the first time, then again)
56 let old = Bag {
57 items: vec!['X', 'Y'],
58 };
59 let new = Bag {
60 items: vec!['X', 'A', 'Y', 'A'],
61 };
62 dump("[X,Y] -> [X,A, Y,A]", &diff_changes(&old, &new));
63}More examples
examples/changes.rs (line 37)
21fn main() {
22 let old = User {
23 age: 30,
24 address: Address {
25 street: "1 Main".into(),
26 city: "Paris".into(),
27 residents: vec!["Alice".into(), "Bob".into()],
28 },
29 };
30
31 let mut new = old.clone();
32 new.age = 31; // scalar
33 new.address.city = "Berlin".into(); // nested scalar
34 new.address.residents.retain(|n| n != "Bob"); // remove one
35 new.address.residents.push("Carol".into()); // add one
36
37 let changes = diff_changes(&old, &new);
38
39 for ch in &changes {
40 #[allow(clippy::deprecated_cfg_attr)]
41 #[cfg_attr(rustfmt, rustfmt_skip)]
42 match ch {
43 UserChange::age(age) => println!("age -> {age}"),
44 UserChange::address(AddressChange::self_(address)) => println!("address -> {address:?}"),
45 UserChange::address(AddressChange::city(val)) => println!("city -> {val}"),
46 UserChange::address(AddressChange::residents(Changed::Added(name))) => println!("resident + -> {name}"),
47 UserChange::address(AddressChange::residents(Changed::Removed(name))) => println!("resident - -> {name}"),
48 _ => {}
49 }
50 }
51
52 for ch in &changes {
53 changed!(ch;
54 User.age(age) => { println!("age -> {age}"); };
55 User.address@(snapshot) => { println!("address -> {snapshot:?}"); };
56 User.address.city(v) => { println!("city -> {v}"); };
57 User.address.residents(Added(v)) => { println!("+res -> {v}"); };
58 User.address.residents(Removed(v)) => { println!("-res -> {v}"); };
59 );
60 }
61
62 println!("\nCHANGES: {changes:?}");
63}examples/complex.rs (line 149)
93fn main() -> Result<(), Box<dyn std::error::Error>> {
94 /* baseline */
95 let old = Company {
96 name: "Acme Inc.".into(),
97 staff: vec![
98 Account {
99 id: 1,
100 username: "alice".into(),
101 password: "secret".into(),
102 roles: HashSet::from(["admin".into()]),
103 preferences: HashMap::from([("theme".into(), "dark".into())]),
104 address: Address {
105 street: "1 Main".into(),
106 city: "Paris".into(),
107 },
108 },
109 Account {
110 id: 2,
111 username: "bob".into(),
112 password: "hunter2".into(),
113 roles: HashSet::from(["user".into()]),
114 preferences: HashMap::new(),
115 address: Address {
116 street: "99 Broadway".into(),
117 city: "London".into(),
118 },
119 },
120 ],
121 };
122
123 /* edited version */
124 let mut new = old.clone();
125 new.name = "Acme Corp.".into();
126 new.staff[0].address.city = "Berlin".into();
127 new.staff[0].roles.insert("devops".into());
128 new.staff[1].roles.remove("user");
129 new.staff[0]
130 .preferences
131 .insert("notifications".into(), "email".into());
132
133 /* insert + move */
134 let charlie = Account {
135 id: 3,
136 username: "charlie".into(),
137 password: "pwd".into(),
138 roles: HashSet::from(["user".into()]),
139 preferences: HashMap::new(),
140 address: Address {
141 street: "5 High".into(),
142 city: "Madrid".into(),
143 },
144 };
145 new.staff.insert(0, charlie); // AddedAt
146 new.staff.swap(1, 2); // Moved
147
148 println!("Company diff");
149 let diff = diff_changes(&old, &new);
150 dump_company(&diff);
151
152 println!("\n Alice diff");
153 let old_alice = old.staff.iter().find(|a| a.id == 1).unwrap();
154 let new_alice = new.staff.iter().find(|a| a.id == 1).unwrap();
155 let alice_diff = diff_changes(old_alice, new_alice);
156 dump_account(&alice_diff);
157
158 Ok(())
159}