get next op length without consume it

This commit is contained in:
appflowy 2021-08-13 16:39:32 +08:00
parent 93cf9712dc
commit cd751a7b15
6 changed files with 95 additions and 39 deletions

View File

@ -50,8 +50,10 @@ impl Document {
// .view // .view
// .format(&self.delta, attribute.clone(), interval) // .format(&self.delta, attribute.clone(), interval)
// .unwrap(); // .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) self.update_with_attribute(attribute, interval)
} }

View File

@ -86,7 +86,7 @@ impl FormatExt for ResolveInlineFormatExt {
let len = interval.size(); let len = interval.size();
while cur < len && iter.has_next() { 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() { if some_op.is_none() {
return Some(new_delta); return Some(new_delta);
} }

View File

@ -2,7 +2,7 @@ use crate::{
core::{Delta, Interval, Operation}, core::{Delta, Interval, Operation},
errors::{ErrorBuilder, OTError, OTErrorCode}, errors::{ErrorBuilder, OTError, OTErrorCode},
}; };
use std::{cmp::min, slice::Iter}; use std::{cmp::min, iter::Enumerate, slice::Iter};
#[derive(Debug)] #[derive(Debug)]
pub struct Cursor<'a> { pub struct Cursor<'a> {
@ -11,7 +11,7 @@ pub struct Cursor<'a> {
pub(crate) next_iv: Interval, pub(crate) next_iv: Interval,
pub(crate) c_index: usize, pub(crate) c_index: usize,
pub(crate) o_index: usize, pub(crate) o_index: usize,
iter: Iter<'a, Operation>, iter: Enumerate<Iter<'a, Operation>>,
next_op: Option<Operation>, next_op: Option<Operation>,
} }
@ -24,7 +24,7 @@ impl<'a> Cursor<'a> {
next_iv: interval, next_iv: interval,
c_index: 0, c_index: 0,
o_index: 0, o_index: 0,
iter: delta.ops.iter(), iter: delta.ops.iter().enumerate(),
next_op: None, next_op: None,
}; };
cursor.descend(0); cursor.descend(0);
@ -33,12 +33,12 @@ impl<'a> Cursor<'a> {
fn descend(&mut self, index: usize) { fn descend(&mut self, index: usize) {
self.next_iv.start += index; self.next_iv.start += index;
if self.c_index >= self.next_iv.start { if self.c_index >= self.next_iv.start {
return; return;
} }
while let Some((o_index, op)) = self.iter.next() {
while let Some(op) = self.iter.next() { self.o_index = o_index;
self.o_index += 1;
let start = self.c_index; let start = self.c_index;
let end = start + op.length(); let end = start + op.length();
let intersect = Interval::new(start, end).intersect(self.next_iv); 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) }
let mut find_op = None;
let next_op = self.next_op.take(); fn next_op_interval_with_len(&self, force_len: Option<usize>) -> Interval {
let mut next_op = next_op.as_ref(); let op = self
if next_op.is_none() { .next_op
next_op = self.iter.next(); .as_ref()
self.o_index += 1; .unwrap_or(&self.delta.ops[self.o_index]);
}
while find_op.is_none() && next_op.is_some() {
let op = next_op.unwrap();
let start = self.c_index; let start = self.c_index;
let end = match length { let end = match force_len {
None => self.c_index + op.length(), None => self.c_index + op.length(),
Some(length) => self.c_index + min(length, op.length()), Some(force_len) => self.c_index + min(force_len, op.length()),
}; };
let intersect = Interval::new(start, end).intersect(self.next_iv); let intersect = Interval::new(start, end).intersect(self.next_iv);
let interval = intersect.translate_neg(start); let interval = intersect.translate_neg(start);
interval
}
let op_interval = Interval::new(0, op.length()); pub fn next_op_with_len(&mut self, force_len: Option<usize>) -> Option<Operation> {
let suffix = op_interval.suffix(interval); 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 = find_next_op(self);
}
while find_op.is_none() && next_op.is_some() {
let op = next_op.take().unwrap();
let interval = self.next_op_interval_with_len(force_len);
find_op = op.shrink(interval); find_op = op.shrink(interval);
let suffix = Interval::new(0, op.length()).suffix(interval);
if !suffix.is_empty() { if !suffix.is_empty() {
self.next_op = op.shrink(suffix); self.next_op = op.shrink(suffix);
} }
self.c_index = intersect.end; self.c_index += interval.end;
self.next_iv.start = intersect.end; self.next_iv.start = self.c_index;
if find_op.is_none() { if find_op.is_none() {
next_op = self.iter.next(); next_op = find_next_op(self);
} }
} }
find_op 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 } 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>; type SeekResult = Result<(), OTError>;
pub trait Metric { pub trait Metric {
fn seek(cursor: &mut Cursor, index: usize) -> SeekResult; fn seek(cursor: &mut Cursor, index: usize) -> SeekResult;
@ -107,7 +126,7 @@ impl Metric for OpMetric {
let _ = check_bound(cursor.o_index, index)?; let _ = check_bound(cursor.o_index, index)?;
let mut temp_cursor = Cursor::new(cursor.delta, cursor.origin_iv); let mut temp_cursor = Cursor::new(cursor.delta, cursor.origin_iv);
let mut offset = 0; let mut offset = 0;
while let Some(op) = temp_cursor.iter.next() { while let Some((_, op)) = temp_cursor.iter.next() {
offset += op.length(); offset += op.length();
if offset > index { if offset > index {
break; break;
@ -123,7 +142,7 @@ pub struct CharMetric {}
impl Metric for CharMetric { impl Metric for CharMetric {
fn seek(cursor: &mut Cursor, index: usize) -> SeekResult { fn seek(cursor: &mut Cursor, index: usize) -> SeekResult {
let _ = check_bound(cursor.c_index, index)?; let _ = check_bound(cursor.c_index, index)?;
let _ = cursor.next_op_with_length(Some(index)); let _ = cursor.next_op_with_len(Some(index));
Ok(()) Ok(())
} }
} }

View File

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

View File

@ -52,6 +52,23 @@ fn delta_insert_text_with_attr() {
OpTester::new().run_script(ops); 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] #[test]
fn delta_add_bold_and_invert_all() { fn delta_add_bold_and_invert_all() {
let ops = vec![ let ops = vec![

View File

@ -148,7 +148,7 @@ fn delta_get_ops_in_interval_7() {
let mut iter_2 = DeltaIter::new(&delta); let mut iter_2 = DeltaIter::new(&delta);
assert_eq!( assert_eq!(
iter_2.next_op_with_length(2).unwrap(), iter_2.next_op_with_len(2).unwrap(),
Builder::insert("12").build() Builder::insert("12").build()
); );
assert_eq!(iter_2.next_op().unwrap(), Builder::insert("345").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); let mut iter = DeltaIter::new(&delta);
assert_eq!( assert_eq!(
iter.next_op_with_length(1).unwrap(), iter.next_op_with_len(1).unwrap(),
Builder::insert("1").build() Builder::insert("1").build()
); );
} }
@ -187,21 +187,21 @@ fn delta_seek_3() {
let mut iter = DeltaIter::new(&delta); let mut iter = DeltaIter::new(&delta);
assert_eq!( assert_eq!(
iter.next_op_with_length(2).unwrap(), iter.next_op_with_len(2).unwrap(),
Builder::insert("12").build() Builder::insert("12").build()
); );
assert_eq!( assert_eq!(
iter.next_op_with_length(2).unwrap(), iter.next_op_with_len(2).unwrap(),
Builder::insert("34").build() Builder::insert("34").build()
); );
assert_eq!( assert_eq!(
iter.next_op_with_length(2).unwrap(), iter.next_op_with_len(2).unwrap(),
Builder::insert("5").build() Builder::insert("5").build()
); );
assert_eq!(iter.next_op_with_length(1), None); assert_eq!(iter.next_op_with_len(1), None);
} }
#[test] #[test]
@ -212,11 +212,27 @@ fn delta_seek_4() {
let mut iter = DeltaIter::new(&delta); let mut iter = DeltaIter::new(&delta);
iter.seek::<CharMetric>(3); iter.seek::<CharMetric>(3);
assert_eq!( assert_eq!(
iter.next_op_with_length(2).unwrap(), iter.next_op_with_len(2).unwrap(),
Builder::insert("45").build() 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] #[test]
fn lengths() { fn lengths() {
let mut delta = Delta::default(); let mut delta = Delta::default();