diff --git a/rust-lib/flowy-ot/src/client/document.rs b/rust-lib/flowy-ot/src/client/document.rs index cfeab02b05..2d5507214d 100644 --- a/rust-lib/flowy-ot/src/client/document.rs +++ b/rust-lib/flowy-ot/src/client/document.rs @@ -34,7 +34,7 @@ impl Document { } let probe = Interval::new(index, index + 1); let mut attributes = self.data.get_attributes(probe); - if attributes == Attributes::Empty { + if attributes.is_empty() { attributes = Attributes::Follow; } let mut delta = Delta::new(); @@ -55,7 +55,7 @@ impl Document { true => AttrsBuilder::new().add(attribute).build(), false => AttrsBuilder::new().remove(&attribute).build(), }; - + log::debug!("format with {} at {}", attributes, interval); self.update_with_attribute(attributes, interval) } @@ -153,22 +153,19 @@ impl Document { mut attributes: Attributes, interval: Interval, ) -> Result<(), OTError> { + log::debug!("Update document with attributes: {:?}", attributes,); let old_attributes = self.data.get_attributes(interval); - log::debug!( - "combine attributes: {:?} : {:?}", - attributes, - old_attributes - ); + log::debug!("combine with old: {:?}", old_attributes); let new_attributes = match &mut attributes { Attributes::Follow => old_attributes, Attributes::Custom(attr_data) => { attr_data.extend(old_attributes.data(), true); + log::debug!("combine with old result : {:?}", attr_data); 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()) .attributes(new_attributes) .build(); @@ -202,6 +199,7 @@ impl Document { self.history.record(undo_delta); } + log::debug!("document delta: {}", &composed_delta); Ok(composed_delta) } diff --git a/rust-lib/flowy-ot/src/core/attributes/attributes.rs b/rust-lib/flowy-ot/src/core/attributes/attributes.rs index 10c249ee0b..7b1f11af1b 100644 --- a/rust-lib/flowy-ot/src/core/attributes/attributes.rs +++ b/rust-lib/flowy-ot/src/core/attributes/attributes.rs @@ -7,16 +7,13 @@ pub enum Attributes { #[serde(skip)] Follow, Custom(AttributesData), - #[serde(skip)] - Empty, } impl fmt::Display for Attributes { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Attributes::Follow => f.write_str("follow"), - Attributes::Custom(data) => f.write_fmt(format_args!("{:?}", data.inner)), - Attributes::Empty => f.write_str("empty"), + Attributes::Custom(data) => f.write_fmt(format_args!("{}", data)), } } } @@ -26,13 +23,19 @@ impl Attributes { match self { Attributes::Follow => None, 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 { - fn default() -> Self { Attributes::Empty } + fn default() -> Self { Attributes::Custom(AttributesData::new()) } } pub(crate) fn attributes_from(operation: &Option) -> Option { @@ -44,7 +47,7 @@ pub(crate) fn attributes_from(operation: &Option) -> Option, right: &Option) -> Attributes { if left.is_none() && right.is_none() { - return Attributes::Empty; + return Attributes::default(); } let attr_l = attributes_from(left); let attr_r = attributes_from(right); @@ -66,13 +69,12 @@ pub fn transform_operation(left: &Option, right: &Option) if attr_l.is_none() { if attr_r.is_none() { - return Attributes::Empty; + return Attributes::default(); } return match attr_r.as_ref().unwrap() { Attributes::Follow => Attributes::Follow, 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(); if attr.is_none() && base.is_none() { - return Attributes::Empty; + return Attributes::default(); } 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); let attr = match (&left, &right) { - (_, Attributes::Empty) => Attributes::Empty, (_, Attributes::Custom(_)) => merge_attributes(left, right), (Attributes::Custom(_), _) => merge_attributes(left, right), _ => Attributes::Follow, @@ -149,6 +150,6 @@ fn transform_attributes(left: Attributes, right: Attributes) -> Attributes { Attributes::Custom(result) }, - _ => Attributes::Empty, + _ => Attributes::default(), } } diff --git a/rust-lib/flowy-ot/src/core/attributes/data.rs b/rust-lib/flowy-ot/src/core/attributes/data.rs index 31fdba17b1..adc35dd416 100644 --- a/rust-lib/flowy-ot/src/core/attributes/data.rs +++ b/rust-lib/flowy-ot/src/core/attributes/data.rs @@ -11,6 +11,12 @@ pub struct AttributesData { pub(crate) inner: HashMap, } +impl fmt::Display for AttributesData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_fmt(format_args!("{:?}", self.inner)) + } +} + impl AttributesData { pub fn new() -> Self { AttributesData { @@ -34,11 +40,12 @@ impl AttributesData { if prune { let mut new_attributes = other.unwrap().inner; self.inner.iter().for_each(|(k, v)| { - if should_remove(v) { - new_attributes.remove(k); - } else { - new_attributes.insert(k.clone(), v.clone()); - } + // if should_remove(v) { + // new_attributes.remove(k); + // } else { + // new_attributes.insert(k.clone(), v.clone()); + // } + new_attributes.insert(k.clone(), v.clone()); }); self.inner = new_attributes; } else { @@ -56,10 +63,8 @@ impl AttributesDataRule for AttributesData { fn apply_rule(&mut self) { self.inner.retain(|_, v| !should_remove(v)); } fn into_attributes(mut self) -> Attributes { - self.apply_rule(); - if self.is_plain() { - Attributes::Empty + Attributes::default() } else { Attributes::Custom(self) } @@ -74,8 +79,10 @@ impl AttributesRule for Attributes { fn apply_rule(self) -> Attributes { match self { Attributes::Follow => self, - Attributes::Custom(data) => data.into_attributes(), - Attributes::Empty => self, + Attributes::Custom(mut data) => { + data.apply_rule(); + data.into_attributes() + }, } } } diff --git a/rust-lib/flowy-ot/src/core/delta.rs b/rust-lib/flowy-ot/src/core/delta.rs index d0af7281a8..ceea70a79f 100644 --- a/rust-lib/flowy-ot/src/core/delta.rs +++ b/rust-lib/flowy-ot/src/core/delta.rs @@ -261,15 +261,7 @@ impl Delta { &chars.take(o_retain.n as usize).collect::(), composed_attrs, ); - next_op1 = Some( - Builder::insert(&chars.collect::()) - // 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_op1 = Some(Builder::insert(&chars.collect::()).build()); next_op2 = ops2.next(); }, } @@ -594,7 +586,7 @@ impl Delta { pub fn get_attributes(&self, interval: Interval) -> Attributes { let mut attributes_data = AttributesData::new(); let mut offset: usize = 0; - + log::debug!("Get attributes at {:?}", interval); self.ops.iter().for_each(|op| match op { Operation::Delete(_n) => {}, Operation::Retain(_retain) => { @@ -615,17 +607,19 @@ impl Delta { Attributes::Follow => {}, Attributes::Custom(data) => { 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::Empty => {}, } 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()) } diff --git a/rust-lib/flowy-ot/src/core/operation/builder.rs b/rust-lib/flowy-ot/src/core/operation/builder.rs index 993cf213fc..b717fd7f3e 100644 --- a/rust-lib/flowy-ot/src/core/operation/builder.rs +++ b/rust-lib/flowy-ot/src/core/operation/builder.rs @@ -9,7 +9,7 @@ impl Builder { pub fn new(ty: Operation) -> Builder { Builder { ty, - attrs: Attributes::Empty, + attrs: Attributes::default(), } } diff --git a/rust-lib/flowy-ot/src/core/operation/operation.rs b/rust-lib/flowy-ot/src/core/operation/operation.rs index cb893dd01c..2ca586060c 100644 --- a/rust-lib/flowy-ot/src/core/operation/operation.rs +++ b/rust-lib/flowy-ot/src/core/operation/operation.rs @@ -32,7 +32,7 @@ impl Operation { pub fn get_attributes(&self) -> Attributes { match self { - Operation::Delete(_) => Attributes::Empty, + Operation::Delete(_) => Attributes::default(), Operation::Retain(retain) => retain.attributes.clone(), Operation::Insert(insert) => insert.attributes.clone(), } @@ -55,9 +55,7 @@ impl Operation { pub fn has_attribute(&self) -> bool { match self.get_attributes() { Attributes::Follow => false, - // Attributes::Custom(data) => !data.is_plain(), - Attributes::Custom(data) => true, - Attributes::Empty => false, + Attributes::Custom(data) => !data.is_plain(), } } @@ -147,7 +145,7 @@ impl Retain { self.n += n; None }, - Attributes::Custom(_) | Attributes::Empty => { + Attributes::Custom(_) => { if self.attributes == attributes { self.n += n; None @@ -162,7 +160,6 @@ impl Retain { match &self.attributes { Attributes::Follow => true, Attributes::Custom(data) => data.is_plain(), - Attributes::Empty => true, } } } @@ -225,7 +222,7 @@ impl Insert { self.s += s; return None; }, - Attributes::Custom(_) | Attributes::Empty => { + Attributes::Custom(_) => { if self.attributes == attributes { self.s += s; None @@ -254,6 +251,5 @@ fn is_empty(attributes: &Attributes) -> bool { match attributes { Attributes::Follow => true, Attributes::Custom(data) => data.is_plain(), - Attributes::Empty => true, } } diff --git a/rust-lib/flowy-ot/src/core/operation/operation_serde.rs b/rust-lib/flowy-ot/src/core/operation/operation_serde.rs index f84e8bcabe..62ab3eed7b 100644 --- a/rust-lib/flowy-ot/src/core/operation/operation_serde.rs +++ b/rust-lib/flowy-ot/src/core/operation/operation_serde.rs @@ -82,7 +82,7 @@ impl<'de> Deserialize<'de> for Operation { match operation { None => Err(de::Error::missing_field("operation")), Some(mut operation) => { - operation.set_attributes(attributes.unwrap_or(Attributes::Empty)); + operation.set_attributes(attributes.unwrap_or(Attributes::default())); Ok(operation) }, } diff --git a/rust-lib/flowy-ot/tests/helper/mod.rs b/rust-lib/flowy-ot/tests/helper/mod.rs index aa1c2df008..06794f251a 100644 --- a/rust-lib/flowy-ot/tests/helper/mod.rs +++ b/rust-lib/flowy-ot/tests/helper/mod.rs @@ -57,7 +57,7 @@ impl OpTester { static INIT: Once = Once::new(); INIT.call_once(|| { color_eyre::install().unwrap(); - std::env::set_var("RUST_LOG", "debug"); + std::env::set_var("RUST_LOG", "info"); env_logger::init(); }); @@ -201,18 +201,21 @@ impl Rng { }; match self.0.gen_range(0.0, 1.0) { 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 => { delta.delete(i); }, _ => { - delta.retain(i, Attributes::Empty); + delta.retain(i, Attributes::Follow); }, } } 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 } diff --git a/rust-lib/flowy-ot/tests/op_test.rs b/rust-lib/flowy-ot/tests/op_test.rs index adbd18d4cd..6ab6d8faae 100644 --- a/rust-lib/flowy-ot/tests/op_test.rs +++ b/rust-lib/flowy-ot/tests/op_test.rs @@ -125,13 +125,13 @@ fn lengths() { let mut delta = Delta::default(); assert_eq!(delta.base_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.target_len, 5); - delta.insert("abc", Attributes::Empty); + delta.insert("abc", Attributes::default()); assert_eq!(delta.base_len, 5); 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.target_len, 10); delta.delete(2); @@ -141,10 +141,10 @@ fn lengths() { #[test] fn sequence() { let mut delta = Delta::default(); - delta.retain(5, Attributes::Empty); - delta.retain(0, Attributes::Empty); - delta.insert("appflowy", Attributes::Empty); - delta.insert("", Attributes::Empty); + delta.retain(5, Attributes::default()); + delta.retain(0, Attributes::default()); + delta.insert("appflowy", Attributes::default()); + delta.insert("", Attributes::default()); delta.delete(3); delta.delete(0); assert_eq!(delta.ops.len(), 3); @@ -165,11 +165,11 @@ fn apply_1000() { fn apply() { let s = "hello world,".to_owned(); let mut delta_a = Delta::default(); - delta_a.insert(&s, Attributes::Empty); + delta_a.insert(&s, Attributes::default()); let mut delta_b = Delta::default(); - delta_b.retain(s.len(), Attributes::Empty); - delta_b.insert("appflowy", Attributes::Empty); + delta_b.retain(s.len(), Attributes::default()); + delta_b.insert("appflowy", Attributes::default()); let after_a = delta_a.apply("").unwrap(); let after_b = delta_b.apply(&after_a).unwrap(); @@ -179,15 +179,15 @@ fn apply() { #[test] fn base_len_test() { let mut delta_a = Delta::default(); - delta_a.insert("a", Attributes::Empty); - delta_a.insert("b", Attributes::Empty); - delta_a.insert("c", Attributes::Empty); + delta_a.insert("a", Attributes::default()); + delta_a.insert("b", Attributes::default()); + delta_a.insert("c", Attributes::default()); let s = "hello world,".to_owned(); delta_a.delete(s.len()); 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); } @@ -207,8 +207,8 @@ fn invert() { #[test] fn empty_ops() { let mut delta = Delta::default(); - delta.retain(0, Attributes::Empty); - delta.insert("", Attributes::Empty); + delta.retain(0, Attributes::default()); + delta.insert("", Attributes::default()); delta.delete(0); assert_eq!(delta.ops.len(), 0); } @@ -216,33 +216,33 @@ fn empty_ops() { fn eq() { let mut delta_a = Delta::default(); delta_a.delete(1); - delta_a.insert("lo", Attributes::Empty); - delta_a.retain(2, Attributes::Empty); - delta_a.retain(3, Attributes::Empty); + delta_a.insert("lo", Attributes::default()); + delta_a.retain(2, Attributes::default()); + delta_a.retain(3, Attributes::default()); let mut delta_b = Delta::default(); delta_b.delete(1); - delta_b.insert("l", Attributes::Empty); - delta_b.insert("o", Attributes::Empty); - delta_b.retain(5, Attributes::Empty); + delta_b.insert("l", Attributes::default()); + delta_b.insert("o", Attributes::default()); + delta_b.retain(5, Attributes::default()); assert_eq!(delta_a, delta_b); delta_a.delete(1); - delta_b.retain(1, Attributes::Empty); + delta_b.retain(1, Attributes::default()); assert_ne!(delta_a, delta_b); } #[test] fn ops_merging() { let mut delta = Delta::default(); 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.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.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.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.last(), Some(&Builder::insert("abcxyz").build())); delta.delete(1); @@ -256,11 +256,11 @@ fn ops_merging() { fn is_noop() { let mut delta = Delta::default(); assert!(delta.is_noop()); - delta.retain(5, Attributes::Empty); + delta.retain(5, Attributes::default()); assert!(delta.is_noop()); - delta.retain(3, Attributes::Empty); + delta.retain(3, Attributes::default()); assert!(delta.is_noop()); - delta.insert("lorem", Attributes::Empty); + delta.insert("lorem", Attributes::default()); assert!(!delta.is_noop()); } #[test] @@ -322,7 +322,7 @@ fn delta_transform_test() { let mut b = Delta::default(); let mut b_s = String::new(); - b.insert("456", Attributes::Empty); + b.insert("456", Attributes::default()); b_s = b.apply(&b_s).unwrap(); assert_eq!(&b_s, "456");