mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
replace attributes::empty with attributes::custom
This commit is contained in:
parent
ca81c990bf
commit
7b6d1632f4
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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<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 {
|
||||
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<Operation>, right: &Option<Operation>)
|
||||
|
||||
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(),
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,12 @@ pub struct AttributesData {
|
||||
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 {
|
||||
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()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,15 +261,7 @@ impl Delta {
|
||||
&chars.take(o_retain.n as usize).collect::<String>(),
|
||||
composed_attrs,
|
||||
);
|
||||
next_op1 = Some(
|
||||
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_op1 = Some(Builder::insert(&chars.collect::<String>()).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()) }
|
||||
|
@ -9,7 +9,7 @@ impl Builder {
|
||||
pub fn new(ty: Operation) -> Builder {
|
||||
Builder {
|
||||
ty,
|
||||
attrs: Attributes::Empty,
|
||||
attrs: Attributes::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
},
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user