This commit is contained in:
appflowy 2021-08-13 18:16:52 +08:00
parent cd751a7b15
commit 07268291d1
8 changed files with 206 additions and 133 deletions

View File

@ -60,12 +60,12 @@ impl Document {
pub fn replace(&mut self, interval: Interval, s: &str) -> Result<(), OTError> {
let mut delta = Delta::default();
if !s.is_empty() {
let insert = Builder::insert(s).build();
let insert = OpBuilder::insert(s).build();
delta.add(insert);
}
if !interval.is_empty() {
let delete = Builder::delete(interval.size()).build();
let delete = OpBuilder::delete(interval.size()).build();
delta.add(delete);
}
@ -157,7 +157,7 @@ impl Document {
let new_attributes = attributes;
log::debug!("combine result: {:?}", new_attributes);
let retain = Builder::retain(interval.size())
let retain = OpBuilder::retain(interval.size())
.attributes(new_attributes)
.build();

View File

@ -31,44 +31,8 @@ impl<'a> Cursor<'a> {
cursor
}
fn descend(&mut self, index: usize) {
self.next_iv.start += index;
if self.c_index >= self.next_iv.start {
return;
}
while let Some((o_index, op)) = self.iter.next() {
self.o_index = o_index;
let start = self.c_index;
let end = start + op.length();
let intersect = Interval::new(start, end).intersect(self.next_iv);
if intersect.is_empty() {
self.c_index += op.length();
} else {
self.next_op = Some(op.clone());
break;
}
}
}
pub fn next_interval(&self) -> Interval { self.next_op_interval_with_len(None) }
fn next_op_interval_with_len(&self, force_len: Option<usize>) -> Interval {
let op = self
.next_op
.as_ref()
.unwrap_or(&self.delta.ops[self.o_index]);
let start = self.c_index;
let end = match force_len {
None => self.c_index + op.length(),
Some(force_len) => self.c_index + min(force_len, op.length()),
};
let intersect = Interval::new(start, end).intersect(self.next_iv);
let interval = intersect.translate_neg(start);
interval
}
pub fn next_op_with_len(&mut self, force_len: Option<usize>) -> Option<Operation> {
let mut find_op = None;
let next_op = self.next_op.take();
@ -102,6 +66,46 @@ impl<'a> Cursor<'a> {
pub fn next_op(&mut self) -> Option<Operation> { self.next_op_with_len(None) }
pub fn has_next(&self) -> bool { self.c_index < self.next_iv.end }
fn descend(&mut self, index: usize) {
self.next_iv.start += index;
if self.c_index >= self.next_iv.start {
return;
}
while let Some((o_index, op)) = self.iter.next() {
self.o_index = o_index;
let start = self.c_index;
let end = start + op.length();
let intersect = Interval::new(start, end).intersect(self.next_iv);
if intersect.is_empty() {
self.c_index += op.length();
} else {
self.next_op = Some(op.clone());
break;
}
}
}
pub fn current_op(&self) -> &Operation {
let op = self
.next_op
.as_ref()
.unwrap_or(&self.delta.ops[self.o_index]);
op
}
fn next_op_interval_with_len(&self, force_len: Option<usize>) -> Interval {
let op = self.current_op();
let start = self.c_index;
let end = match force_len {
None => self.c_index + op.length(),
Some(force_len) => self.c_index + min(force_len, op.length()),
};
let intersect = Interval::new(start, end).intersect(self.next_iv);
let interval = intersect.translate_neg(start);
interval
}
}
fn find_next_op<'a>(cursor: &mut Cursor<'a>) -> Option<&'a Operation> {

View File

@ -3,7 +3,12 @@ use crate::{
errors::{ErrorBuilder, OTError, OTErrorCode},
};
use bytecount::num_chars;
use std::{cmp::Ordering, fmt, iter::FromIterator, str::FromStr};
use std::{
cmp::{min, Ordering},
fmt,
iter::FromIterator,
str::FromStr,
};
#[derive(Clone, Debug, PartialEq)]
pub struct Delta {
@ -86,7 +91,7 @@ impl Delta {
if let Some(Operation::Delete(n_last)) = self.ops.last_mut() {
*n_last += n;
} else {
self.ops.push(Builder::delete(n).build());
self.ops.push(OpBuilder::delete(n).build());
}
}
@ -107,10 +112,10 @@ impl Delta {
},
[.., op_last @ Operation::Delete(_)] => {
let new_last = op_last.clone();
*op_last = Builder::insert(s).attributes(attrs).build();
*op_last = OpBuilder::insert(s).attributes(attrs).build();
Some(new_last)
},
_ => Some(Builder::insert(s).attributes(attrs).build()),
_ => Some(OpBuilder::insert(s).attributes(attrs).build()),
};
match new_last {
@ -131,10 +136,41 @@ impl Delta {
self.ops.push(new_op);
}
} else {
self.ops.push(Builder::retain(n).attributes(attrs).build());
self.ops
.push(OpBuilder::retain(n).attributes(attrs).build());
}
}
pub fn compose2(&self, other: &Self) -> Result<Self, OTError> {
let mut new_delta = Delta::default();
let mut iter_1 = DeltaIter::new(self);
let mut iter_2 = DeltaIter::new(other);
while iter_1.has_next() || iter_2.has_next() {
if iter_2.is_next_insert() {
new_delta.add(iter_2.next_op().unwrap());
continue;
}
if iter_1.is_next_Delete() {
new_delta.add(iter_1.next_op().unwrap());
continue;
}
let length = min(iter_1.next_op_len(), iter_2.next_op_len());
let op1 = iter_1
.next_op_with_len(length)
.unwrap_or(OpBuilder::retain(length).build());
let op2 = iter_2
.next_op_with_len(length)
.unwrap_or(OpBuilder::retain(length).build());
debug_assert!(op1.length())
}
Ok(new_delta)
}
/// Merges the operation with `other` into one operation while preserving
/// the changes of both. Or, in other words, for each input string S and a
/// pair of consecutive operations A and B.
@ -182,7 +218,7 @@ impl Delta {
Ordering::Less => {
new_delta.retain(retain.n, composed_attrs);
next_op2 = Some(
Builder::retain(o_retain.n - retain.n)
OpBuilder::retain(o_retain.n - retain.n)
.attributes(o_retain.attributes.clone())
.build(),
);
@ -195,7 +231,7 @@ impl Delta {
},
std::cmp::Ordering::Greater => {
new_delta.retain(o_retain.n, composed_attrs);
next_op1 = Some(Builder::retain(retain.n - o_retain.n).build());
next_op1 = Some(OpBuilder::retain(retain.n - o_retain.n).build());
next_op2 = ops2.next();
},
}
@ -204,7 +240,7 @@ impl Delta {
match (num_chars(insert.as_bytes()) as usize).cmp(o_num) {
Ordering::Less => {
next_op2 = Some(
Builder::delete(*o_num - num_chars(insert.as_bytes()) as usize)
OpBuilder::delete(*o_num - num_chars(insert.as_bytes()) as usize)
.attributes(insert.attributes.clone())
.build(),
);
@ -216,7 +252,7 @@ impl Delta {
},
Ordering::Greater => {
next_op1 = Some(
Builder::insert(
OpBuilder::insert(
&insert.chars().skip(*o_num as usize).collect::<String>(),
)
.build(),
@ -239,7 +275,7 @@ impl Delta {
Ordering::Less => {
new_delta.insert(&insert.s, composed_attrs.clone());
next_op2 = Some(
Builder::retain(o_retain.n - insert.num_chars())
OpBuilder::retain(o_retain.n - insert.num_chars())
.attributes(o_retain.attributes.clone())
.build(),
);
@ -256,7 +292,7 @@ impl Delta {
&chars.take(o_retain.n as usize).collect::<String>(),
composed_attrs,
);
next_op1 = Some(Builder::insert(&chars.collect::<String>()).build());
next_op1 = Some(OpBuilder::insert(&chars.collect::<String>()).build());
next_op2 = ops2.next();
},
}
@ -265,7 +301,7 @@ impl Delta {
match retain.cmp(&o_num) {
Ordering::Less => {
new_delta.delete(retain.n);
next_op2 = Some(Builder::delete(*o_num - retain.n).build());
next_op2 = Some(OpBuilder::delete(*o_num - retain.n).build());
next_op1 = ops1.next();
},
Ordering::Equal => {
@ -275,7 +311,7 @@ impl Delta {
},
Ordering::Greater => {
new_delta.delete(*o_num);
next_op1 = Some(Builder::retain(retain.n - *o_num).build());
next_op1 = Some(OpBuilder::retain(retain.n - *o_num).build());
next_op2 = ops2.next();
},
}
@ -334,7 +370,7 @@ impl Delta {
Ordering::Less => {
a_prime.retain(retain.n, composed_attrs.clone());
b_prime.retain(retain.n, composed_attrs.clone());
next_op2 = Some(Builder::retain(o_retain.n - retain.n).build());
next_op2 = Some(OpBuilder::retain(o_retain.n - retain.n).build());
next_op1 = ops1.next();
},
Ordering::Equal => {
@ -346,14 +382,14 @@ impl Delta {
Ordering::Greater => {
a_prime.retain(o_retain.n, composed_attrs.clone());
b_prime.retain(o_retain.n, composed_attrs.clone());
next_op1 = Some(Builder::retain(retain.n - o_retain.n).build());
next_op1 = Some(OpBuilder::retain(retain.n - o_retain.n).build());
next_op2 = ops2.next();
},
};
},
(Some(Operation::Delete(i)), Some(Operation::Delete(j))) => match i.cmp(&j) {
Ordering::Less => {
next_op2 = Some(Builder::delete(*j - *i).build());
next_op2 = Some(OpBuilder::delete(*j - *i).build());
next_op1 = ops1.next();
},
Ordering::Equal => {
@ -361,7 +397,7 @@ impl Delta {
next_op2 = ops2.next();
},
Ordering::Greater => {
next_op1 = Some(Builder::delete(*i - *j).build());
next_op1 = Some(OpBuilder::delete(*i - *j).build());
next_op2 = ops2.next();
},
},
@ -369,7 +405,7 @@ impl Delta {
match i.cmp(&o_retain) {
Ordering::Less => {
a_prime.delete(*i);
next_op2 = Some(Builder::retain(o_retain.n - *i).build());
next_op2 = Some(OpBuilder::retain(o_retain.n - *i).build());
next_op1 = ops1.next();
},
Ordering::Equal => {
@ -379,7 +415,7 @@ impl Delta {
},
Ordering::Greater => {
a_prime.delete(o_retain.n);
next_op1 = Some(Builder::delete(*i - o_retain.n).build());
next_op1 = Some(OpBuilder::delete(*i - o_retain.n).build());
next_op2 = ops2.next();
},
};
@ -388,7 +424,7 @@ impl Delta {
match retain.cmp(&j) {
Ordering::Less => {
b_prime.delete(retain.n);
next_op2 = Some(Builder::delete(*j - retain.n).build());
next_op2 = Some(OpBuilder::delete(*j - retain.n).build());
next_op1 = ops1.next();
},
Ordering::Equal => {
@ -398,7 +434,7 @@ impl Delta {
},
Ordering::Greater => {
b_prime.delete(*j);
next_op1 = Some(Builder::retain(retain.n - *j).build());
next_op1 = Some(OpBuilder::retain(retain.n - *j).build());
next_op2 = ops2.next();
},
};

View File

@ -37,6 +37,12 @@ impl<'a> DeltaIter<'a> {
}
pub fn has_next(&self) -> bool { self.cursor.has_next() }
pub fn is_next_insert(&self) -> bool { self.cursor.current_op().is_insert() }
pub fn is_next_retain(&self) -> bool { self.cursor.current_op().is_retain() }
pub fn is_next_delete(&self) -> bool { self.cursor.current_op().is_delete() }
}
impl<'a> Iterator for DeltaIter<'a> {

View File

@ -1,25 +1,25 @@
use crate::core::{Attributes, Operation};
pub struct Builder {
pub struct OpBuilder {
ty: Operation,
attrs: Attributes,
}
impl Builder {
pub fn new(ty: Operation) -> Builder {
Builder {
impl OpBuilder {
pub fn new(ty: Operation) -> OpBuilder {
OpBuilder {
ty,
attrs: Attributes::default(),
}
}
pub fn retain(n: usize) -> Builder { Builder::new(Operation::Retain(n.into())) }
pub fn retain(n: usize) -> OpBuilder { OpBuilder::new(Operation::Retain(n.into())) }
pub fn delete(n: usize) -> Builder { Builder::new(Operation::Delete(n)) }
pub fn delete(n: usize) -> OpBuilder { OpBuilder::new(Operation::Delete(n)) }
pub fn insert(s: &str) -> Builder { Builder::new(Operation::Insert(s.into())) }
pub fn insert(s: &str) -> OpBuilder { OpBuilder::new(Operation::Insert(s.into())) }
pub fn attributes(mut self, attrs: Attributes) -> Builder {
pub fn attributes(mut self, attrs: Attributes) -> OpBuilder {
self.attrs = attrs;
self
}

View File

@ -1,4 +1,4 @@
use crate::core::{Attribute, Attributes, Builder, Interval};
use crate::core::{Attribute, Attributes, Interval, OpBuilder};
use bytecount::num_chars;
use serde::__private::Formatter;
use std::{
@ -68,22 +68,22 @@ impl Operation {
let mut right = None;
match self {
Operation::Delete(n) => {
left = Some(Builder::delete(index).build());
right = Some(Builder::delete(*n - index).build());
left = Some(OpBuilder::delete(index).build());
right = Some(OpBuilder::delete(*n - index).build());
},
Operation::Retain(retain) => {
left = Some(Builder::delete(index).build());
right = Some(Builder::delete(retain.n - index).build());
left = Some(OpBuilder::delete(index).build());
right = Some(OpBuilder::delete(retain.n - index).build());
},
Operation::Insert(insert) => {
let attributes = self.get_attributes();
left = Some(
Builder::insert(&insert.s[0..index])
OpBuilder::insert(&insert.s[0..index])
.attributes(attributes.clone())
.build(),
);
right = Some(
Builder::insert(&insert.s[index..insert.num_chars()])
OpBuilder::insert(&insert.s[index..insert.num_chars()])
.attributes(attributes)
.build(),
);
@ -95,16 +95,16 @@ impl Operation {
pub fn shrink(&self, interval: Interval) -> Option<Operation> {
let op = match self {
Operation::Delete(n) => Builder::delete(min(*n, interval.size())).build(),
Operation::Retain(retain) => Builder::retain(min(retain.n, interval.size()))
Operation::Delete(n) => OpBuilder::delete(min(*n, interval.size())).build(),
Operation::Retain(retain) => OpBuilder::retain(min(retain.n, interval.size()))
.attributes(retain.attributes.clone())
.build(),
Operation::Insert(insert) => {
if interval.start > insert.s.len() {
Builder::insert("").build()
OpBuilder::insert("").build()
} else {
let s = &insert.s[interval.start..min(interval.end, insert.s.len())];
Builder::insert(s)
OpBuilder::insert(s)
.attributes(insert.attributes.clone())
.build()
}
@ -116,6 +116,27 @@ impl Operation {
false => Some(op),
}
}
pub fn is_delete(&self) -> bool {
if let Operation::Delete(_) = self {
return true;
}
false
}
pub fn is_insert(&self) -> bool {
if let Operation::Insert(_) = self {
return true;
}
false
}
pub fn is_retain(&self) -> bool {
if let Operation::Retain(_) = self {
return true;
}
false
}
}
impl fmt::Display for Operation {
@ -167,7 +188,7 @@ impl Retain {
self.n += n;
None
} else {
Some(Builder::retain(n).attributes(attributes).build())
Some(OpBuilder::retain(n).attributes(attributes).build())
}
}
@ -231,7 +252,7 @@ impl Insert {
self.s += s;
None
} else {
Some(Builder::insert(s).attributes(attributes).build())
Some(OpBuilder::insert(s).attributes(attributes).build())
}
}
}

View File

@ -8,8 +8,8 @@ use helper::*;
#[test]
fn delta_get_ops_in_interval_1() {
let mut delta = Delta::default();
let insert_a = Builder::insert("123").build();
let insert_b = Builder::insert("4").build();
let insert_a = OpBuilder::insert("123").build();
let insert_b = OpBuilder::insert("4").build();
delta.add(insert_a.clone());
delta.add(insert_b.clone());
@ -21,10 +21,10 @@ fn delta_get_ops_in_interval_1() {
#[test]
fn delta_get_ops_in_interval_2() {
let mut delta = Delta::default();
let insert_a = Builder::insert("123").build();
let insert_b = Builder::insert("4").build();
let insert_c = Builder::insert("5").build();
let retain_a = Builder::retain(3).build();
let insert_a = OpBuilder::insert("123").build();
let insert_b = OpBuilder::insert("4").build();
let insert_c = OpBuilder::insert("5").build();
let retain_a = OpBuilder::retain(3).build();
delta.add(insert_a.clone());
delta.add(retain_a.clone());
@ -33,12 +33,12 @@ fn delta_get_ops_in_interval_2() {
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(0, 2)).ops(),
vec![Builder::insert("12").build()]
vec![OpBuilder::insert("12").build()]
);
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(1, 3)).ops(),
vec![Builder::insert("23").build()]
vec![OpBuilder::insert("23").build()]
);
assert_eq!(
@ -48,7 +48,7 @@ fn delta_get_ops_in_interval_2() {
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(0, 4)).ops(),
vec![insert_a.clone(), Builder::retain(1).build()]
vec![insert_a.clone(), OpBuilder::retain(1).build()]
);
assert_eq!(
@ -65,20 +65,20 @@ fn delta_get_ops_in_interval_2() {
#[test]
fn delta_get_ops_in_interval_3() {
let mut delta = Delta::default();
let insert_a = Builder::insert("123456").build();
let insert_a = OpBuilder::insert("123456").build();
delta.add(insert_a.clone());
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(3, 5)).ops(),
vec![Builder::insert("45").build()]
vec![OpBuilder::insert("45").build()]
);
}
#[test]
fn delta_get_ops_in_interval_4() {
let mut delta = Delta::default();
let insert_a = Builder::insert("12").build();
let insert_b = Builder::insert("34").build();
let insert_c = Builder::insert("56").build();
let insert_a = OpBuilder::insert("12").build();
let insert_b = OpBuilder::insert("34").build();
let insert_c = OpBuilder::insert("56").build();
delta.ops.push(insert_a.clone());
delta.ops.push(insert_b.clone());
@ -99,20 +99,26 @@ fn delta_get_ops_in_interval_4() {
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(2, 5)).ops(),
vec![Builder::insert("34").build(), Builder::insert("5").build()]
vec![
OpBuilder::insert("34").build(),
OpBuilder::insert("5").build()
]
);
}
#[test]
fn delta_get_ops_in_interval_5() {
let mut delta = Delta::default();
let insert_a = Builder::insert("123456").build();
let insert_b = Builder::insert("789").build();
let insert_a = OpBuilder::insert("123456").build();
let insert_b = OpBuilder::insert("789").build();
delta.ops.push(insert_a.clone());
delta.ops.push(insert_b.clone());
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(4, 8)).ops(),
vec![Builder::insert("56").build(), Builder::insert("78").build()]
vec![
OpBuilder::insert("56").build(),
OpBuilder::insert("78").build()
]
);
// assert_eq!(
@ -124,81 +130,81 @@ fn delta_get_ops_in_interval_5() {
#[test]
fn delta_get_ops_in_interval_6() {
let mut delta = Delta::default();
let insert_a = Builder::insert("12345678").build();
let insert_a = OpBuilder::insert("12345678").build();
delta.add(insert_a.clone());
assert_eq!(
DeltaIter::from_interval(&delta, Interval::new(4, 6)).ops(),
vec![Builder::insert("56").build()]
vec![OpBuilder::insert("56").build()]
);
}
#[test]
fn delta_get_ops_in_interval_7() {
let mut delta = Delta::default();
let insert_a = Builder::insert("12345").build();
let retain_a = Builder::retain(3).build();
let insert_a = OpBuilder::insert("12345").build();
let retain_a = OpBuilder::retain(3).build();
delta.add(insert_a.clone());
delta.add(retain_a.clone());
let mut iter_1 = DeltaIter::new(&delta);
iter_1.seek::<CharMetric>(2).unwrap();
assert_eq!(iter_1.next_op().unwrap(), Builder::insert("345").build());
assert_eq!(iter_1.next_op().unwrap(), Builder::retain(3).build());
assert_eq!(iter_1.next_op().unwrap(), OpBuilder::insert("345").build());
assert_eq!(iter_1.next_op().unwrap(), OpBuilder::retain(3).build());
let mut iter_2 = DeltaIter::new(&delta);
assert_eq!(
iter_2.next_op_with_len(2).unwrap(),
Builder::insert("12").build()
OpBuilder::insert("12").build()
);
assert_eq!(iter_2.next_op().unwrap(), Builder::insert("345").build());
assert_eq!(iter_2.next_op().unwrap(), OpBuilder::insert("345").build());
assert_eq!(iter_2.next_op().unwrap(), Builder::retain(3).build());
assert_eq!(iter_2.next_op().unwrap(), OpBuilder::retain(3).build());
}
#[test]
fn delta_seek_1() {
let mut delta = Delta::default();
let insert_a = Builder::insert("12345").build();
let retain_a = Builder::retain(3).build();
let insert_a = OpBuilder::insert("12345").build();
let retain_a = OpBuilder::retain(3).build();
delta.add(insert_a.clone());
delta.add(retain_a.clone());
let mut iter = DeltaIter::new(&delta);
iter.seek::<OpMetric>(1).unwrap();
assert_eq!(iter.next_op().unwrap(), Builder::retain(3).build());
assert_eq!(iter.next_op().unwrap(), OpBuilder::retain(3).build());
}
#[test]
fn delta_seek_2() {
let mut delta = Delta::default();
delta.add(Builder::insert("12345").build());
delta.add(OpBuilder::insert("12345").build());
let mut iter = DeltaIter::new(&delta);
assert_eq!(
iter.next_op_with_len(1).unwrap(),
Builder::insert("1").build()
OpBuilder::insert("1").build()
);
}
#[test]
fn delta_seek_3() {
let mut delta = Delta::default();
delta.add(Builder::insert("12345").build());
delta.add(OpBuilder::insert("12345").build());
let mut iter = DeltaIter::new(&delta);
assert_eq!(
iter.next_op_with_len(2).unwrap(),
Builder::insert("12").build()
OpBuilder::insert("12").build()
);
assert_eq!(
iter.next_op_with_len(2).unwrap(),
Builder::insert("34").build()
OpBuilder::insert("34").build()
);
assert_eq!(
iter.next_op_with_len(2).unwrap(),
Builder::insert("5").build()
OpBuilder::insert("5").build()
);
assert_eq!(iter.next_op_with_len(1), None);
@ -207,30 +213,30 @@ fn delta_seek_3() {
#[test]
fn delta_seek_4() {
let mut delta = Delta::default();
delta.add(Builder::insert("12345").build());
delta.add(OpBuilder::insert("12345").build());
let mut iter = DeltaIter::new(&delta);
iter.seek::<CharMetric>(3);
assert_eq!(
iter.next_op_with_len(2).unwrap(),
Builder::insert("45").build()
OpBuilder::insert("45").build()
);
}
#[test]
fn delta_next_op_len_test() {
let mut delta = Delta::default();
delta.add(Builder::insert("12345").build());
delta.add(OpBuilder::insert("12345").build());
let mut iter = DeltaIter::new(&delta);
iter.seek::<CharMetric>(3);
assert_eq!(iter.next_op_len(), 2);
assert_eq!(
iter.next_op_with_len(1).unwrap(),
Builder::insert("4").build()
OpBuilder::insert("4").build()
);
assert_eq!(iter.next_op_len(), 1);
assert_eq!(iter.next_op().unwrap(), Builder::insert("5").build());
assert_eq!(iter.next_op().unwrap(), OpBuilder::insert("5").build());
}
#[test]
@ -348,22 +354,22 @@ fn ops_merging() {
assert_eq!(delta.ops.len(), 0);
delta.retain(2, Attributes::default());
assert_eq!(delta.ops.len(), 1);
assert_eq!(delta.ops.last(), Some(&Builder::retain(2).build()));
assert_eq!(delta.ops.last(), Some(&OpBuilder::retain(2).build()));
delta.retain(3, Attributes::default());
assert_eq!(delta.ops.len(), 1);
assert_eq!(delta.ops.last(), Some(&Builder::retain(5).build()));
assert_eq!(delta.ops.last(), Some(&OpBuilder::retain(5).build()));
delta.insert("abc", Attributes::default());
assert_eq!(delta.ops.len(), 2);
assert_eq!(delta.ops.last(), Some(&Builder::insert("abc").build()));
assert_eq!(delta.ops.last(), Some(&OpBuilder::insert("abc").build()));
delta.insert("xyz", Attributes::default());
assert_eq!(delta.ops.len(), 2);
assert_eq!(delta.ops.last(), Some(&Builder::insert("abcxyz").build()));
assert_eq!(delta.ops.last(), Some(&OpBuilder::insert("abcxyz").build()));
delta.delete(1);
assert_eq!(delta.ops.len(), 3);
assert_eq!(delta.ops.last(), Some(&Builder::delete(1).build()));
assert_eq!(delta.ops.last(), Some(&OpBuilder::delete(1).build()));
delta.delete(1);
assert_eq!(delta.ops.len(), 3);
assert_eq!(delta.ops.last(), Some(&Builder::delete(2).build()));
assert_eq!(delta.ops.last(), Some(&OpBuilder::delete(2).build()));
}
#[test]
fn is_noop() {
@ -453,11 +459,11 @@ fn delta_transform_test() {
#[test]
fn delta_invert_no_attribute_delta() {
let mut delta = Delta::default();
delta.add(Builder::insert("123").build());
delta.add(OpBuilder::insert("123").build());
let mut change = Delta::default();
change.add(Builder::retain(3).build());
change.add(Builder::insert("456").build());
change.add(OpBuilder::retain(3).build());
change.add(OpBuilder::insert("456").build());
let undo = change.invert(&delta);
let new_delta = delta.compose(&change).unwrap();

View File

@ -3,7 +3,7 @@ use flowy_ot::core::*;
#[test]
fn operation_insert_serialize_test() {
let attributes = AttrsBuilder::new().bold(true).italic(true).build();
let operation = Builder::insert("123").attributes(attributes).build();
let operation = OpBuilder::insert("123").attributes(attributes).build();
let json = serde_json::to_string(&operation).unwrap();
eprintln!("{}", json);
@ -33,7 +33,7 @@ fn delta_serialize_test() {
let mut delta = Delta::default();
let attributes = AttrsBuilder::new().bold(true).italic(true).build();
let retain = Builder::insert("123").attributes(attributes).build();
let retain = OpBuilder::insert("123").attributes(attributes).build();
delta.add(retain);
delta.add(Operation::Retain(5.into()));