mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix warnings
This commit is contained in:
parent
7b6d1632f4
commit
1490d5c1b0
@ -159,9 +159,9 @@ impl Document {
|
||||
let new_attributes = match &mut attributes {
|
||||
Attributes::Follow => old_attributes,
|
||||
Attributes::Custom(attr_data) => {
|
||||
attr_data.extend(old_attributes.data(), true);
|
||||
attr_data.merge(old_attributes.data());
|
||||
log::debug!("combine with old result : {:?}", attr_data);
|
||||
attr_data.clone().into_attributes()
|
||||
attr_data.clone().into()
|
||||
},
|
||||
};
|
||||
|
||||
@ -209,7 +209,7 @@ impl Document {
|
||||
// a = c.compose(d)
|
||||
log::debug!("👉invert change {}", change);
|
||||
let new_delta = self.data.compose(change)?;
|
||||
let mut inverted_delta = change.invert(&self.data);
|
||||
let inverted_delta = change.invert(&self.data);
|
||||
// trim(&mut inverted_delta);
|
||||
|
||||
Ok((new_delta, inverted_delta))
|
||||
|
@ -1,5 +1,22 @@
|
||||
use crate::core::{Attribute, AttributesData, AttributesRule, Operation};
|
||||
use std::{collections::HashMap, fmt, fmt::Formatter};
|
||||
use crate::core::{AttributesData, Operation};
|
||||
use std::{fmt, fmt::Formatter};
|
||||
|
||||
pub trait AttributesRule {
|
||||
// Remove the empty attribute that its value is empty. e.g. {bold: ""}.
|
||||
fn remove_empty(self) -> Attributes;
|
||||
}
|
||||
|
||||
impl AttributesRule for Attributes {
|
||||
fn remove_empty(self) -> Attributes {
|
||||
match self {
|
||||
Attributes::Follow => self,
|
||||
Attributes::Custom(mut data) => {
|
||||
data.remove_empty_value();
|
||||
data.into()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
@ -49,18 +66,27 @@ pub fn compose_operation(left: &Option<Operation>, right: &Option<Operation>) ->
|
||||
if left.is_none() && right.is_none() {
|
||||
return Attributes::default();
|
||||
}
|
||||
let attr_l = attributes_from(left);
|
||||
let attr_r = attributes_from(right);
|
||||
let attr_left = attributes_from(left);
|
||||
let attr_right = attributes_from(right);
|
||||
|
||||
if attr_l.is_none() {
|
||||
return attr_r.unwrap();
|
||||
if attr_left.is_none() {
|
||||
return attr_right.unwrap();
|
||||
}
|
||||
|
||||
if attr_r.is_none() {
|
||||
return attr_l.unwrap();
|
||||
if attr_right.is_none() {
|
||||
return attr_left.unwrap();
|
||||
}
|
||||
|
||||
compose_attributes(attr_l.unwrap(), attr_r.unwrap())
|
||||
let left = attr_left.unwrap();
|
||||
let right = attr_right.unwrap();
|
||||
log::trace!("compose attributes: a: {:?}, b: {:?}", left, right);
|
||||
let attr = match (&left, &right) {
|
||||
(_, Attributes::Custom(_)) => merge_attributes(left, right),
|
||||
(Attributes::Custom(_), _) => merge_attributes(left, right),
|
||||
_ => Attributes::Follow,
|
||||
};
|
||||
log::trace!("compose attributes result: {:?}", attr);
|
||||
attr
|
||||
}
|
||||
|
||||
pub fn transform_operation(left: &Option<Operation>, right: &Option<Operation>) -> Attributes {
|
||||
@ -78,7 +104,23 @@ pub fn transform_operation(left: &Option<Operation>, right: &Option<Operation>)
|
||||
};
|
||||
}
|
||||
|
||||
transform_attributes(attr_l.unwrap(), attr_r.unwrap())
|
||||
let left = attr_l.unwrap();
|
||||
let right = attr_r.unwrap();
|
||||
match (left, right) {
|
||||
(Attributes::Custom(data_l), Attributes::Custom(data_r)) => {
|
||||
let result = data_r
|
||||
.iter()
|
||||
.fold(AttributesData::new(), |mut new_attr_data, (k, v)| {
|
||||
if !data_l.contains_key(k) {
|
||||
new_attr_data.insert(k.clone(), v.clone());
|
||||
}
|
||||
new_attr_data
|
||||
});
|
||||
|
||||
Attributes::Custom(result)
|
||||
},
|
||||
_ => Attributes::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn invert_attributes(attr: Attributes, base: Attributes) -> Attributes {
|
||||
@ -115,41 +157,10 @@ pub fn merge_attributes(attributes: Attributes, other: Attributes) -> Attributes
|
||||
match (&attributes, &other) {
|
||||
(Attributes::Custom(data), Attributes::Custom(o_data)) => {
|
||||
let mut data = data.clone();
|
||||
data.extend(Some(o_data.clone()), false);
|
||||
data.extend(Some(o_data.clone()));
|
||||
Attributes::Custom(data)
|
||||
},
|
||||
(Attributes::Custom(data), _) => Attributes::Custom(data.clone()),
|
||||
_ => other,
|
||||
}
|
||||
}
|
||||
|
||||
fn compose_attributes(left: Attributes, right: Attributes) -> Attributes {
|
||||
log::trace!("compose_attributes: a: {:?}, b: {:?}", left, right);
|
||||
|
||||
let attr = match (&left, &right) {
|
||||
(_, Attributes::Custom(_)) => merge_attributes(left, right),
|
||||
(Attributes::Custom(_), _) => merge_attributes(left, right),
|
||||
_ => Attributes::Follow,
|
||||
};
|
||||
|
||||
log::trace!("composed_attributes: a: {:?}", attr);
|
||||
attr
|
||||
}
|
||||
|
||||
fn transform_attributes(left: Attributes, right: Attributes) -> Attributes {
|
||||
match (left, right) {
|
||||
(Attributes::Custom(data_l), Attributes::Custom(data_r)) => {
|
||||
let result = data_r
|
||||
.iter()
|
||||
.fold(AttributesData::new(), |mut new_attr_data, (k, v)| {
|
||||
if !data_l.contains_key(k) {
|
||||
new_attr_data.insert(k.clone(), v.clone());
|
||||
}
|
||||
new_attr_data
|
||||
});
|
||||
|
||||
Attributes::Custom(result)
|
||||
},
|
||||
_ => Attributes::default(),
|
||||
}
|
||||
}
|
||||
|
@ -24,72 +24,39 @@ impl AttributesData {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_plain(&self) -> bool { self.inner.is_empty() }
|
||||
pub fn is_empty(&self) -> bool { self.inner.is_empty() }
|
||||
|
||||
pub fn add(&mut self, attribute: Attribute) { self.inner.insert(attribute, "true".to_owned()); }
|
||||
|
||||
pub fn remove(&mut self, attribute: &Attribute) {
|
||||
self.inner.insert(attribute.clone(), REMOVE_FLAG.to_owned());
|
||||
}
|
||||
|
||||
pub fn add(&mut self, attribute: Attribute) { self.inner.insert(attribute, "true".to_owned()); }
|
||||
// Remove the key if its value is empty. e.g. { bold: "" }
|
||||
pub fn remove_empty_value(&mut self) { self.inner.retain(|_, v| !should_remove(v)); }
|
||||
|
||||
pub fn extend(&mut self, other: Option<AttributesData>, prune: bool) {
|
||||
pub fn extend(&mut self, other: Option<AttributesData>) {
|
||||
if other.is_none() {
|
||||
return;
|
||||
}
|
||||
self.inner.extend(other.unwrap().inner);
|
||||
}
|
||||
|
||||
// Update self attributes by constructing new attributes from the other if it's
|
||||
// not None and replace the key/value with self key/value.
|
||||
pub fn merge(&mut self, other: Option<AttributesData>) {
|
||||
if other.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
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());
|
||||
// }
|
||||
new_attributes.insert(k.clone(), v.clone());
|
||||
});
|
||||
self.inner = new_attributes;
|
||||
} else {
|
||||
self.inner.extend(other.unwrap().inner);
|
||||
}
|
||||
let mut new_attributes = other.unwrap().inner;
|
||||
self.inner.iter().for_each(|(k, v)| {
|
||||
new_attributes.insert(k.clone(), v.clone());
|
||||
});
|
||||
self.inner = new_attributes;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AttributesDataRule {
|
||||
fn apply_rule(&mut self);
|
||||
|
||||
fn into_attributes(self) -> Attributes;
|
||||
}
|
||||
impl AttributesDataRule for AttributesData {
|
||||
fn apply_rule(&mut self) { self.inner.retain(|_, v| !should_remove(v)); }
|
||||
|
||||
fn into_attributes(mut self) -> Attributes {
|
||||
if self.is_plain() {
|
||||
Attributes::default()
|
||||
} else {
|
||||
Attributes::Custom(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AttributesRule {
|
||||
fn apply_rule(self) -> Attributes;
|
||||
}
|
||||
|
||||
impl AttributesRule for Attributes {
|
||||
fn apply_rule(self) -> Attributes {
|
||||
match self {
|
||||
Attributes::Follow => self,
|
||||
Attributes::Custom(mut data) => {
|
||||
data.apply_rule();
|
||||
data.into_attributes()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
// impl std::convert::From<HashMap<String, String>> for AttributesData {
|
||||
// fn from(attributes: HashMap<String, String>) -> Self { AttributesData {
|
||||
// inner: attributes } } }
|
||||
|
||||
impl std::ops::Deref for AttributesData {
|
||||
type Target = HashMap<Attribute, String>;
|
||||
|
||||
@ -99,3 +66,7 @@ impl std::ops::Deref for AttributesData {
|
||||
impl std::ops::DerefMut for AttributesData {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner }
|
||||
}
|
||||
|
||||
impl std::convert::Into<Attributes> for AttributesData {
|
||||
fn into(self) -> Attributes { Attributes::Custom(self) }
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
};
|
||||
use bytecount::num_chars;
|
||||
use std::{
|
||||
cmp::{max, min, Ordering},
|
||||
cmp::{min, Ordering},
|
||||
fmt,
|
||||
iter::FromIterator,
|
||||
str::FromStr,
|
||||
@ -46,7 +46,7 @@ impl fmt::Display for Delta {
|
||||
// f.write_str(&serde_json::to_string(self).unwrap_or("".to_owned()))?;
|
||||
f.write_str("[ ")?;
|
||||
for op in &self.ops {
|
||||
f.write_fmt(format_args!("{} ", op));
|
||||
f.write_fmt(format_args!("{} ", op))?;
|
||||
}
|
||||
f.write_str("]")?;
|
||||
Ok(())
|
||||
@ -232,7 +232,7 @@ impl Delta {
|
||||
},
|
||||
(Some(Operation::Insert(insert)), Some(Operation::Retain(o_retain))) => {
|
||||
let mut composed_attrs = compose_operation(&next_op1, &next_op2);
|
||||
composed_attrs = composed_attrs.apply_rule();
|
||||
composed_attrs = composed_attrs.remove_empty();
|
||||
|
||||
log::debug!(
|
||||
"compose: [{} - {}], composed_attrs: {}",
|
||||
@ -589,35 +589,28 @@ impl Delta {
|
||||
log::debug!("Get attributes at {:?}", interval);
|
||||
self.ops.iter().for_each(|op| match op {
|
||||
Operation::Delete(_n) => {},
|
||||
Operation::Retain(_retain) => {
|
||||
unimplemented!()
|
||||
// if interval.contains(retain.n as usize) {
|
||||
// match &retain.attributes {
|
||||
// Attributes::Follow => {},
|
||||
// Attributes::Custom(data) => {
|
||||
// attributes_data.extend(data.clone());
|
||||
// },
|
||||
// Attributes::Empty => {},
|
||||
// }
|
||||
// }
|
||||
Operation::Retain(retain) => {
|
||||
if let Attributes::Custom(data) = &retain.attributes {
|
||||
if interval.contains_range(offset, offset + retain.n) {
|
||||
log::debug!("extend retain attributes with {} ", &data);
|
||||
attributes_data.extend(Some(data.clone()));
|
||||
}
|
||||
}
|
||||
offset += retain.n;
|
||||
},
|
||||
Operation::Insert(insert) => {
|
||||
let end = insert.num_chars() as usize;
|
||||
match &insert.attributes {
|
||||
Attributes::Follow => {},
|
||||
Attributes::Custom(data) => {
|
||||
if interval.contains_range(offset, offset + end) {
|
||||
log::debug!("extend attributes with {} ", &data);
|
||||
attributes_data.extend(Some(data.clone()), false);
|
||||
}
|
||||
},
|
||||
if let Attributes::Custom(data) = &insert.attributes {
|
||||
if interval.contains_range(offset, offset + end) {
|
||||
log::debug!("extend insert attributes with {} ", &data);
|
||||
attributes_data.extend(Some(data.clone()));
|
||||
}
|
||||
}
|
||||
offset += end
|
||||
offset += end;
|
||||
},
|
||||
});
|
||||
|
||||
attributes_data.apply_rule();
|
||||
let attribute = attributes_data.into_attributes();
|
||||
let attribute: Attributes = attributes_data.into();
|
||||
log::debug!("Get attributes result: {} ", &attribute);
|
||||
attribute
|
||||
}
|
||||
|
@ -55,7 +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) => !data.is_empty(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ impl Operation {
|
||||
|
||||
impl fmt::Display for Operation {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("{");
|
||||
f.write_str("{")?;
|
||||
match self {
|
||||
Operation::Delete(n) => {
|
||||
f.write_fmt(format_args!("delete: {}", n))?;
|
||||
@ -108,7 +108,7 @@ impl fmt::Display for Operation {
|
||||
f.write_fmt(format_args!("{}", i))?;
|
||||
},
|
||||
}
|
||||
f.write_str("}");
|
||||
f.write_str("}")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -159,7 +159,7 @@ impl Retain {
|
||||
pub fn is_plain(&self) -> bool {
|
||||
match &self.attributes {
|
||||
Attributes::Follow => true,
|
||||
Attributes::Custom(data) => data.is_plain(),
|
||||
Attributes::Custom(data) => data.is_empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -250,6 +250,6 @@ impl std::convert::From<&str> for Insert {
|
||||
fn is_empty(attributes: &Attributes) -> bool {
|
||||
match attributes {
|
||||
Attributes::Follow => true,
|
||||
Attributes::Custom(data) => data.is_plain(),
|
||||
Attributes::Custom(data) => data.is_empty(),
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use derive_more::Display;
|
||||
use flowy_ot::{client::Document, core::*};
|
||||
use rand::{prelude::*, Rng as WrappedRng};
|
||||
use std::{sync::Once, thread::sleep_ms, time::Duration};
|
||||
use std::{sync::Once, time::Duration};
|
||||
|
||||
#[derive(Clone, Debug, Display)]
|
||||
pub enum TestOp {
|
||||
|
Loading…
Reference in New Issue
Block a user