mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
get next op length without consume it
This commit is contained in:
parent
93cf9712dc
commit
cd751a7b15
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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> {
|
||||||
|
@ -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![
|
||||||
|
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user