diff --git a/rust-lib/flowy-ot/src/client/document.rs b/rust-lib/flowy-ot/src/client/document.rs index 9a94202c78..12c0f8c972 100644 --- a/rust-lib/flowy-ot/src/client/document.rs +++ b/rust-lib/flowy-ot/src/client/document.rs @@ -50,8 +50,10 @@ impl Document { // .view // .format(&self.delta, attribute.clone(), interval) // .unwrap(); - // let a = self.delta.compose(&format_delta).unwrap(); - // println!("{:?}", a); + // + // self.delta = self.record_change(&format_delta)?; + // Ok(()) + self.update_with_attribute(attribute, interval) } diff --git a/rust-lib/flowy-ot/src/client/view/format_ext.rs b/rust-lib/flowy-ot/src/client/view/format_ext.rs index 52fd7173ec..8eac24af9e 100644 --- a/rust-lib/flowy-ot/src/client/view/format_ext.rs +++ b/rust-lib/flowy-ot/src/client/view/format_ext.rs @@ -86,7 +86,7 @@ impl FormatExt for ResolveInlineFormatExt { let len = interval.size(); while cur < len && iter.has_next() { - let some_op = iter.next_op_with_length(len - cur); + let some_op = iter.next_op_with_len(len - cur); if some_op.is_none() { return Some(new_delta); } diff --git a/rust-lib/flowy-ot/src/core/delta/cursor.rs b/rust-lib/flowy-ot/src/core/delta/cursor.rs index c173ae04b8..98d2ba3d53 100644 --- a/rust-lib/flowy-ot/src/core/delta/cursor.rs +++ b/rust-lib/flowy-ot/src/core/delta/cursor.rs @@ -2,7 +2,7 @@ use crate::{ core::{Delta, Interval, Operation}, errors::{ErrorBuilder, OTError, OTErrorCode}, }; -use std::{cmp::min, slice::Iter}; +use std::{cmp::min, iter::Enumerate, slice::Iter}; #[derive(Debug)] pub struct Cursor<'a> { @@ -11,7 +11,7 @@ pub struct Cursor<'a> { pub(crate) next_iv: Interval, pub(crate) c_index: usize, pub(crate) o_index: usize, - iter: Iter<'a, Operation>, + iter: Enumerate>, next_op: Option, } @@ -24,7 +24,7 @@ impl<'a> Cursor<'a> { next_iv: interval, c_index: 0, o_index: 0, - iter: delta.ops.iter(), + iter: delta.ops.iter().enumerate(), next_op: None, }; cursor.descend(0); @@ -33,12 +33,12 @@ impl<'a> Cursor<'a> { fn descend(&mut self, index: usize) { self.next_iv.start += index; + if self.c_index >= self.next_iv.start { return; } - - while let Some(op) = self.iter.next() { - self.o_index += 1; + 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); @@ -51,50 +51,69 @@ impl<'a> Cursor<'a> { } } - pub fn next_op_with_length(&mut self, length: Option) -> Option { + pub fn next_interval(&self) -> Interval { self.next_op_interval_with_len(None) } + + fn next_op_interval_with_len(&self, force_len: Option) -> 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) -> Option { let mut find_op = None; let next_op = self.next_op.take(); let mut next_op = next_op.as_ref(); + if next_op.is_none() { - next_op = self.iter.next(); - self.o_index += 1; + next_op = find_next_op(self); } while find_op.is_none() && next_op.is_some() { - let op = next_op.unwrap(); - let start = self.c_index; - let end = match length { - None => self.c_index + op.length(), - Some(length) => self.c_index + min(length, op.length()), - }; - let intersect = Interval::new(start, end).intersect(self.next_iv); - let interval = intersect.translate_neg(start); - - let op_interval = Interval::new(0, op.length()); - let suffix = op_interval.suffix(interval); - + let op = next_op.take().unwrap(); + let interval = self.next_op_interval_with_len(force_len); find_op = op.shrink(interval); + let suffix = Interval::new(0, op.length()).suffix(interval); if !suffix.is_empty() { self.next_op = op.shrink(suffix); } - self.c_index = intersect.end; - self.next_iv.start = intersect.end; + self.c_index += interval.end; + self.next_iv.start = self.c_index; if find_op.is_none() { - next_op = self.iter.next(); + next_op = find_next_op(self); } } find_op } - pub fn next_op(&mut self) -> Option { self.next_op_with_length(None) } + pub fn next_op(&mut self) -> Option { self.next_op_with_len(None) } pub fn has_next(&self) -> bool { self.c_index < self.next_iv.end } } +fn find_next_op<'a>(cursor: &mut Cursor<'a>) -> Option<&'a Operation> { + match cursor.iter.next() { + None => None, + Some((o_index, op)) => { + cursor.o_index = o_index; + Some(op) + }, + } +} + type SeekResult = Result<(), OTError>; pub trait Metric { fn seek(cursor: &mut Cursor, index: usize) -> SeekResult; @@ -107,7 +126,7 @@ impl Metric for OpMetric { let _ = check_bound(cursor.o_index, index)?; let mut temp_cursor = Cursor::new(cursor.delta, cursor.origin_iv); let mut offset = 0; - while let Some(op) = temp_cursor.iter.next() { + while let Some((_, op)) = temp_cursor.iter.next() { offset += op.length(); if offset > index { break; @@ -123,7 +142,7 @@ pub struct CharMetric {} impl Metric for CharMetric { fn seek(cursor: &mut Cursor, index: usize) -> SeekResult { let _ = check_bound(cursor.c_index, index)?; - let _ = cursor.next_op_with_length(Some(index)); + let _ = cursor.next_op_with_len(Some(index)); Ok(()) } } diff --git a/rust-lib/flowy-ot/src/core/delta/iterator.rs b/rust-lib/flowy-ot/src/core/delta/iterator.rs index 952e50cd3f..5e88ff4f4f 100644 --- a/rust-lib/flowy-ot/src/core/delta/iterator.rs +++ b/rust-lib/flowy-ot/src/core/delta/iterator.rs @@ -25,8 +25,10 @@ impl<'a> DeltaIter<'a> { pub fn next_op(&mut self) -> Option { self.cursor.next_op() } - pub fn next_op_with_length(&mut self, length: usize) -> Option { - self.cursor.next_op_with_length(Some(length)) + pub fn next_op_len(&self) -> usize { self.cursor.next_interval().size() } + + pub fn next_op_with_len(&mut self, length: usize) -> Option { + self.cursor.next_op_with_len(Some(length)) } pub fn seek(&mut self, index: usize) -> Result<(), OTError> { diff --git a/rust-lib/flowy-ot/tests/attribute_test.rs b/rust-lib/flowy-ot/tests/attribute_test.rs index 5f44e22edc..b3bde149bf 100644 --- a/rust-lib/flowy-ot/tests/attribute_test.rs +++ b/rust-lib/flowy-ot/tests/attribute_test.rs @@ -52,6 +52,23 @@ fn delta_insert_text_with_attr() { OpTester::new().run_script(ops); } +#[test] +fn delta_add_bold() { + let ops = vec![ + Insert(0, "123456", 0), + Bold(0, Interval::new(3, 5), true), + AssertOpsJson( + 0, + r#"[ + {"insert":"123"}, + {"insert":"45","attributes":{"bold":"true"}}, + {"insert":"6"} + ]"#, + ), + ]; + OpTester::new().run_script(ops); +} + #[test] fn delta_add_bold_and_invert_all() { let ops = vec![ diff --git a/rust-lib/flowy-ot/tests/op_test.rs b/rust-lib/flowy-ot/tests/op_test.rs index e09a217dc5..ebc4d70a5a 100644 --- a/rust-lib/flowy-ot/tests/op_test.rs +++ b/rust-lib/flowy-ot/tests/op_test.rs @@ -148,7 +148,7 @@ fn delta_get_ops_in_interval_7() { let mut iter_2 = DeltaIter::new(&delta); assert_eq!( - iter_2.next_op_with_length(2).unwrap(), + iter_2.next_op_with_len(2).unwrap(), Builder::insert("12").build() ); assert_eq!(iter_2.next_op().unwrap(), Builder::insert("345").build()); @@ -175,7 +175,7 @@ fn delta_seek_2() { let mut iter = DeltaIter::new(&delta); assert_eq!( - iter.next_op_with_length(1).unwrap(), + iter.next_op_with_len(1).unwrap(), Builder::insert("1").build() ); } @@ -187,21 +187,21 @@ fn delta_seek_3() { let mut iter = DeltaIter::new(&delta); assert_eq!( - iter.next_op_with_length(2).unwrap(), + iter.next_op_with_len(2).unwrap(), Builder::insert("12").build() ); assert_eq!( - iter.next_op_with_length(2).unwrap(), + iter.next_op_with_len(2).unwrap(), Builder::insert("34").build() ); assert_eq!( - iter.next_op_with_length(2).unwrap(), + iter.next_op_with_len(2).unwrap(), Builder::insert("5").build() ); - assert_eq!(iter.next_op_with_length(1), None); + assert_eq!(iter.next_op_with_len(1), None); } #[test] @@ -212,11 +212,27 @@ fn delta_seek_4() { let mut iter = DeltaIter::new(&delta); iter.seek::(3); assert_eq!( - iter.next_op_with_length(2).unwrap(), + iter.next_op_with_len(2).unwrap(), Builder::insert("45").build() ); } +#[test] +fn delta_next_op_len_test() { + let mut delta = Delta::default(); + delta.add(Builder::insert("12345").build()); + + let mut iter = DeltaIter::new(&delta); + iter.seek::(3); + assert_eq!(iter.next_op_len(), 2); + assert_eq!( + iter.next_op_with_len(1).unwrap(), + Builder::insert("4").build() + ); + assert_eq!(iter.next_op_len(), 1); + assert_eq!(iter.next_op().unwrap(), Builder::insert("5").build()); +} + #[test] fn lengths() { let mut delta = Delta::default();