Explorar o código

get next op length without consume it

appflowy %!s(int64=3) %!d(string=hai) anos
pai
achega
cd751a7b15

+ 4 - 2
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)
     }
 

+ 1 - 1
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);
             }

+ 46 - 27
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<Iter<'a, Operation>>,
     next_op: Option<Operation>,
 }
 
@@ -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<usize>) -> Option<Operation> {
+    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();
         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<Operation> { self.next_op_with_length(None) }
+    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 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(())
     }
 }

+ 4 - 2
rust-lib/flowy-ot/src/core/delta/iterator.rs

@@ -25,8 +25,10 @@ impl<'a> DeltaIter<'a> {
 
     pub fn next_op(&mut self) -> Option<Operation> { self.cursor.next_op() }
 
-    pub fn next_op_with_length(&mut self, length: usize) -> Option<Operation> {
-        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<Operation> {
+        self.cursor.next_op_with_len(Some(length))
     }
 
     pub fn seek<M: Metric>(&mut self, index: usize) -> Result<(), OTError> {

+ 17 - 0
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![

+ 23 - 7
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::<CharMetric>(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::<CharMetric>(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();