replace attributes::empty with attributes::custom

This commit is contained in:
appflowy 2021-08-10 14:24:41 +08:00
parent ca81c990bf
commit 7b6d1632f4
9 changed files with 88 additions and 89 deletions

View File

@ -34,7 +34,7 @@ impl Document {
} }
let probe = Interval::new(index, index + 1); let probe = Interval::new(index, index + 1);
let mut attributes = self.data.get_attributes(probe); let mut attributes = self.data.get_attributes(probe);
if attributes == Attributes::Empty { if attributes.is_empty() {
attributes = Attributes::Follow; attributes = Attributes::Follow;
} }
let mut delta = Delta::new(); let mut delta = Delta::new();
@ -55,7 +55,7 @@ impl Document {
true => AttrsBuilder::new().add(attribute).build(), true => AttrsBuilder::new().add(attribute).build(),
false => AttrsBuilder::new().remove(&attribute).build(), false => AttrsBuilder::new().remove(&attribute).build(),
}; };
log::debug!("format with {} at {}", attributes, interval);
self.update_with_attribute(attributes, interval) self.update_with_attribute(attributes, interval)
} }
@ -153,22 +153,19 @@ impl Document {
mut attributes: Attributes, mut attributes: Attributes,
interval: Interval, interval: Interval,
) -> Result<(), OTError> { ) -> Result<(), OTError> {
log::debug!("Update document with attributes: {:?}", attributes,);
let old_attributes = self.data.get_attributes(interval); let old_attributes = self.data.get_attributes(interval);
log::debug!( log::debug!("combine with old: {:?}", old_attributes);
"combine attributes: {:?} : {:?}",
attributes,
old_attributes
);
let new_attributes = match &mut attributes { let new_attributes = match &mut attributes {
Attributes::Follow => old_attributes, Attributes::Follow => old_attributes,
Attributes::Custom(attr_data) => { Attributes::Custom(attr_data) => {
attr_data.extend(old_attributes.data(), true); attr_data.extend(old_attributes.data(), true);
log::debug!("combine with old result : {:?}", attr_data);
attr_data.clone().into_attributes() attr_data.clone().into_attributes()
}, },
Attributes::Empty => Attributes::Empty,
}; };
log::debug!("combined result: {:?}", new_attributes); log::debug!("combine result: {:?}", new_attributes);
let retain = Builder::retain(interval.size()) let retain = Builder::retain(interval.size())
.attributes(new_attributes) .attributes(new_attributes)
.build(); .build();
@ -202,6 +199,7 @@ impl Document {
self.history.record(undo_delta); self.history.record(undo_delta);
} }
log::debug!("document delta: {}", &composed_delta);
Ok(composed_delta) Ok(composed_delta)
} }

View File

@ -7,16 +7,13 @@ pub enum Attributes {
#[serde(skip)] #[serde(skip)]
Follow, Follow,
Custom(AttributesData), Custom(AttributesData),
#[serde(skip)]
Empty,
} }
impl fmt::Display for Attributes { impl fmt::Display for Attributes {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self { match self {
Attributes::Follow => f.write_str("follow"), Attributes::Follow => f.write_str("follow"),
Attributes::Custom(data) => f.write_fmt(format_args!("{:?}", data.inner)), Attributes::Custom(data) => f.write_fmt(format_args!("{}", data)),
Attributes::Empty => f.write_str("empty"),
} }
} }
} }
@ -26,13 +23,19 @@ impl Attributes {
match self { match self {
Attributes::Follow => None, Attributes::Follow => None,
Attributes::Custom(data) => Some(data.clone()), Attributes::Custom(data) => Some(data.clone()),
Attributes::Empty => None, }
}
pub fn is_empty(&self) -> bool {
match self {
Attributes::Follow => false,
Attributes::Custom(data) => data.is_empty(),
} }
} }
} }
impl std::default::Default for Attributes { impl std::default::Default for Attributes {
fn default() -> Self { Attributes::Empty } fn default() -> Self { Attributes::Custom(AttributesData::new()) }
} }
pub(crate) fn attributes_from(operation: &Option<Operation>) -> Option<Attributes> { pub(crate) fn attributes_from(operation: &Option<Operation>) -> Option<Attributes> {
@ -44,7 +47,7 @@ pub(crate) fn attributes_from(operation: &Option<Operation>) -> Option<Attribute
pub fn compose_operation(left: &Option<Operation>, right: &Option<Operation>) -> Attributes { pub fn compose_operation(left: &Option<Operation>, right: &Option<Operation>) -> Attributes {
if left.is_none() && right.is_none() { if left.is_none() && right.is_none() {
return Attributes::Empty; return Attributes::default();
} }
let attr_l = attributes_from(left); let attr_l = attributes_from(left);
let attr_r = attributes_from(right); let attr_r = attributes_from(right);
@ -66,13 +69,12 @@ pub fn transform_operation(left: &Option<Operation>, right: &Option<Operation>)
if attr_l.is_none() { if attr_l.is_none() {
if attr_r.is_none() { if attr_r.is_none() {
return Attributes::Empty; return Attributes::default();
} }
return match attr_r.as_ref().unwrap() { return match attr_r.as_ref().unwrap() {
Attributes::Follow => Attributes::Follow, Attributes::Follow => Attributes::Follow,
Attributes::Custom(_) => attr_r.unwrap(), Attributes::Custom(_) => attr_r.unwrap(),
Attributes::Empty => Attributes::Empty,
}; };
} }
@ -84,7 +86,7 @@ pub fn invert_attributes(attr: Attributes, base: Attributes) -> Attributes {
let base = base.data(); let base = base.data();
if attr.is_none() && base.is_none() { if attr.is_none() && base.is_none() {
return Attributes::Empty; return Attributes::default();
} }
let attr = attr.unwrap_or(AttributesData::new()); let attr = attr.unwrap_or(AttributesData::new());
@ -125,7 +127,6 @@ fn compose_attributes(left: Attributes, right: Attributes) -> Attributes {
log::trace!("compose_attributes: a: {:?}, b: {:?}", left, right); log::trace!("compose_attributes: a: {:?}, b: {:?}", left, right);
let attr = match (&left, &right) { let attr = match (&left, &right) {
(_, Attributes::Empty) => Attributes::Empty,
(_, Attributes::Custom(_)) => merge_attributes(left, right), (_, Attributes::Custom(_)) => merge_attributes(left, right),
(Attributes::Custom(_), _) => merge_attributes(left, right), (Attributes::Custom(_), _) => merge_attributes(left, right),
_ => Attributes::Follow, _ => Attributes::Follow,
@ -149,6 +150,6 @@ fn transform_attributes(left: Attributes, right: Attributes) -> Attributes {
Attributes::Custom(result) Attributes::Custom(result)
}, },
_ => Attributes::Empty, _ => Attributes::default(),
} }
} }

View File

@ -11,6 +11,12 @@ pub struct AttributesData {
pub(crate) inner: HashMap<Attribute, String>, pub(crate) inner: HashMap<Attribute, String>,
} }
impl fmt::Display for AttributesData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("{:?}", self.inner))
}
}
impl AttributesData { impl AttributesData {
pub fn new() -> Self { pub fn new() -> Self {
AttributesData { AttributesData {
@ -34,11 +40,12 @@ impl AttributesData {
if prune { if prune {
let mut new_attributes = other.unwrap().inner; let mut new_attributes = other.unwrap().inner;
self.inner.iter().for_each(|(k, v)| { self.inner.iter().for_each(|(k, v)| {
if should_remove(v) { // if should_remove(v) {
new_attributes.remove(k); // new_attributes.remove(k);
} else { // } else {
new_attributes.insert(k.clone(), v.clone()); // new_attributes.insert(k.clone(), v.clone());
} // }
new_attributes.insert(k.clone(), v.clone());
}); });
self.inner = new_attributes; self.inner = new_attributes;
} else { } else {
@ -56,10 +63,8 @@ impl AttributesDataRule for AttributesData {
fn apply_rule(&mut self) { self.inner.retain(|_, v| !should_remove(v)); } fn apply_rule(&mut self) { self.inner.retain(|_, v| !should_remove(v)); }
fn into_attributes(mut self) -> Attributes { fn into_attributes(mut self) -> Attributes {
self.apply_rule();
if self.is_plain() { if self.is_plain() {
Attributes::Empty Attributes::default()
} else { } else {
Attributes::Custom(self) Attributes::Custom(self)
} }
@ -74,8 +79,10 @@ impl AttributesRule for Attributes {
fn apply_rule(self) -> Attributes { fn apply_rule(self) -> Attributes {
match self { match self {
Attributes::Follow => self, Attributes::Follow => self,
Attributes::Custom(data) => data.into_attributes(), Attributes::Custom(mut data) => {
Attributes::Empty => self, data.apply_rule();
data.into_attributes()
},
} }
} }
} }

View File

@ -261,15 +261,7 @@ impl Delta {
&chars.take(o_retain.n as usize).collect::<String>(), &chars.take(o_retain.n as usize).collect::<String>(),
composed_attrs, composed_attrs,
); );
next_op1 = Some( next_op1 = Some(Builder::insert(&chars.collect::<String>()).build());
Builder::insert(&chars.collect::<String>())
// consider this situation:
// [insert:12345678 - retain:4],
// the attributes of "5678" should be empty and the following
// retain will bringing the attributes.
.attributes(Attributes::Empty)
.build(),
);
next_op2 = ops2.next(); next_op2 = ops2.next();
}, },
} }
@ -594,7 +586,7 @@ impl Delta {
pub fn get_attributes(&self, interval: Interval) -> Attributes { pub fn get_attributes(&self, interval: Interval) -> Attributes {
let mut attributes_data = AttributesData::new(); let mut attributes_data = AttributesData::new();
let mut offset: usize = 0; let mut offset: usize = 0;
log::debug!("Get attributes at {:?}", interval);
self.ops.iter().for_each(|op| match op { self.ops.iter().for_each(|op| match op {
Operation::Delete(_n) => {}, Operation::Delete(_n) => {},
Operation::Retain(_retain) => { Operation::Retain(_retain) => {
@ -615,17 +607,19 @@ impl Delta {
Attributes::Follow => {}, Attributes::Follow => {},
Attributes::Custom(data) => { Attributes::Custom(data) => {
if interval.contains_range(offset, offset + end) { if interval.contains_range(offset, offset + end) {
log::debug!("Get attributes from op: {:?} at {:?}", op, interval); log::debug!("extend attributes with {} ", &data);
attributes_data.extend(Some(data.clone()), false); attributes_data.extend(Some(data.clone()), false);
} }
}, },
Attributes::Empty => {},
} }
offset += end offset += end
}, },
}); });
attributes_data.into_attributes() attributes_data.apply_rule();
let attribute = attributes_data.into_attributes();
log::debug!("Get attributes result: {} ", &attribute);
attribute
} }
pub fn to_json(&self) -> String { serde_json::to_string(self).unwrap_or("".to_owned()) } pub fn to_json(&self) -> String { serde_json::to_string(self).unwrap_or("".to_owned()) }

View File

@ -9,7 +9,7 @@ impl Builder {
pub fn new(ty: Operation) -> Builder { pub fn new(ty: Operation) -> Builder {
Builder { Builder {
ty, ty,
attrs: Attributes::Empty, attrs: Attributes::default(),
} }
} }

View File

@ -32,7 +32,7 @@ impl Operation {
pub fn get_attributes(&self) -> Attributes { pub fn get_attributes(&self) -> Attributes {
match self { match self {
Operation::Delete(_) => Attributes::Empty, Operation::Delete(_) => Attributes::default(),
Operation::Retain(retain) => retain.attributes.clone(), Operation::Retain(retain) => retain.attributes.clone(),
Operation::Insert(insert) => insert.attributes.clone(), Operation::Insert(insert) => insert.attributes.clone(),
} }
@ -55,9 +55,7 @@ impl Operation {
pub fn has_attribute(&self) -> bool { pub fn has_attribute(&self) -> bool {
match self.get_attributes() { match self.get_attributes() {
Attributes::Follow => false, Attributes::Follow => false,
// Attributes::Custom(data) => !data.is_plain(), Attributes::Custom(data) => !data.is_plain(),
Attributes::Custom(data) => true,
Attributes::Empty => false,
} }
} }
@ -147,7 +145,7 @@ impl Retain {
self.n += n; self.n += n;
None None
}, },
Attributes::Custom(_) | Attributes::Empty => { Attributes::Custom(_) => {
if self.attributes == attributes { if self.attributes == attributes {
self.n += n; self.n += n;
None None
@ -162,7 +160,6 @@ impl Retain {
match &self.attributes { match &self.attributes {
Attributes::Follow => true, Attributes::Follow => true,
Attributes::Custom(data) => data.is_plain(), Attributes::Custom(data) => data.is_plain(),
Attributes::Empty => true,
} }
} }
} }
@ -225,7 +222,7 @@ impl Insert {
self.s += s; self.s += s;
return None; return None;
}, },
Attributes::Custom(_) | Attributes::Empty => { Attributes::Custom(_) => {
if self.attributes == attributes { if self.attributes == attributes {
self.s += s; self.s += s;
None None
@ -254,6 +251,5 @@ fn is_empty(attributes: &Attributes) -> bool {
match attributes { match attributes {
Attributes::Follow => true, Attributes::Follow => true,
Attributes::Custom(data) => data.is_plain(), Attributes::Custom(data) => data.is_plain(),
Attributes::Empty => true,
} }
} }

View File

@ -82,7 +82,7 @@ impl<'de> Deserialize<'de> for Operation {
match operation { match operation {
None => Err(de::Error::missing_field("operation")), None => Err(de::Error::missing_field("operation")),
Some(mut operation) => { Some(mut operation) => {
operation.set_attributes(attributes.unwrap_or(Attributes::Empty)); operation.set_attributes(attributes.unwrap_or(Attributes::default()));
Ok(operation) Ok(operation)
}, },
} }

View File

@ -57,7 +57,7 @@ impl OpTester {
static INIT: Once = Once::new(); static INIT: Once = Once::new();
INIT.call_once(|| { INIT.call_once(|| {
color_eyre::install().unwrap(); color_eyre::install().unwrap();
std::env::set_var("RUST_LOG", "debug"); std::env::set_var("RUST_LOG", "info");
env_logger::init(); env_logger::init();
}); });
@ -201,18 +201,21 @@ impl Rng {
}; };
match self.0.gen_range(0.0, 1.0) { match self.0.gen_range(0.0, 1.0) {
f if f < 0.2 => { f if f < 0.2 => {
delta.insert(&self.gen_string(i), Attributes::Empty); delta.insert(&self.gen_string(i), Attributes::default());
}, },
f if f < 0.4 => { f if f < 0.4 => {
delta.delete(i); delta.delete(i);
}, },
_ => { _ => {
delta.retain(i, Attributes::Empty); delta.retain(i, Attributes::Follow);
}, },
} }
} }
if self.0.gen_range(0.0, 1.0) < 0.3 { if self.0.gen_range(0.0, 1.0) < 0.3 {
delta.insert(&("1".to_owned() + &self.gen_string(10)), Attributes::Empty); delta.insert(
&("1".to_owned() + &self.gen_string(10)),
Attributes::default(),
);
} }
delta delta
} }

View File

@ -125,13 +125,13 @@ fn lengths() {
let mut delta = Delta::default(); let mut delta = Delta::default();
assert_eq!(delta.base_len, 0); assert_eq!(delta.base_len, 0);
assert_eq!(delta.target_len, 0); assert_eq!(delta.target_len, 0);
delta.retain(5, Attributes::Empty); delta.retain(5, Attributes::default());
assert_eq!(delta.base_len, 5); assert_eq!(delta.base_len, 5);
assert_eq!(delta.target_len, 5); assert_eq!(delta.target_len, 5);
delta.insert("abc", Attributes::Empty); delta.insert("abc", Attributes::default());
assert_eq!(delta.base_len, 5); assert_eq!(delta.base_len, 5);
assert_eq!(delta.target_len, 8); assert_eq!(delta.target_len, 8);
delta.retain(2, Attributes::Empty); delta.retain(2, Attributes::default());
assert_eq!(delta.base_len, 7); assert_eq!(delta.base_len, 7);
assert_eq!(delta.target_len, 10); assert_eq!(delta.target_len, 10);
delta.delete(2); delta.delete(2);
@ -141,10 +141,10 @@ fn lengths() {
#[test] #[test]
fn sequence() { fn sequence() {
let mut delta = Delta::default(); let mut delta = Delta::default();
delta.retain(5, Attributes::Empty); delta.retain(5, Attributes::default());
delta.retain(0, Attributes::Empty); delta.retain(0, Attributes::default());
delta.insert("appflowy", Attributes::Empty); delta.insert("appflowy", Attributes::default());
delta.insert("", Attributes::Empty); delta.insert("", Attributes::default());
delta.delete(3); delta.delete(3);
delta.delete(0); delta.delete(0);
assert_eq!(delta.ops.len(), 3); assert_eq!(delta.ops.len(), 3);
@ -165,11 +165,11 @@ fn apply_1000() {
fn apply() { fn apply() {
let s = "hello world,".to_owned(); let s = "hello world,".to_owned();
let mut delta_a = Delta::default(); let mut delta_a = Delta::default();
delta_a.insert(&s, Attributes::Empty); delta_a.insert(&s, Attributes::default());
let mut delta_b = Delta::default(); let mut delta_b = Delta::default();
delta_b.retain(s.len(), Attributes::Empty); delta_b.retain(s.len(), Attributes::default());
delta_b.insert("appflowy", Attributes::Empty); delta_b.insert("appflowy", Attributes::default());
let after_a = delta_a.apply("").unwrap(); let after_a = delta_a.apply("").unwrap();
let after_b = delta_b.apply(&after_a).unwrap(); let after_b = delta_b.apply(&after_a).unwrap();
@ -179,15 +179,15 @@ fn apply() {
#[test] #[test]
fn base_len_test() { fn base_len_test() {
let mut delta_a = Delta::default(); let mut delta_a = Delta::default();
delta_a.insert("a", Attributes::Empty); delta_a.insert("a", Attributes::default());
delta_a.insert("b", Attributes::Empty); delta_a.insert("b", Attributes::default());
delta_a.insert("c", Attributes::Empty); delta_a.insert("c", Attributes::default());
let s = "hello world,".to_owned(); let s = "hello world,".to_owned();
delta_a.delete(s.len()); delta_a.delete(s.len());
let after_a = delta_a.apply(&s).unwrap(); let after_a = delta_a.apply(&s).unwrap();
delta_a.insert("d", Attributes::Empty); delta_a.insert("d", Attributes::default());
assert_eq!("abc", &after_a); assert_eq!("abc", &after_a);
} }
@ -207,8 +207,8 @@ fn invert() {
#[test] #[test]
fn empty_ops() { fn empty_ops() {
let mut delta = Delta::default(); let mut delta = Delta::default();
delta.retain(0, Attributes::Empty); delta.retain(0, Attributes::default());
delta.insert("", Attributes::Empty); delta.insert("", Attributes::default());
delta.delete(0); delta.delete(0);
assert_eq!(delta.ops.len(), 0); assert_eq!(delta.ops.len(), 0);
} }
@ -216,33 +216,33 @@ fn empty_ops() {
fn eq() { fn eq() {
let mut delta_a = Delta::default(); let mut delta_a = Delta::default();
delta_a.delete(1); delta_a.delete(1);
delta_a.insert("lo", Attributes::Empty); delta_a.insert("lo", Attributes::default());
delta_a.retain(2, Attributes::Empty); delta_a.retain(2, Attributes::default());
delta_a.retain(3, Attributes::Empty); delta_a.retain(3, Attributes::default());
let mut delta_b = Delta::default(); let mut delta_b = Delta::default();
delta_b.delete(1); delta_b.delete(1);
delta_b.insert("l", Attributes::Empty); delta_b.insert("l", Attributes::default());
delta_b.insert("o", Attributes::Empty); delta_b.insert("o", Attributes::default());
delta_b.retain(5, Attributes::Empty); delta_b.retain(5, Attributes::default());
assert_eq!(delta_a, delta_b); assert_eq!(delta_a, delta_b);
delta_a.delete(1); delta_a.delete(1);
delta_b.retain(1, Attributes::Empty); delta_b.retain(1, Attributes::default());
assert_ne!(delta_a, delta_b); assert_ne!(delta_a, delta_b);
} }
#[test] #[test]
fn ops_merging() { fn ops_merging() {
let mut delta = Delta::default(); let mut delta = Delta::default();
assert_eq!(delta.ops.len(), 0); assert_eq!(delta.ops.len(), 0);
delta.retain(2, Attributes::Empty); delta.retain(2, Attributes::default());
assert_eq!(delta.ops.len(), 1); assert_eq!(delta.ops.len(), 1);
assert_eq!(delta.ops.last(), Some(&Builder::retain(2).build())); assert_eq!(delta.ops.last(), Some(&Builder::retain(2).build()));
delta.retain(3, Attributes::Empty); delta.retain(3, Attributes::default());
assert_eq!(delta.ops.len(), 1); assert_eq!(delta.ops.len(), 1);
assert_eq!(delta.ops.last(), Some(&Builder::retain(5).build())); assert_eq!(delta.ops.last(), Some(&Builder::retain(5).build()));
delta.insert("abc", Attributes::Empty); delta.insert("abc", Attributes::default());
assert_eq!(delta.ops.len(), 2); assert_eq!(delta.ops.len(), 2);
assert_eq!(delta.ops.last(), Some(&Builder::insert("abc").build())); assert_eq!(delta.ops.last(), Some(&Builder::insert("abc").build()));
delta.insert("xyz", Attributes::Empty); delta.insert("xyz", Attributes::default());
assert_eq!(delta.ops.len(), 2); assert_eq!(delta.ops.len(), 2);
assert_eq!(delta.ops.last(), Some(&Builder::insert("abcxyz").build())); assert_eq!(delta.ops.last(), Some(&Builder::insert("abcxyz").build()));
delta.delete(1); delta.delete(1);
@ -256,11 +256,11 @@ fn ops_merging() {
fn is_noop() { fn is_noop() {
let mut delta = Delta::default(); let mut delta = Delta::default();
assert!(delta.is_noop()); assert!(delta.is_noop());
delta.retain(5, Attributes::Empty); delta.retain(5, Attributes::default());
assert!(delta.is_noop()); assert!(delta.is_noop());
delta.retain(3, Attributes::Empty); delta.retain(3, Attributes::default());
assert!(delta.is_noop()); assert!(delta.is_noop());
delta.insert("lorem", Attributes::Empty); delta.insert("lorem", Attributes::default());
assert!(!delta.is_noop()); assert!(!delta.is_noop());
} }
#[test] #[test]
@ -322,7 +322,7 @@ fn delta_transform_test() {
let mut b = Delta::default(); let mut b = Delta::default();
let mut b_s = String::new(); let mut b_s = String::new();
b.insert("456", Attributes::Empty); b.insert("456", Attributes::default());
b_s = b.apply(&b_s).unwrap(); b_s = b.apply(&b_s).unwrap();
assert_eq!(&b_s, "456"); assert_eq!(&b_s, "456");