delta_struct/lib.rs
1//! Compute the difference (delta) between two instances of a type, and apply
2//! that difference to a third.
3//!
4//! Deriving [`Delta`] on a struct generates a companion "delta struct" holding
5//! only what changed, plus an implementation of the [`Delta`] trait that knows
6//! how to produce one and how to apply it. Pair it with `serde` and you can
7//! send updates over the wire without resending state that both sides already
8//! agree on.
9//!
10//! # Quick start
11//!
12//! ```
13//! use delta_struct::Delta;
14//!
15//! #[derive(Delta)]
16//! struct Config {
17//! host: String,
18//! port: u16,
19//! }
20//!
21//! let old = Config { host: "localhost".to_string(), port: 80 };
22//! let new = Config { host: "localhost".to_string(), port: 8080 };
23//!
24//! // `Config` gained a companion struct named `ConfigDelta`.
25//! let delta = Delta::delta(old, new).expect("the port changed");
26//! assert_eq!(delta.host, None); // unchanged fields are `None`
27//! assert_eq!(delta.port, Some(8080));
28//!
29//! // Applying the delta to an older copy brings it up to date.
30//! let mut current = Config { host: "localhost".to_string(), port: 80 };
31//! current.apply_delta(delta);
32//! assert_eq!(current.port, 8080);
33//! ```
34//!
35//! Note that a single `use delta_struct::Delta;` imports both the trait and
36//! the derive macro. The trait has to be in scope wherever you derive it — the
37//! generated code refers to `Delta` by that name.
38//!
39//! [`Delta::delta`] returns [`None`] when nothing changed, so
40//! `if let Some(delta) = Delta::delta(old, new)` is the usual way to skip
41//! sending an empty update.
42//!
43//! # Field types
44//!
45//! Every field is diffed according to a *field type*, chosen with
46//! `#[delta_struct(field_type = "...")]`. The default is `"scalar"`, which can
47//! be changed per struct — see [Container attributes](#container-attributes).
48//!
49//! ## `scalar` (the default)
50//!
51//! The field is compared with `!=` and replaced wholesale. In the delta struct
52//! it becomes `Option<T>`: `Some(new_value)` when the two differ, [`None`]
53//! when they don't. Requires `T: PartialEq`.
54//!
55//! ## `unordered`
56//!
57//! The field is treated as a bag of items whose order carries no meaning, so
58//! the delta records only which items came and went. One field becomes two:
59//! `{field}_add` and `{field}_remove`, both `Vec<Item>`.
60//!
61//! ```
62//! use delta_struct::Delta;
63//!
64//! #[derive(Delta)]
65//! struct Device {
66//! #[delta_struct(field_type = "unordered")]
67//! services: Vec<String>,
68//! }
69//!
70//! let old = Device { services: vec!["ssh".to_string(), "http".to_string()] };
71//! let new = Device { services: vec!["http".to_string(), "mqtt".to_string()] };
72//!
73//! let delta = Delta::delta(old, new).unwrap();
74//! assert_eq!(delta.services_add, vec!["mqtt".to_string()]);
75//! assert_eq!(delta.services_remove, vec!["ssh".to_string()]);
76//! ```
77//!
78//! Duplicates are counted rather than deduplicated: diffing `[3, 3]` against
79//! `[3]` removes a single `3`. Any collection works as long as it satisfies
80//! `IntoIterator` (to compute the delta) plus `FromIterator` and `Extend` (to
81//! apply one) and its items are `PartialEq` — [`Vec`] and
82//! [`HashSet`](std::collections::HashSet) both qualify.
83//!
84//! Because matching items are found by linear search, computing a delta over
85//! an `unordered` field costs O(n * m) comparisons. That is fine for the
86//! handful-of-elements collections this is aimed at, and something to keep in
87//! mind for large ones.
88//!
89//! `apply_delta` removes then appends, so for an ordered collection like
90//! [`Vec`] the result is a permutation of the new value, not necessarily the
91//! new value itself. Use `ordered` where that matters.
92//!
93//! ## `ordered`
94//!
95//! The field is diffed positionally with Myers' algorithm, and the delta is a
96//! minimal edit script: a [`SeqDelta`] holding [`Splice`]s that each say
97//! "at this index, drop this many items and put these in their place". Unlike
98//! `unordered`, one source field stays one delta field.
99//!
100//! ```
101//! use delta_struct::{Delta, Splice};
102//!
103//! #[derive(Delta)]
104//! struct Playlist {
105//! #[delta_struct(field_type = "ordered")]
106//! tracks: Vec<String>,
107//! }
108//!
109//! let old = Playlist { tracks: vec!["intro".to_string(), "b".to_string(), "outro".to_string()] };
110//! let new = Playlist { tracks: vec!["intro".to_string(), "x".to_string(), "outro".to_string()] };
111//!
112//! let delta = Delta::delta(old, new).unwrap();
113//! assert_eq!(
114//! delta.tracks.splices,
115//! vec![Splice { at: 1, remove: 1, insert: vec!["x".to_string()] }],
116//! );
117//! ```
118//!
119//! Splice positions index the *old* sequence and arrive sorted and
120//! non-overlapping, so applying one is a single forward pass. Reordering is a
121//! real change here where `unordered` would see none, and applying a delta
122//! reproduces the new sequence exactly, position included.
123//!
124//! The collection needs `IntoIterator` and `FromIterator`, and its items need
125//! **`Hash + Eq`** — a stricter bar than the `PartialEq` the other field types
126//! ask for, because that is what indexing the sequences for Myers requires.
127//! The practical consequence is that a `Vec<f64>` cannot be an `ordered`
128//! field, though it can be `unordered`.
129//!
130//! Turn on the `serde` feature to get `Serialize` and `Deserialize` on
131//! [`SeqDelta`] and [`Splice`]; without it, a delta struct containing an
132//! `ordered` field cannot derive them.
133//!
134//! ## `delta`
135//!
136//! The field is itself diffed recursively, which keeps a nested change from
137//! resending the whole subtree. Requires the field's type to implement
138//! [`Delta`]; the delta struct holds `Option<<T as Delta>::Output>`.
139//!
140//! ```
141//! use delta_struct::Delta;
142//!
143//! #[derive(Delta)]
144//! struct Inner {
145//! a: i32,
146//! b: i32,
147//! }
148//!
149//! #[derive(Delta)]
150//! struct Outer {
151//! #[delta_struct(field_type = "delta")]
152//! inner: Inner,
153//! name: String,
154//! }
155//!
156//! let old = Outer { inner: Inner { a: 1, b: 2 }, name: "x".to_string() };
157//! let new = Outer { inner: Inner { a: 1, b: 3 }, name: "x".to_string() };
158//!
159//! let delta = Delta::delta(old, new).unwrap();
160//! let inner_delta = delta.inner.expect("`b` changed");
161//! assert_eq!(inner_delta.a, None);
162//! assert_eq!(inner_delta.b, Some(3));
163//! ```
164//!
165//! # Container attributes
166//!
167//! `#[delta_struct(...)]` on the struct itself accepts:
168//!
169//! - `default = "..."` — the field type used for fields without their own
170//! `field_type`. Defaults to `"scalar"`.
171//! - `delta_leader = "..."` — tokens to emit immediately above the generated
172//! struct. This is how you attach derives, doc comments, or any other
173//! attribute to a type you never get to write by hand.
174//!
175//! ```
176//! use delta_struct::Delta;
177//!
178//! #[derive(Delta)]
179//! #[delta_struct(
180//! default = "unordered",
181//! delta_leader = "/// The changes to a `Tags`.\n#[derive(Debug)]"
182//! )]
183//! struct Tags {
184//! labels: Vec<String>,
185//! // Opt an individual field back out of the container default.
186//! #[delta_struct(field_type = "scalar")]
187//! revision: u32,
188//! }
189//!
190//! let old = Tags { labels: vec![], revision: 1 };
191//! let new = Tags { labels: vec!["new".to_string()], revision: 2 };
192//! let delta = Delta::delta(old, new).unwrap();
193//! assert_eq!(format!("{:?}", delta.labels_add), r#"["new"]"#);
194//! assert_eq!(delta.revision, Some(2));
195//! ```
196//!
197//! `delta_leader` also works on individual fields, where it decorates the
198//! generated field instead of the generated struct. On an `unordered` field it
199//! is emitted above *both* the `_add` and the `_remove` field, so write it to
200//! read sensibly on each.
201//!
202//! ```
203//! # use delta_struct::Delta;
204//! #[derive(Delta)]
205//! struct Host {
206//! #[delta_struct(delta_leader = "/// The new port, if it moved.")]
207//! port: u16,
208//! }
209//! ```
210//!
211//! # Working with serde
212//!
213//! For everything but `ordered` fields there is no serde integration to
214//! enable; `delta_leader` is the whole story. Put the derives on the generated
215//! struct and it serializes like anything else:
216//!
217//! ```
218//! use delta_struct::Delta;
219//!
220//! #[derive(Delta)]
221//! #[delta_struct(delta_leader = "#[derive(serde::Serialize, serde::Deserialize)]")]
222//! struct Config {
223//! host: String,
224//! port: u16,
225//! }
226//!
227//! let old = Config { host: "localhost".to_string(), port: 80 };
228//! let new = Config { host: "localhost".to_string(), port: 8080 };
229//!
230//! // Sender: there is no message to send at all when nothing changed.
231//! let payload = Delta::delta(old, new).map(|delta| serde_json::to_string(&delta).unwrap());
232//! assert_eq!(payload.as_deref(), Some(r#"{"host":null,"port":8080}"#));
233//!
234//! // Receiver applies it to whatever it already had.
235//! let mut config = Config { host: "localhost".to_string(), port: 80 };
236//! config.apply_delta(serde_json::from_str::<ConfigDelta>(&payload.unwrap()).unwrap());
237//! assert_eq!(config.port, 8080);
238//! ```
239//!
240//! Field-level `delta_leader` carries serde attributes just as well, so
241//! `skip_serializing_if` can keep unchanged fields out of the payload
242//! entirely rather than sending them as `null`:
243//!
244//! ```
245//! use delta_struct::Delta;
246//!
247//! #[derive(Delta)]
248//! #[delta_struct(delta_leader = "#[derive(serde::Serialize)]")]
249//! struct Config {
250//! #[delta_struct(delta_leader = "#[serde(skip_serializing_if = \"Option::is_none\")]")]
251//! host: String,
252//! #[delta_struct(delta_leader = "#[serde(skip_serializing_if = \"Option::is_none\")]")]
253//! port: u16,
254//! }
255//!
256//! let old = Config { host: "localhost".to_string(), port: 80 };
257//! let new = Config { host: "localhost".to_string(), port: 8080 };
258//!
259//! let delta = Delta::delta(old, new).unwrap();
260//! assert_eq!(serde_json::to_string(&delta).unwrap(), r#"{"port":8080}"#);
261//! ```
262//!
263//! # What gets generated
264//!
265//! For `struct Foo`, deriving [`Delta`] emits `struct FooDelta` with the same
266//! visibility as `Foo` and the same generic parameters, carrying over their
267//! bounds and `where` clause as written. All of its fields are
268//! `pub`, and by default it derives nothing at all — reach for `delta_leader`
269//! whenever you need `Debug`, `Clone`, or serde on it. (Likewise if your crate
270//! sets `#![deny(missing_docs)]`: the generated struct and its fields need doc
271//! comments supplied through `delta_leader`.)
272//!
273//! Tuple structs are supported; their delta fields are named `field_0`,
274//! `field_1`, and so on, since tuple-struct syntax has nowhere to hang the
275//! `_add`/`_remove` pairs an `unordered` field needs.
276//!
277//! ```
278//! use delta_struct::Delta;
279//!
280//! #[derive(Delta)]
281//! struct Meters(i32);
282//!
283//! let delta = Delta::delta(Meters(3), Meters(4)).unwrap();
284//! assert_eq!(delta.field_0, Some(4));
285//! ```
286//!
287//! # Limitations
288//!
289//! - **Structs only.** Enums and unions are rejected; there is no obvious
290//! delta for a value that changed variant.
291//! - **Every type parameter gets a `PartialEq` bound** on the generated impl,
292//! whether or not the field that uses it needs one.
293//! - **A unit struct's delta is always [`None`]**, as is that of a struct with
294//! no fields — there is nothing that could differ.
295//! - **`ordered` items need `Hash + Eq`**, so float sequences are out. See
296//! that section above.
297
298#![warn(missing_docs)]
299
300// The derive emits `::delta_struct::…` paths for the runtime items an
301// `ordered` field needs. That path has to resolve inside this crate too, or
302// the crate's own tests could not use its own derive.
303extern crate self as delta_struct;
304
305pub mod seq;
306
307pub use delta_struct_macros::Delta;
308pub use seq::{SeqDelta, Splice};
309
310/// Computing the difference between two values, and applying it to a third.
311///
312/// You will normally derive this rather than implement it — see the
313/// [crate documentation](crate) for the derive's attributes and the shape of
314/// the type it generates. Implement it by hand when you want custom diffing
315/// for a type that other structs then reference with
316/// `#[delta_struct(field_type = "delta")]`.
317pub trait Delta {
318 /// The type describing a difference between two `Self` values.
319 ///
320 /// The derive sets this to the generated `{Self}Delta` struct.
321 type Output;
322
323 /// Computes what it would take to turn `old` into `new`.
324 ///
325 /// Returns [`None`] when the two are equivalent, which lets callers skip
326 /// sending or storing an update that would do nothing. Both values are
327 /// consumed: the delta takes ownership of whatever it needs from `new`.
328 fn delta(old: Self, new: Self) -> Option<Self::Output>;
329
330 /// Applies a delta in place.
331 ///
332 /// Applying the delta from `delta(old, new)` to a value equal to `old`
333 /// yields a value equal to `new` — with the caveat that `unordered` fields
334 /// preserve membership rather than order.
335 fn apply_delta(&mut self, delta: Self::Output);
336}
337#[cfg(test)]
338mod tests {
339 use super::*;
340
341 #[derive(Delta)]
342 #[allow(dead_code)] // The derive is itself the test
343 struct UnitType;
344
345 #[derive(Delta, Clone, Debug, PartialEq, Eq)]
346 #[delta_struct(delta_leader = "#[derive(Clone, Debug, PartialEq, Eq)]")]
347 struct NewType(i32);
348
349 #[derive(Delta)]
350 #[allow(dead_code)] // The derive is itself the test
351 struct NewTypeWithGeneric<T>(T);
352
353 #[derive(Delta)]
354 struct InlineBoundGeneric<T: Clone> {
355 foo: T,
356 bar: bool,
357 }
358
359 #[derive(Delta)]
360 struct WhereClauseGeneric<T>
361 where
362 T: Clone,
363 {
364 foo: T,
365 bar: bool,
366 }
367
368 #[derive(Delta)]
369 struct InlineBoundDeltaField<T: Delta> {
370 #[delta_struct(field_type = "delta")]
371 foo: T,
372 }
373
374 #[derive(Delta)]
375 struct WhereClauseDeltaField<T>
376 where
377 T: Delta,
378 {
379 #[delta_struct(field_type = "delta")]
380 foo: T,
381 }
382
383 #[derive(Delta)]
384 struct SimpleType {
385 #[delta_struct(delta_leader = "/// This is foo.")]
386 foo: i32,
387 bar: bool,
388 }
389
390 #[derive(Delta)]
391 #[allow(dead_code)] // The derive is itself the test
392 struct SimpleTypeWithGeneric<T> {
393 foo: T,
394 bar: bool,
395 }
396
397 #[derive(Delta)]
398 struct SimpleCollectionWithGeneric<T> {
399 #[delta_struct(
400 field_type = "unordered",
401 delta_leader = "/// This the foo type on the delta struct."
402 )]
403 foo: Vec<T>,
404 bar: bool,
405 }
406
407 #[derive(Delta)]
408 struct DeltaRecursion {
409 #[delta_struct(field_type = "delta")]
410 foo: NewType,
411 bar: bool,
412 }
413
414 #[derive(Delta)]
415 #[delta_struct(default = "unordered")]
416 struct AttributeTest {
417 #[delta_struct(field_type = "scalar")]
418 foo: i32,
419 #[delta_struct(field_type = "scalar")]
420 bar: i32,
421 baz: Vec<i32>,
422 }
423
424 #[derive(Delta, Clone, Debug, PartialEq, Eq)]
425 struct AllFieldTypes {
426 #[delta_struct(field_type = "scalar")]
427 scalar: i32,
428 #[delta_struct(field_type = "delta")]
429 delta: NewType,
430 #[delta_struct(field_type = "unordered")]
431 unordered: Vec<i32>,
432 }
433
434 #[derive(Clone, Debug, Delta, PartialEq)]
435 #[allow(dead_code)] // The derive is itself the test
436 struct DeviceConfig {
437 #[delta_struct(field_type = "unordered")]
438 pub services: Vec<String>,
439 #[delta_struct(field_type = "unordered")]
440 pub settings: Vec<String>,
441 pub thumbnail_request: i32,
442 pub speedtest_request: i32,
443 #[delta_struct(field_type = "delta")]
444 pub features: AllFieldTypes,
445 pub deprovision: bool,
446 }
447
448 #[test]
449 fn unordered_with_scalar() {
450 let old = SimpleCollectionWithGeneric {
451 foo: vec![1, 2, 3],
452 bar: false,
453 };
454 let new = SimpleCollectionWithGeneric {
455 foo: vec![3, 4, 5],
456 bar: true,
457 };
458 let delta = Delta::delta(old, new).unwrap();
459 assert_eq!(delta.foo_add, vec![4, 5]);
460 assert_eq!(delta.foo_remove, vec![1, 2]);
461 assert_eq!(delta.bar, Some(true));
462 }
463
464 #[test]
465 fn delta_false_positive_check() {
466 let old = NewType(5);
467 let new = NewType(5);
468 let delta = Delta::delta(old, new);
469 assert!(delta.is_none());
470 }
471
472 #[test]
473 fn scalar_delta_false_positive_check() {
474 let old = SimpleType { foo: 5, bar: false };
475 let new = SimpleType { foo: 5, bar: true };
476 let delta = Delta::delta(old, new).unwrap();
477 assert!(delta.foo.is_none());
478 assert_eq!(delta.bar, Some(true));
479 }
480
481 #[test]
482 fn delta_field() {
483 let old = DeltaRecursion {
484 foo: NewType(5),
485 bar: false,
486 };
487 let new = DeltaRecursion {
488 foo: NewType(6),
489 bar: true,
490 };
491 let delta = Delta::delta(old, new).unwrap();
492 // TODO: Use assert_eq when we build out delta struct
493 // attributes.
494 if let Some(NewTypeDelta { field_0: Some(6) }) = delta.foo {
495 // Do nothing, this is the pass case.
496 } else {
497 panic!();
498 }
499 assert_eq!(delta.bar, Some(true));
500 }
501
502 #[test]
503 fn default_type_respected() {
504 let old = AttributeTest {
505 foo: 5,
506 bar: 4,
507 baz: vec![],
508 };
509 let new = AttributeTest {
510 foo: 5,
511 bar: 4,
512 baz: vec![9, 4, 5],
513 };
514 let delta = Delta::delta(old, new).unwrap();
515 assert!(delta.foo.is_none());
516 assert!(delta.bar.is_none());
517 assert_eq!(delta.baz_add, vec![9, 4, 5]);
518 assert_eq!(delta.baz_remove, Vec::<i32>::new());
519 }
520
521 #[derive(Clone, Debug, Delta, PartialEq)]
522 struct Playlist {
523 #[delta_struct(field_type = "ordered")]
524 tracks: Vec<String>,
525 shuffle: bool,
526 }
527
528 #[derive(Delta)]
529 #[delta_struct(default = "ordered")]
530 struct OrderedByDefault {
531 a: Vec<i32>,
532 b: Vec<i32>,
533 }
534
535 fn playlist(tracks: &[&str], shuffle: bool) -> Playlist {
536 Playlist {
537 tracks: tracks.iter().map(|t| t.to_string()).collect(),
538 shuffle,
539 }
540 }
541
542 #[test]
543 fn ordered_records_position() {
544 let delta = Delta::delta(
545 playlist(&["a", "b", "c"], false),
546 playlist(&["a", "x", "c"], false),
547 )
548 .unwrap();
549 assert_eq!(
550 delta.tracks.splices,
551 vec![Splice {
552 at: 1,
553 remove: 1,
554 insert: vec!["x".to_string()],
555 }]
556 );
557 assert_eq!(delta.shuffle, None);
558 }
559
560 #[test]
561 fn ordered_distinguishes_reorder_from_unordered() {
562 // Reordering is invisible to `unordered` but not to `ordered`.
563 let delta = Delta::delta(playlist(&["a", "b"], false), playlist(&["b", "a"], false));
564 assert!(delta.is_some());
565 }
566
567 #[test]
568 fn ordered_false_positive_check() {
569 let delta = Delta::delta(playlist(&["a", "b"], false), playlist(&["a", "b"], false));
570 assert!(delta.is_none());
571 }
572
573 #[test]
574 fn ordered_apply_round_trips() {
575 let cases: &[(&[&str], &[&str])] = &[
576 (&["a", "b", "c"], &["a", "x", "c"]),
577 (&["a", "b"], &["a", "b", "c"]),
578 (&["b", "c"], &["a", "b", "c"]),
579 (&["a", "b", "c"], &[]),
580 (&[], &["a", "b", "c"]),
581 (&["a", "b", "c", "d", "e"], &["a", "x", "c", "y", "e"]),
582 (&["a", "a", "a", "b"], &["a", "b", "a", "a"]),
583 (&["a", "b", "c"], &["c", "b", "a"]),
584 ];
585 for (old, new) in cases {
586 let mut applied = playlist(old, true);
587 let delta = Delta::delta(playlist(old, false), playlist(new, true)).unwrap();
588 applied.apply_delta(delta);
589 assert_eq!(applied, playlist(new, true), "{:?} -> {:?}", old, new);
590 }
591 }
592
593 #[cfg(feature = "serde")]
594 #[test]
595 fn ordered_delta_serializes() {
596 let delta =
597 Delta::delta(playlist(&["a", "b"], false), playlist(&["a", "c"], false)).unwrap();
598 let json = serde_json::to_string(&delta.tracks).unwrap();
599 assert_eq!(json, r#"{"splices":[{"at":1,"remove":1,"insert":["c"]}]}"#);
600 let round_tripped: SeqDelta<String> = serde_json::from_str(&json).unwrap();
601 let mut target = playlist(&["a", "b"], false);
602 seq::apply(&mut target.tracks, round_tripped);
603 assert_eq!(target.tracks, vec!["a".to_string(), "c".to_string()]);
604 }
605
606 #[test]
607 fn ordered_as_container_default() {
608 let delta = Delta::delta(
609 OrderedByDefault {
610 a: vec![1, 2],
611 b: vec![3],
612 },
613 OrderedByDefault {
614 a: vec![1, 2],
615 b: vec![3, 4],
616 },
617 )
618 .unwrap();
619 assert!(delta.a.is_empty());
620 assert_eq!(
621 delta.b.splices,
622 vec![Splice {
623 at: 1,
624 remove: 0,
625 insert: vec![4],
626 }]
627 );
628 }
629
630 #[test]
631 fn bounded_generics() {
632 let delta = Delta::delta(
633 InlineBoundGeneric { foo: 1, bar: false },
634 InlineBoundGeneric { foo: 2, bar: false },
635 )
636 .unwrap();
637 assert_eq!(delta.foo, Some(2));
638 assert_eq!(delta.bar, None);
639
640 let delta = Delta::delta(
641 WhereClauseGeneric { foo: 1, bar: false },
642 WhereClauseGeneric { foo: 2, bar: false },
643 )
644 .unwrap();
645 assert_eq!(delta.foo, Some(2));
646 assert_eq!(delta.bar, None);
647 }
648
649 #[test]
650 fn bounded_generics_with_delta_field() {
651 let delta = Delta::delta(
652 InlineBoundDeltaField { foo: NewType(1) },
653 InlineBoundDeltaField { foo: NewType(2) },
654 )
655 .unwrap();
656 assert_eq!(delta.foo.unwrap().field_0, Some(2));
657
658 let mut applied = WhereClauseDeltaField { foo: NewType(1) };
659 let delta = Delta::delta(
660 WhereClauseDeltaField { foo: NewType(1) },
661 WhereClauseDeltaField { foo: NewType(2) },
662 )
663 .unwrap();
664 applied.apply_delta(delta);
665 assert_eq!(applied.foo, NewType(2));
666 }
667
668 #[test]
669 fn apply_delta_all_field_types() {
670 let old = AllFieldTypes {
671 scalar: 1,
672 delta: NewType(3),
673 unordered: vec![1, 2, 3, 3],
674 };
675 let new = AllFieldTypes {
676 scalar: 2,
677 delta: NewType(4),
678 unordered: vec![3, 4, 5],
679 };
680 let new_clone = new.clone();
681 let mut old_delta_applied = old.clone();
682 let delta = Delta::delta(old, new);
683 old_delta_applied.apply_delta(delta.unwrap());
684 assert_eq!(new_clone, old_delta_applied);
685 }
686}