loro_internal/delta/
seq.rs

1use enum_as_inner::EnumAsInner;
2use serde::Serialize;
3use std::fmt::Debug;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct Delta<Value, Meta = ()> {
7    pub(crate) vec: Vec<DeltaItem<Value, Meta>>,
8}
9
10impl<V: Serialize, M: Serialize> Serialize for Delta<V, M> {
11    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
12    where
13        S: serde::Serializer,
14    {
15        serializer.collect_seq(self.vec.iter())
16    }
17}
18
19#[derive(Debug, EnumAsInner, Clone, PartialEq, Eq, Serialize)]
20pub enum DeltaItem<Value, Meta> {
21    Retain { retain: usize, attributes: Meta },
22    Insert { insert: Value, attributes: Meta },
23    Delete { delete: usize, attributes: Meta },
24}
25
26#[derive(PartialEq, Debug, Eq)]
27pub enum DeltaType {
28    Retain,
29    Insert,
30    Delete,
31}
32
33/// The metadata of a DeltaItem
34/// If empty metadata is used to override the older one, we will remove the metadata into None
35pub trait Meta: Debug + Clone + PartialEq + Default {
36    fn empty() -> Self {
37        Self::default()
38    }
39    fn is_empty(&self) -> bool;
40
41    /// this is used when composing two [DeltaItem]s with the same length
42    fn compose(&mut self, other: &Self, type_pair: (DeltaType, DeltaType));
43    #[allow(unused)]
44    fn take(&mut self, other: &Self) -> Self {
45        self.clone()
46    }
47
48    fn is_mergeable(&self, other: &Self) -> bool;
49    /// This is used when we merge two [DeltaItem]s.
50    /// And it's guaranteed that [Meta::is_mergeable] is true
51    fn merge(&mut self, other: &Self);
52}
53
54impl Meta for () {
55    fn empty() -> Self {}
56    fn is_empty(&self) -> bool {
57        true
58    }
59
60    fn compose(&mut self, _other: &Self, _type_pair: (DeltaType, DeltaType)) {}
61
62    fn is_mergeable(&self, _other: &Self) -> bool {
63        true
64    }
65
66    fn merge(&mut self, _other: &Self) {}
67}
68
69/// The value of [DeltaItem::Insert]
70pub trait DeltaValue: Debug + Sized {
71    /// the other will be merged into self
72    fn value_extend(&mut self, other: Self) -> Result<(), Self>;
73    /// takes the first number of `length` elements
74    fn take(&mut self, length: usize) -> Self;
75    /// the length of the value
76    fn length(&self) -> usize;
77}
78
79impl<V: DeltaValue, M: Debug> DeltaValue for DeltaItem<V, M> {
80    fn value_extend(&mut self, _other: Self) -> Result<(), Self> {
81        unreachable!()
82    }
83
84    fn take(&mut self, _length: usize) -> Self {
85        unreachable!()
86    }
87
88    fn length(&self) -> usize {
89        match self {
90            DeltaItem::Retain {
91                retain: len,
92                attributes: _,
93            } => *len,
94            DeltaItem::Insert {
95                insert: value,
96                attributes: _,
97            } => value.length(),
98            DeltaItem::Delete {
99                delete: len,
100                attributes: _,
101            } => *len,
102        }
103    }
104}
105
106impl<Value: DeltaValue, M: Meta> DeltaItem<Value, M> {
107    pub fn meta(&self) -> &M {
108        match self {
109            DeltaItem::Insert {
110                attributes: meta, ..
111            } => meta,
112            DeltaItem::Retain {
113                attributes: meta, ..
114            } => meta,
115            DeltaItem::Delete {
116                delete: _,
117                attributes: meta,
118            } => meta,
119        }
120    }
121
122    pub fn meta_mut(&mut self) -> &mut M {
123        match self {
124            DeltaItem::Insert {
125                attributes: meta, ..
126            } => meta,
127            DeltaItem::Retain {
128                attributes: meta, ..
129            } => meta,
130            DeltaItem::Delete {
131                delete: _,
132                attributes: meta,
133            } => meta,
134        }
135    }
136
137    pub fn set_meta(&mut self, meta: M) {
138        match self {
139            DeltaItem::Insert { attributes: m, .. } => *m = meta,
140            DeltaItem::Retain { attributes: m, .. } => *m = meta,
141            DeltaItem::Delete {
142                delete: _,
143                attributes: m,
144            } => *m = meta,
145        }
146    }
147
148    fn type_(&self) -> DeltaType {
149        match self {
150            DeltaItem::Insert { .. } => DeltaType::Insert,
151            DeltaItem::Retain { .. } => DeltaType::Retain,
152            DeltaItem::Delete { .. } => DeltaType::Delete,
153        }
154    }
155
156    pub fn compose_meta(&mut self, other: &Self) {
157        let type_pair = (self.type_(), other.type_());
158        let meta = self.meta_mut();
159        let other_meta = other.meta();
160        Meta::compose(meta, other_meta, type_pair);
161    }
162
163    // change self-length to self.len()-length
164    // and return the taken one.
165    pub(crate) fn take(&mut self, length: usize) -> Self {
166        match self {
167            DeltaItem::Insert {
168                insert: value,
169                attributes: meta,
170            } => {
171                let v = value.take(length);
172                Self::Insert {
173                    insert: v,
174                    attributes: meta.clone(),
175                }
176            }
177            DeltaItem::Retain {
178                retain: len,
179                attributes: meta,
180            } => {
181                *len -= length;
182                Self::Retain {
183                    retain: length,
184                    attributes: meta.clone(),
185                }
186            }
187            DeltaItem::Delete {
188                delete: len,
189                attributes: _,
190            } => {
191                *len -= length;
192                Self::Delete {
193                    delete: length,
194                    // meta may store utf16 length, this take will invalidate it
195                    attributes: M::empty(),
196                }
197            }
198        }
199    }
200
201    pub(crate) fn take_with_meta_ref(&mut self, length: usize, other_meta: &Self) -> Self {
202        match self {
203            DeltaItem::Insert {
204                insert: value,
205                attributes: meta,
206            } => {
207                let v = value.take(length);
208                Self::Insert {
209                    insert: v,
210                    attributes: meta.take(other_meta.meta()),
211                }
212            }
213            DeltaItem::Retain {
214                retain: len,
215                attributes: meta,
216            } => {
217                *len -= length;
218                Self::Retain {
219                    retain: length,
220                    attributes: meta.take(other_meta.meta()),
221                }
222            }
223            DeltaItem::Delete {
224                delete: len,
225                attributes: meta,
226            } => {
227                *len -= length;
228                Self::Delete {
229                    delete: length,
230                    attributes: meta.take(other_meta.meta()),
231                }
232            }
233        }
234    }
235
236    fn insert_inner(self) -> Value {
237        match self {
238            DeltaItem::Insert { insert: value, .. } => value,
239            _ => unreachable!(),
240        }
241    }
242}
243
244#[derive(Debug)]
245pub struct DeltaIterator<V, M: Meta> {
246    // The reversed Vec uses pop() to simulate getting the first element each time
247    ops: Vec<DeltaItem<V, M>>,
248}
249
250impl<V: DeltaValue, M: Meta> DeltaIterator<V, M> {
251    fn new(ops: Vec<DeltaItem<V, M>>) -> Self {
252        Self { ops }
253    }
254
255    #[inline(always)]
256    fn next<L: Into<Option<usize>>>(&mut self, len: L) -> DeltaItem<V, M> {
257        self.next_impl(len.into())
258    }
259
260    fn next_impl(&mut self, len: Option<usize>) -> DeltaItem<V, M> {
261        let length = len.unwrap_or(usize::MAX);
262        let next_op = self.peek_mut();
263        if next_op.is_none() {
264            return DeltaItem::Retain {
265                retain: usize::MAX,
266                attributes: M::empty(),
267            };
268        }
269        let op = next_op.unwrap();
270        let op_length = op.length();
271        if length < op_length {
272            // a part of the peek op
273            op.take(length)
274        } else {
275            self.take_peek().unwrap()
276        }
277    }
278
279    fn next_with_ref(&mut self, len: usize, other: &DeltaItem<V, M>) -> DeltaItem<V, M> {
280        let next_op = self.peek_mut();
281        if next_op.is_none() {
282            return DeltaItem::Retain {
283                retain: other.length(),
284                attributes: M::empty(),
285            };
286        }
287        let op = next_op.unwrap();
288        let op_length = op.length();
289        if len < op_length {
290            // a part of the peek op
291            op.take_with_meta_ref(len, other)
292        } else {
293            self.take_peek().unwrap()
294        }
295    }
296
297    fn next_pair(&mut self, other: &mut Self) -> (DeltaItem<V, M>, DeltaItem<V, M>) {
298        let self_len = self.peek_length();
299        let other_len = other.peek_length();
300        if self_len > other_len {
301            let length = other_len;
302            let other_op = other.next(None);
303            debug_assert_eq!(other_op.length(), length);
304            let this_op = self.next_with_ref(length, &other_op);
305            (this_op, other_op)
306        } else {
307            let length = self_len;
308            let this_op = self.next(None);
309            debug_assert_eq!(this_op.length(), length);
310            let other_op = other.next_with_ref(length, &this_op);
311            (this_op, other_op)
312        }
313    }
314
315    fn peek_mut(&mut self) -> Option<&mut DeltaItem<V, M>> {
316        self.ops.last_mut()
317    }
318
319    fn take_peek(&mut self) -> Option<DeltaItem<V, M>> {
320        self.ops.pop()
321    }
322
323    fn rest(mut self) -> Vec<DeltaItem<V, M>> {
324        self.ops.reverse();
325        self.ops
326    }
327
328    fn has_next(&self) -> bool {
329        !self.ops.is_empty()
330    }
331
332    fn peek(&self) -> Option<&DeltaItem<V, M>> {
333        self.ops.last()
334    }
335
336    fn peek_length(&self) -> usize {
337        if let Some(op) = self.peek() {
338            op.length()
339        } else {
340            usize::MAX
341        }
342    }
343
344    fn peek_is_insert(&self) -> bool {
345        if let Some(op) = self.peek() {
346            op.is_insert()
347        } else {
348            false
349        }
350    }
351
352    fn peek_is_delete(&self) -> bool {
353        if let Some(op) = self.peek() {
354            op.is_delete()
355        } else {
356            false
357        }
358    }
359}
360
361impl<Value: DeltaValue, M: Meta> Delta<Value, M> {
362    pub fn new() -> Self {
363        Self { vec: Vec::new() }
364    }
365
366    pub fn items(&self) -> &[DeltaItem<Value, M>] {
367        &self.vec
368    }
369
370    pub fn inner(self) -> Vec<DeltaItem<Value, M>> {
371        self.vec
372    }
373
374    pub fn retain_with_meta(mut self, len: usize, meta: M) -> Self {
375        if len == 0 {
376            // currently no meta for retain if len == 0
377            return self;
378        }
379
380        self.push(DeltaItem::Retain {
381            retain: len,
382            attributes: meta,
383        });
384        self
385    }
386
387    pub fn insert_with_meta<V: Into<Value>>(mut self, value: V, meta: M) -> Self {
388        self.push(DeltaItem::Insert {
389            insert: value.into(),
390            attributes: meta,
391        });
392        self
393    }
394
395    pub fn delete_with_meta(mut self, len: usize, meta: M) -> Self {
396        self.push(DeltaItem::Delete {
397            delete: len,
398            attributes: meta,
399        });
400        self
401    }
402
403    pub fn delete(mut self, len: usize) -> Self {
404        if len == 0 {
405            return self;
406        }
407        self.push(DeltaItem::Delete {
408            delete: len,
409            attributes: M::empty(),
410        });
411        self
412    }
413
414    pub fn retain(mut self, len: usize) -> Self {
415        if len == 0 {
416            return self;
417        }
418
419        self.push(DeltaItem::Retain {
420            retain: len,
421            attributes: M::empty(),
422        });
423        self
424    }
425
426    pub fn insert<V: Into<Value>>(mut self, value: V) -> Self {
427        self.push(DeltaItem::Insert {
428            insert: value.into(),
429            attributes: M::empty(),
430        });
431        self
432    }
433
434    // If the new_op is merged, return true
435    pub fn push(&mut self, new_op: DeltaItem<Value, M>) -> bool {
436        let mut index = self.vec.len();
437        let last_op = self.vec.pop();
438        if let Some(mut last_op) = last_op {
439            if new_op.is_delete() && last_op.is_delete() {
440                *last_op.as_delete_mut().unwrap().0 += new_op.length();
441                self.vec.push(last_op);
442                return true;
443            }
444            // Since it does not matter if we insert before or after deleting at the same index,
445            // always prefer to insert first
446            if last_op.is_delete() && new_op.is_insert() {
447                index -= 1;
448                let _last_op = self.vec.pop();
449                self.vec.push(last_op);
450                if let Some(_last_op_inner) = _last_op {
451                    last_op = _last_op_inner;
452                } else {
453                    self.vec.insert(0, new_op);
454                    return true;
455                };
456            }
457            if last_op.meta().is_mergeable(new_op.meta()) {
458                if new_op.is_insert() && last_op.is_insert() {
459                    let value = last_op.as_insert_mut().unwrap().0;
460                    let meta = new_op.meta().clone();
461                    match value.value_extend(new_op.insert_inner()) {
462                        Ok(_) => {
463                            last_op.meta_mut().merge(&meta);
464                            self.vec.insert(index - 1, last_op);
465                            return true;
466                        }
467                        Err(inner) => {
468                            self.vec.insert(index - 1, last_op);
469                            self.vec.insert(
470                                index,
471                                DeltaItem::Insert {
472                                    insert: inner,
473                                    attributes: meta,
474                                },
475                            );
476                            return false;
477                        }
478                    }
479                } else if new_op.is_retain() && last_op.is_retain() {
480                    *last_op.as_retain_mut().unwrap().0 += new_op.length();
481                    last_op.meta_mut().merge(new_op.meta());
482                    // self.vec.push(last_op);
483                    self.vec.insert(index - 1, last_op);
484                    return true;
485                }
486            }
487
488            // self.vec.push(last_op);
489            self.vec.insert(index - 1, last_op);
490        }
491        if index == self.vec.len() {
492            self.vec.push(new_op);
493            false
494        } else {
495            self.vec.insert(index, new_op);
496            true
497        }
498    }
499
500    pub fn iter(&self) -> impl Iterator<Item = &DeltaItem<Value, M>> {
501        self.vec.iter()
502    }
503
504    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut DeltaItem<Value, M>> {
505        self.vec.iter_mut()
506    }
507
508    pub fn into_op_iter(self) -> DeltaIterator<Value, M> {
509        DeltaIterator::new(self.vec.into_iter().rev().collect())
510    }
511
512    pub fn len(&self) -> usize {
513        self.vec.len()
514    }
515
516    pub fn is_empty(&self) -> bool {
517        self.len() == 0
518    }
519
520    /// Reference: [Quill Delta](https://github.com/quilljs/delta)
521    // TODO: PERF use &mut self and &other
522    pub fn compose(self, other: Delta<Value, M>) -> Delta<Value, M> {
523        let mut this_iter = self.into_op_iter();
524        let mut other_iter = other.into_op_iter();
525        let mut ops = vec![];
526        let first_other = other_iter.peek();
527        if let Some(first_other) = first_other {
528            // if other.delta starts with retain, we insert corresponding number of inserts from self.delta
529            if first_other.is_retain() && first_other.meta().is_empty() {
530                let mut first_left = first_other.length();
531                let mut first_this = this_iter.peek();
532                while let Some(first_this_inner) = first_this {
533                    if first_this_inner.is_insert() && first_this_inner.length() <= first_left {
534                        first_left -= first_this_inner.length();
535                        let mut op = this_iter.next(None);
536                        op.compose_meta(first_other);
537                        ops.push(op);
538                        first_this = this_iter.peek();
539                    } else {
540                        break;
541                    }
542                }
543                if first_other.length() - first_left > 0 {
544                    other_iter.next(first_other.length() - first_left);
545                }
546            }
547        }
548        let mut delta = Delta { vec: ops };
549        while this_iter.has_next() || other_iter.has_next() {
550            if other_iter.peek_is_insert() {
551                // nothing to compose here
552                delta.push(other_iter.next(None));
553            } else if this_iter.peek_is_delete() {
554                // nothing to compose here
555                delta.push(this_iter.next(None));
556            } else {
557                // possible cases:
558                // 1. this: insert, other: retain
559                // 2. this: retain, other: retain
560                // 3. this: retain, other: delete
561                // 4. this: insert, other: delete
562
563                let (mut this_op, mut other_op) = this_iter.next_pair(&mut other_iter);
564                if other_op.is_retain() {
565                    // 1. this: insert, other: retain
566                    // 2. this: retain, other: retain
567                    this_op.compose_meta(&other_op);
568                    let merged = delta.push(this_op);
569                    let concat_rest = !other_iter.has_next() && !merged;
570                    if concat_rest {
571                        let vec = this_iter.rest();
572                        if vec.is_empty() {
573                            break;
574                        }
575
576                        let rest = Delta { vec };
577                        delta = delta.concat(rest);
578                        break;
579                    }
580                } else if other_op.is_delete() && this_op.is_retain() {
581                    // 3. this: retain, other: delete
582                    other_op.compose_meta(&this_op);
583                    // other deletes the retained text
584                    delta.push(other_op);
585                } else {
586                    // 4. this: insert, other: delete
587                    // nothing to do here, because insert and delete have the same length
588                }
589            }
590        }
591
592        delta.chop()
593    }
594
595    pub(crate) fn concat(mut self, mut other: Self) -> Self {
596        if !other.vec.is_empty() {
597            let other_first = other.vec.remove(0);
598            self.push(other_first);
599            self.vec.extend(other.vec);
600        }
601        self
602    }
603
604    pub fn chop(mut self) -> Self {
605        loop {
606            match self.vec.last() {
607                Some(last_op) if last_op.is_retain() && last_op.meta().is_empty() => {
608                    self.vec.pop();
609                }
610                _ => break,
611            }
612        }
613
614        self
615    }
616
617    pub fn insert_len(&self) -> usize {
618        self.vec
619            .iter()
620            .map(|x| match x {
621                DeltaItem::Insert { insert, .. } => insert.length(),
622                _ => 0,
623            })
624            .sum()
625    }
626}
627
628impl<Value, M> IntoIterator for Delta<Value, M> {
629    type Item = DeltaItem<Value, M>;
630
631    type IntoIter = std::vec::IntoIter<DeltaItem<Value, M>>;
632    fn into_iter(self) -> Self::IntoIter {
633        self.vec.into_iter()
634    }
635}
636
637impl<Value: DeltaValue, M: Meta> Default for Delta<Value, M> {
638    fn default() -> Self {
639        Self::new()
640    }
641}
642
643impl<T: Debug> DeltaValue for Vec<T> {
644    fn value_extend(&mut self, other: Self) -> Result<(), Self> {
645        self.extend(other);
646        Ok(())
647    }
648
649    fn take(&mut self, length: usize) -> Self {
650        let mut new = self.split_off(length);
651        std::mem::swap(self, &mut new);
652        new
653    }
654
655    fn length(&self) -> usize {
656        self.len()
657    }
658}
659
660impl DeltaValue for String {
661    fn value_extend(&mut self, other: Self) -> Result<(), Self> {
662        self.push_str(&other);
663        Ok(())
664    }
665
666    fn take(&mut self, length: usize) -> Self {
667        let mut new = self.split_off(length);
668        std::mem::swap(self, &mut new);
669        new
670    }
671    fn length(&self) -> usize {
672        self.len()
673    }
674}
675
676#[cfg(test)]
677mod test {
678    use super::{Delta, DeltaItem, DeltaType, Meta};
679
680    #[derive(Debug, PartialEq, Clone, Default)]
681    struct TestMeta {
682        bold: Option<Option<bool>>,
683        color: Option<Option<()>>,
684    }
685
686    impl Meta for TestMeta {
687        fn empty() -> Self {
688            TestMeta {
689                bold: None,
690                color: None,
691            }
692        }
693        fn is_empty(&self) -> bool {
694            self.bold.is_none() && self.color.is_none()
695        }
696
697        fn compose(
698            &mut self,
699            other: &Self,
700            (this_type, other_type): (super::DeltaType, super::DeltaType),
701        ) {
702            if this_type != DeltaType::Delete && other_type != DeltaType::Delete {
703                if let Some(other_bold) = other.bold {
704                    self.bold = Some(other_bold);
705                }
706                if let Some(other_color) = other.color {
707                    self.color = Some(other_color);
708                }
709            }
710        }
711
712        fn is_mergeable(&self, other: &Self) -> bool {
713            self == other
714        }
715
716        fn merge(&mut self, _other: &Self) {}
717    }
718
719    type TestDelta = Delta<String, TestMeta>;
720    const BOLD_META: TestMeta = TestMeta {
721        bold: Some(Some(true)),
722        color: None,
723    };
724    const COLOR_META: TestMeta = TestMeta {
725        bold: None,
726        color: Some(Some(())),
727    };
728    const EMPTY_META: TestMeta = TestMeta {
729        bold: Some(None),
730        color: Some(None),
731    };
732    const BOTH_META: TestMeta = TestMeta {
733        bold: Some(Some(true)),
734        color: Some(Some(())),
735    };
736
737    #[test]
738    fn delta_push() {
739        let mut a: Delta<String, ()> = Delta::new().insert("a".to_string());
740        a.push(DeltaItem::Insert {
741            insert: "b".to_string(),
742            attributes: (),
743        });
744        assert_eq!(a, Delta::new().insert("ab".to_string()));
745    }
746
747    #[test]
748    fn delta_compose() {
749        let a: Delta<String, ()> = Delta::new().retain(3).insert("abcde".to_string());
750        let b = Delta::new().retain(5).delete(6);
751        assert_eq!(
752            a.compose(b),
753            Delta::new().retain(3).insert("ab".to_string()).delete(3)
754        );
755
756        let a: Delta<String, ()> = Delta::new().insert("123".to_string());
757        let b = Delta::new().retain(1).insert("123".to_string());
758        assert_eq!(a.compose(b), Delta::new().insert("112323".to_string()));
759    }
760
761    #[test]
762    fn delete_failed() {
763        let a: Delta<String, ()> = Delta::new()
764            .retain(2)
765            .insert("[31354]")
766            .retain(1)
767            .insert("[31354]")
768            .retain(12)
769            .insert("[31354]");
770        let b: Delta<String, ()> = Delta::new().retain(27).delete(3);
771        assert_eq!(
772            a.compose(b),
773            Delta::new()
774                .retain(2)
775                .insert("[31354]")
776                .retain(1)
777                .insert("[31354]")
778                .retain(10)
779                .insert("31354]")
780                .delete(2)
781        );
782    }
783
784    #[test]
785    fn insert_insert() {
786        let a = TestDelta::new().insert("a");
787        let b = TestDelta::new().insert("b");
788        assert_eq!(a.compose(b), TestDelta::new().insert("b").insert("a"));
789    }
790
791    #[test]
792    fn insert_retain() {
793        let a = TestDelta::new().insert("a");
794        let b = TestDelta::new().retain_with_meta(1, BOLD_META);
795        assert_eq!(
796            a.compose(b),
797            TestDelta::new().insert_with_meta("a", BOLD_META)
798        );
799    }
800
801    #[test]
802    fn insert_delete() {
803        let a = TestDelta::new().insert("a");
804        let b = TestDelta::new().delete(1);
805        assert_eq!(a.compose(b), TestDelta::new());
806    }
807
808    #[test]
809    fn delete_insert() {
810        let a = TestDelta::new().delete(1);
811        let b = TestDelta::new().insert("b");
812        assert_eq!(a.compose(b), TestDelta::new().insert("b").delete(1));
813    }
814
815    #[test]
816    fn delete_retain() {
817        let a = TestDelta::new().delete(1);
818        let b = TestDelta::new().retain_with_meta(1, BOLD_META);
819        assert_eq!(
820            a.compose(b),
821            TestDelta::new().delete(1).retain_with_meta(1, BOLD_META)
822        );
823    }
824
825    #[test]
826    fn delete_delete() {
827        let a = TestDelta::new().delete(1);
828        let b = TestDelta::new().delete(1);
829        assert_eq!(a.compose(b), TestDelta::new().delete(2));
830    }
831
832    #[test]
833    fn retain_insert() {
834        let a = TestDelta::new().retain_with_meta(1, BOLD_META);
835        let b = TestDelta::new().insert("b");
836        assert_eq!(
837            a.compose(b),
838            TestDelta::new().insert("b").retain_with_meta(1, BOLD_META)
839        );
840    }
841
842    #[test]
843    fn retain_retain() {
844        let a = TestDelta::new().retain_with_meta(1, BOLD_META);
845        let b = TestDelta::new().retain_with_meta(1, COLOR_META);
846        assert_eq!(
847            a.compose(b),
848            TestDelta::new().retain_with_meta(1, BOTH_META)
849        );
850    }
851
852    #[test]
853    fn retain_delete() {
854        let a = TestDelta::new().retain_with_meta(1, BOLD_META);
855        let b = TestDelta::new().delete(1);
856        assert_eq!(a.compose(b), TestDelta::new().delete(1));
857    }
858
859    #[test]
860    fn delete_entire() {
861        let a = TestDelta::new().retain(4).insert("abcde");
862        let b = TestDelta::new().delete(9);
863        assert_eq!(a.compose(b), TestDelta::new().delete(4));
864    }
865
866    #[test]
867    fn retain_more() {
868        let a = TestDelta::new().insert("abcde");
869        let b = TestDelta::new().retain(10);
870        assert_eq!(a.compose(b), TestDelta::new().insert("abcde"));
871    }
872
873    #[test]
874    fn remove_meta() {
875        let a = TestDelta::new().insert_with_meta("a", BOLD_META);
876        let b = TestDelta::new().retain_with_meta(1, EMPTY_META);
877        assert_eq!(
878            a.compose(b),
879            TestDelta::new().insert_with_meta("a", EMPTY_META)
880        );
881    }
882
883    #[test]
884    fn retain_start_opt() {
885        let a = TestDelta::new()
886            .insert_with_meta("a", BOLD_META)
887            .insert("b")
888            .insert_with_meta("c", BOLD_META)
889            .delete(1);
890        let b = TestDelta::new().retain(3).insert("d");
891        let expect = TestDelta::new()
892            .insert_with_meta("a", BOLD_META)
893            .insert("b")
894            .insert_with_meta("c", BOLD_META)
895            .insert("d")
896            .delete(1);
897        assert_eq!(a.compose(b), expect);
898    }
899
900    #[test]
901    fn retain_start_opt_split() {
902        let a = TestDelta::new()
903            .insert_with_meta("a", BOLD_META)
904            .insert("b")
905            .insert_with_meta("c", BOLD_META)
906            .retain(5)
907            .delete(1);
908        let b = TestDelta::new().retain(4).insert("d");
909        let expect = TestDelta::new()
910            .insert_with_meta("a", BOLD_META)
911            .insert("b")
912            .insert_with_meta("c", BOLD_META)
913            .retain(1)
914            .insert("d")
915            .retain(4)
916            .delete(1);
917        assert_eq!(a.compose(b), expect);
918    }
919
920    #[test]
921    fn retain_end_opt() {
922        let a = TestDelta::new()
923            .insert_with_meta("a", BOLD_META)
924            .insert("b")
925            .insert_with_meta("c", BOLD_META);
926        let b = TestDelta::new().delete(1);
927        let expect = TestDelta::new()
928            .insert("b")
929            .insert_with_meta("c", BOLD_META);
930        assert_eq!(a.compose(b), expect);
931    }
932
933    #[test]
934    fn retain_end_opt_join() {
935        let a = TestDelta::new()
936            .insert_with_meta("a", BOLD_META)
937            .insert("b")
938            .insert_with_meta("c", BOLD_META)
939            .insert("d")
940            .insert_with_meta("e", BOLD_META)
941            .insert("f");
942        let b = TestDelta::new().retain(1).delete(1);
943        let expect = TestDelta::new()
944            .insert_with_meta("ac", BOLD_META)
945            .insert("d")
946            .insert_with_meta("e", BOLD_META)
947            .insert("f");
948        assert_eq!(a.compose(b), expect);
949    }
950}