mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix format and clippy warnings
This commit is contained in:
@ -8,14 +8,18 @@ impl<T> std::default::Default for DeltaBuilder<T>
|
||||
where
|
||||
T: Attributes,
|
||||
{
|
||||
fn default() -> Self { Self { delta: Delta::new() } }
|
||||
fn default() -> Self {
|
||||
Self { delta: Delta::new() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DeltaBuilder<T>
|
||||
where
|
||||
T: Attributes,
|
||||
{
|
||||
pub fn new() -> Self { DeltaBuilder::default() }
|
||||
pub fn new() -> Self {
|
||||
DeltaBuilder::default()
|
||||
}
|
||||
|
||||
pub fn retain_with_attributes(mut self, n: usize, attrs: T) -> Self {
|
||||
self.delta.retain(n, attrs);
|
||||
@ -47,5 +51,7 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Delta<T> { self.delta }
|
||||
pub fn build(self) -> Delta<T> {
|
||||
self.delta
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
#![allow(clippy::while_let_on_iterator)]
|
||||
use crate::{
|
||||
core::{Attributes, Delta, Interval, Operation},
|
||||
errors::{ErrorBuilder, OTError, OTErrorCode},
|
||||
@ -35,9 +36,13 @@ where
|
||||
}
|
||||
|
||||
// get the next operation interval
|
||||
pub fn next_iv(&self) -> Interval { self.next_iv_with_len(None).unwrap_or_else(|| Interval::new(0, 0)) }
|
||||
pub fn next_iv(&self) -> Interval {
|
||||
self.next_iv_with_len(None).unwrap_or_else(|| Interval::new(0, 0))
|
||||
}
|
||||
|
||||
pub fn next_op(&mut self) -> Option<Operation<T>> { self.next_with_len(None) }
|
||||
pub fn next_op(&mut self) -> Option<Operation<T>> {
|
||||
self.next_with_len(None)
|
||||
}
|
||||
|
||||
// get the last operation before the end.
|
||||
// checkout the delta_next_op_with_len_cross_op_return_last test for more detail
|
||||
@ -91,7 +96,9 @@ where
|
||||
find_op
|
||||
}
|
||||
|
||||
pub fn has_next(&self) -> bool { self.next_iter_op().is_some() }
|
||||
pub fn has_next(&self) -> bool {
|
||||
self.next_iter_op().is_some()
|
||||
}
|
||||
|
||||
fn descend(&mut self, index: usize) {
|
||||
self.consume_iv.start += index;
|
||||
@ -151,7 +158,7 @@ where
|
||||
Some((o_index, op)) => {
|
||||
cursor.op_index = o_index;
|
||||
Some(op)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,9 @@ impl<T> Delta<T>
|
||||
where
|
||||
T: Attributes,
|
||||
{
|
||||
pub fn new() -> Self { Self::default() }
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
@ -108,21 +110,21 @@ where
|
||||
[.., Operation::<T>::Insert(insert)] => {
|
||||
//
|
||||
insert.merge_or_new_op(&s, attributes)
|
||||
},
|
||||
}
|
||||
[.., Operation::<T>::Insert(pre_insert), Operation::Delete(_)] => {
|
||||
//
|
||||
pre_insert.merge_or_new_op(&s, attributes)
|
||||
},
|
||||
}
|
||||
[.., op_last @ Operation::<T>::Delete(_)] => {
|
||||
let new_last = op_last.clone();
|
||||
*op_last = OpBuilder::<T>::insert(&s).attributes(attributes).build();
|
||||
Some(new_last)
|
||||
},
|
||||
}
|
||||
_ => Some(OpBuilder::<T>::insert(&s).attributes(attributes).build()),
|
||||
};
|
||||
|
||||
match new_last {
|
||||
None => {},
|
||||
None => {}
|
||||
Some(new_last) => self.ops.push(new_last),
|
||||
}
|
||||
}
|
||||
@ -157,15 +159,15 @@ where
|
||||
for c in code_point_iter.take(retain.n as usize) {
|
||||
new_s.push_str(str::from_utf8(c.0).unwrap_or(""));
|
||||
}
|
||||
},
|
||||
}
|
||||
Operation::Delete(delete) => {
|
||||
for _ in 0..*delete {
|
||||
code_point_iter.next();
|
||||
}
|
||||
},
|
||||
}
|
||||
Operation::Insert(insert) => {
|
||||
new_s += &insert.s;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(new_s)
|
||||
@ -185,13 +187,13 @@ where
|
||||
for _ in 0..retain.n {
|
||||
chars.next();
|
||||
}
|
||||
},
|
||||
}
|
||||
Operation::Insert(insert) => {
|
||||
inverted.delete(insert.utf16_size());
|
||||
},
|
||||
}
|
||||
Operation::Delete(delete) => {
|
||||
inverted.insert(&chars.take(*delete as usize).collect::<String>(), op.get_attributes());
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
inverted
|
||||
@ -199,11 +201,17 @@ where
|
||||
|
||||
/// Checks if this operation has no effect.
|
||||
#[inline]
|
||||
pub fn is_noop(&self) -> bool { matches!(self.ops.as_slice(), [] | [Operation::Retain(_)]) }
|
||||
pub fn is_noop(&self) -> bool {
|
||||
matches!(self.ops.as_slice(), [] | [Operation::Retain(_)])
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool { self.ops.is_empty() }
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.ops.is_empty()
|
||||
}
|
||||
|
||||
pub fn extend(&mut self, other: Self) { other.ops.into_iter().for_each(|op| self.add(op)); }
|
||||
pub fn extend(&mut self, other: Self) {
|
||||
other.ops.into_iter().for_each(|op| self.add(op));
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> OperationTransformable for Delta<T>
|
||||
@ -248,20 +256,20 @@ where
|
||||
let composed_attrs = retain.attributes.compose(&other_retain.attributes)?;
|
||||
|
||||
new_delta.add(OpBuilder::retain(retain.n).attributes(composed_attrs).build())
|
||||
},
|
||||
}
|
||||
(Operation::Insert(insert), Operation::Retain(other_retain)) => {
|
||||
let mut composed_attrs = insert.attributes.compose(&other_retain.attributes)?;
|
||||
composed_attrs.remove_empty();
|
||||
new_delta.add(OpBuilder::insert(op.get_data()).attributes(composed_attrs).build())
|
||||
},
|
||||
}
|
||||
(Operation::Retain(_), Operation::Delete(_)) => {
|
||||
new_delta.add(other_op);
|
||||
},
|
||||
}
|
||||
(a, b) => {
|
||||
debug_assert_eq!(a.is_insert(), true);
|
||||
debug_assert_eq!(b.is_delete(), true);
|
||||
debug_assert!(a.is_insert());
|
||||
debug_assert!(b.is_delete());
|
||||
continue;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(new_delta)
|
||||
@ -296,94 +304,94 @@ where
|
||||
a_prime.insert(&insert.s, insert.attributes.clone());
|
||||
b_prime.retain(insert.utf16_size(), insert.attributes.clone());
|
||||
next_op1 = ops1.next();
|
||||
},
|
||||
}
|
||||
(_, Some(Operation::Insert(o_insert))) => {
|
||||
let composed_attrs = transform_op_attribute(&next_op1, &next_op2)?;
|
||||
a_prime.retain(o_insert.utf16_size(), composed_attrs.clone());
|
||||
b_prime.insert(&o_insert.s, composed_attrs);
|
||||
next_op2 = ops2.next();
|
||||
},
|
||||
}
|
||||
(None, _) => {
|
||||
return Err(ErrorBuilder::new(OTErrorCode::IncompatibleLength).build());
|
||||
},
|
||||
}
|
||||
(_, None) => {
|
||||
return Err(ErrorBuilder::new(OTErrorCode::IncompatibleLength).build());
|
||||
},
|
||||
}
|
||||
(Some(Operation::Retain(retain)), Some(Operation::Retain(o_retain))) => {
|
||||
let composed_attrs = transform_op_attribute(&next_op1, &next_op2)?;
|
||||
match retain.cmp(&o_retain) {
|
||||
match retain.cmp(o_retain) {
|
||||
Ordering::Less => {
|
||||
a_prime.retain(retain.n, composed_attrs.clone());
|
||||
b_prime.retain(retain.n, composed_attrs.clone());
|
||||
next_op2 = Some(OpBuilder::retain(o_retain.n - retain.n).build());
|
||||
next_op1 = ops1.next();
|
||||
},
|
||||
}
|
||||
Ordering::Equal => {
|
||||
a_prime.retain(retain.n, composed_attrs.clone());
|
||||
b_prime.retain(retain.n, composed_attrs.clone());
|
||||
next_op1 = ops1.next();
|
||||
next_op2 = ops2.next();
|
||||
},
|
||||
}
|
||||
Ordering::Greater => {
|
||||
a_prime.retain(o_retain.n, composed_attrs.clone());
|
||||
b_prime.retain(o_retain.n, composed_attrs.clone());
|
||||
next_op1 = Some(OpBuilder::retain(retain.n - o_retain.n).build());
|
||||
next_op2 = ops2.next();
|
||||
},
|
||||
}
|
||||
};
|
||||
},
|
||||
(Some(Operation::Delete(i)), Some(Operation::Delete(j))) => match i.cmp(&j) {
|
||||
}
|
||||
(Some(Operation::Delete(i)), Some(Operation::Delete(j))) => match i.cmp(j) {
|
||||
Ordering::Less => {
|
||||
next_op2 = Some(OpBuilder::delete(*j - *i).build());
|
||||
next_op1 = ops1.next();
|
||||
},
|
||||
}
|
||||
Ordering::Equal => {
|
||||
next_op1 = ops1.next();
|
||||
next_op2 = ops2.next();
|
||||
},
|
||||
}
|
||||
Ordering::Greater => {
|
||||
next_op1 = Some(OpBuilder::delete(*i - *j).build());
|
||||
next_op2 = ops2.next();
|
||||
},
|
||||
}
|
||||
},
|
||||
(Some(Operation::Delete(i)), Some(Operation::Retain(o_retain))) => {
|
||||
match i.cmp(&o_retain) {
|
||||
match i.cmp(o_retain) {
|
||||
Ordering::Less => {
|
||||
a_prime.delete(*i);
|
||||
next_op2 = Some(OpBuilder::retain(o_retain.n - *i).build());
|
||||
next_op1 = ops1.next();
|
||||
},
|
||||
}
|
||||
Ordering::Equal => {
|
||||
a_prime.delete(*i);
|
||||
next_op1 = ops1.next();
|
||||
next_op2 = ops2.next();
|
||||
},
|
||||
}
|
||||
Ordering::Greater => {
|
||||
a_prime.delete(o_retain.n);
|
||||
next_op1 = Some(OpBuilder::delete(*i - o_retain.n).build());
|
||||
next_op2 = ops2.next();
|
||||
},
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
(Some(Operation::Retain(retain)), Some(Operation::Delete(j))) => {
|
||||
match retain.cmp(&j) {
|
||||
match retain.cmp(j) {
|
||||
Ordering::Less => {
|
||||
b_prime.delete(retain.n);
|
||||
next_op2 = Some(OpBuilder::delete(*j - retain.n).build());
|
||||
next_op1 = ops1.next();
|
||||
},
|
||||
}
|
||||
Ordering::Equal => {
|
||||
b_prime.delete(retain.n);
|
||||
next_op1 = ops1.next();
|
||||
next_op2 = ops2.next();
|
||||
},
|
||||
}
|
||||
Ordering::Greater => {
|
||||
b_prime.delete(*j);
|
||||
next_op1 = Some(OpBuilder::retain(retain.n - *j).build());
|
||||
next_op2 = ops2.next();
|
||||
},
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok((a_prime, b_prime))
|
||||
@ -402,7 +410,7 @@ where
|
||||
Operation::Delete(n) => {
|
||||
invert_from_other(&mut inverted, other, op, index, index + *n);
|
||||
index += len;
|
||||
},
|
||||
}
|
||||
Operation::Retain(_) => {
|
||||
match op.has_attribute() {
|
||||
true => invert_from_other(&mut inverted, other, op, index, index + len),
|
||||
@ -410,14 +418,14 @@ where
|
||||
// tracing::trace!("invert retain: {} by retain {} {}", op, len,
|
||||
// op.get_attributes());
|
||||
inverted.retain(len as usize, op.get_attributes())
|
||||
},
|
||||
}
|
||||
}
|
||||
index += len;
|
||||
},
|
||||
}
|
||||
Operation::Insert(_) => {
|
||||
// tracing::trace!("invert insert: {} by delete {}", op, len);
|
||||
inverted.delete(len as usize);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
inverted
|
||||
@ -449,7 +457,7 @@ fn invert_from_other<T: Attributes>(
|
||||
Operation::Delete(n) => {
|
||||
tracing::trace!("invert delete: {} by add {}", n, other_op);
|
||||
base.add(other_op);
|
||||
},
|
||||
}
|
||||
Operation::Retain(_retain) => {
|
||||
tracing::trace!(
|
||||
"invert attributes: {:?}, {:?}",
|
||||
@ -458,10 +466,10 @@ fn invert_from_other<T: Attributes>(
|
||||
);
|
||||
let inverted_attrs = operation.get_attributes().invert(&other_op.get_attributes());
|
||||
base.retain(other_op.len(), inverted_attrs);
|
||||
},
|
||||
}
|
||||
Operation::Insert(_) => {
|
||||
log::error!("Impossible to here. Insert operation should be treated as delete")
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -505,7 +513,9 @@ impl<T> Delta<T>
|
||||
where
|
||||
T: Attributes + serde::Serialize,
|
||||
{
|
||||
pub fn to_json(&self) -> String { serde_json::to_string(self).unwrap_or_else(|_| "".to_owned()) }
|
||||
pub fn to_json(&self) -> String {
|
||||
serde_json::to_string(self).unwrap_or_else(|_| "".to_owned())
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Bytes {
|
||||
let json = self.to_json();
|
||||
@ -531,7 +541,9 @@ where
|
||||
T: Attributes + DeserializeOwned,
|
||||
{
|
||||
type Error = OTError;
|
||||
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> { Delta::from_bytes(bytes) }
|
||||
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
|
||||
Delta::from_bytes(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::convert::TryFrom<Bytes> for Delta<T>
|
||||
@ -540,5 +552,7 @@ where
|
||||
{
|
||||
type Error = OTError;
|
||||
|
||||
fn try_from(bytes: Bytes) -> Result<Self, Self::Error> { Delta::from_bytes(&bytes) }
|
||||
fn try_from(bytes: Bytes) -> Result<Self, Self::Error> {
|
||||
Delta::from_bytes(&bytes)
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,7 @@ use crate::core::{Attributes, Delta};
|
||||
use serde::{
|
||||
de::{SeqAccess, Visitor},
|
||||
ser::SerializeSeq,
|
||||
Deserialize,
|
||||
Deserializer,
|
||||
Serialize,
|
||||
Serializer,
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
};
|
||||
use std::{fmt, marker::PhantomData};
|
||||
|
||||
@ -41,7 +38,9 @@ where
|
||||
{
|
||||
type Value = Delta<T>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a sequence") }
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a sequence")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
|
@ -32,7 +32,9 @@ where
|
||||
Self { cursor }
|
||||
}
|
||||
|
||||
pub fn ops(&mut self) -> Vec<Operation<T>> { self.collect::<Vec<_>>() }
|
||||
pub fn ops(&mut self) -> Vec<Operation<T>> {
|
||||
self.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub fn next_op_len(&self) -> Option<usize> {
|
||||
let interval = self.cursor.next_iv();
|
||||
@ -43,9 +45,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_op(&mut self) -> Option<Operation<T>> { self.cursor.next_op() }
|
||||
pub fn next_op(&mut self) -> Option<Operation<T>> {
|
||||
self.cursor.next_op()
|
||||
}
|
||||
|
||||
pub fn next_op_with_len(&mut self, len: usize) -> Option<Operation<T>> { self.cursor.next_with_len(Some(len)) }
|
||||
pub fn next_op_with_len(&mut self, len: usize) -> Option<Operation<T>> {
|
||||
self.cursor.next_with_len(Some(len))
|
||||
}
|
||||
|
||||
// find next op contains NEW_LINE
|
||||
pub fn next_op_with_newline(&mut self) -> Option<(Operation<T>, usize)> {
|
||||
@ -64,12 +70,14 @@ where
|
||||
|
||||
pub fn seek<M: Metric>(&mut self, index: usize) {
|
||||
match M::seek(&mut self.cursor, index) {
|
||||
Ok(_) => {},
|
||||
Ok(_) => {}
|
||||
Err(e) => log::error!("Seek fail: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_next(&self) -> bool { self.cursor.has_next() }
|
||||
pub fn has_next(&self) -> bool {
|
||||
self.cursor.has_next()
|
||||
}
|
||||
|
||||
pub fn is_next_insert(&self) -> bool {
|
||||
match self.cursor.next_iter_op() {
|
||||
@ -98,7 +106,9 @@ where
|
||||
T: Attributes,
|
||||
{
|
||||
type Item = Operation<T>;
|
||||
fn next(&mut self) -> Option<Self::Item> { self.next_op() }
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.next_op()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty_line_at_index(delta: &Delta<RichTextAttributes>, index: usize) -> bool {
|
||||
@ -149,14 +159,18 @@ where
|
||||
{
|
||||
type Target = DeltaIter<'a, T>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.delta_iter }
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.delta_iter
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> DerefMut for AttributesIter<'a, T>
|
||||
where
|
||||
T: Attributes,
|
||||
{
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.delta_iter }
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.delta_iter
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for AttributesIter<'a, T>
|
||||
@ -171,18 +185,18 @@ where
|
||||
let mut attributes = T::default();
|
||||
|
||||
match next_op.unwrap() {
|
||||
Operation::<T>::Delete(_n) => {},
|
||||
Operation::<T>::Delete(_n) => {}
|
||||
Operation::<T>::Retain(retain) => {
|
||||
tracing::trace!("extend retain attributes with {} ", &retain.attributes);
|
||||
attributes.extend_other(retain.attributes.clone());
|
||||
|
||||
length = retain.n;
|
||||
},
|
||||
}
|
||||
Operation::<T>::Insert(insert) => {
|
||||
tracing::trace!("extend insert attributes with {} ", &insert.attributes);
|
||||
attributes.extend_other(insert.attributes.clone());
|
||||
length = insert.utf16_size();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Some((length, attributes))
|
||||
@ -221,15 +235,23 @@ impl OpNewline {
|
||||
OpNewline::NotFound
|
||||
}
|
||||
|
||||
pub fn is_start(&self) -> bool { self == &OpNewline::Start || self.is_equal() }
|
||||
pub fn is_start(&self) -> bool {
|
||||
self == &OpNewline::Start || self.is_equal()
|
||||
}
|
||||
|
||||
pub fn is_end(&self) -> bool { self == &OpNewline::End || self.is_equal() }
|
||||
pub fn is_end(&self) -> bool {
|
||||
self == &OpNewline::End || self.is_equal()
|
||||
}
|
||||
|
||||
pub fn is_not_found(&self) -> bool { self == &OpNewline::NotFound }
|
||||
pub fn is_not_found(&self) -> bool {
|
||||
self == &OpNewline::NotFound
|
||||
}
|
||||
|
||||
pub fn is_contain(&self) -> bool {
|
||||
self.is_start() || self.is_end() || self.is_equal() || self == &OpNewline::Contain
|
||||
}
|
||||
|
||||
pub fn is_equal(&self) -> bool { self == &OpNewline::Equal }
|
||||
pub fn is_equal(&self) -> bool {
|
||||
self == &OpNewline::Equal
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,13 @@ pub struct FlowyStr(pub String);
|
||||
|
||||
impl FlowyStr {
|
||||
// https://stackoverflow.com/questions/2241348/what-is-unicode-utf-8-utf-16
|
||||
pub fn utf16_size(&self) -> usize { count_utf16_code_units(&self.0) }
|
||||
pub fn utf16_size(&self) -> usize {
|
||||
count_utf16_code_units(&self.0)
|
||||
}
|
||||
|
||||
pub fn utf16_code_unit_iter(&self) -> Utf16CodeUnitIterator { Utf16CodeUnitIterator::new(self) }
|
||||
pub fn utf16_code_unit_iter(&self) -> Utf16CodeUnitIterator {
|
||||
Utf16CodeUnitIterator::new(self)
|
||||
}
|
||||
|
||||
pub fn sub_str(&self, interval: Interval) -> Option<String> {
|
||||
let mut iter = Utf16CodeUnitIterator::new(self);
|
||||
@ -30,29 +34,41 @@ impl FlowyStr {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn utf16_code_point_iter(&self) -> FlowyUtf16CodePointIterator { FlowyUtf16CodePointIterator::new(self, 0) }
|
||||
fn utf16_code_point_iter(&self) -> FlowyUtf16CodePointIterator {
|
||||
FlowyUtf16CodePointIterator::new(self, 0)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for FlowyStr {
|
||||
type Target = String;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for FlowyStr {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<String> for FlowyStr {
|
||||
fn from(s: String) -> Self { FlowyStr(s) }
|
||||
fn from(s: String) -> Self {
|
||||
FlowyStr(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<&str> for FlowyStr {
|
||||
fn from(s: &str) -> Self { s.to_owned().into() }
|
||||
fn from(s: &str) -> Self {
|
||||
s.to_owned().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for FlowyStr {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(&self.0) }
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Add<&str> for FlowyStr {
|
||||
@ -65,7 +81,9 @@ impl std::ops::Add<&str> for FlowyStr {
|
||||
}
|
||||
|
||||
impl std::ops::AddAssign<&str> for FlowyStr {
|
||||
fn add_assign(&mut self, rhs: &str) { self.0 += rhs; }
|
||||
fn add_assign(&mut self, rhs: &str) {
|
||||
self.0 += rhs;
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for FlowyStr {
|
||||
@ -87,7 +105,9 @@ impl<'de> Deserialize<'de> for FlowyStr {
|
||||
impl<'de> Visitor<'de> for FlowyStrVisitor {
|
||||
type Value = FlowyStr;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a str") }
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a str")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
@ -152,7 +172,9 @@ pub struct FlowyUtf16CodePointIterator<'a> {
|
||||
}
|
||||
|
||||
impl<'a> FlowyUtf16CodePointIterator<'a> {
|
||||
pub fn new(s: &'a FlowyStr, offset: usize) -> Self { FlowyUtf16CodePointIterator { s, offset } }
|
||||
pub fn new(s: &'a FlowyStr, offset: usize) -> Self {
|
||||
FlowyUtf16CodePointIterator { s, offset }
|
||||
}
|
||||
}
|
||||
|
||||
use crate::core::Interval;
|
||||
|
@ -23,23 +23,37 @@ impl Interval {
|
||||
Interval { start, end }
|
||||
}
|
||||
|
||||
pub fn start(&self) -> usize { self.start }
|
||||
pub fn start(&self) -> usize {
|
||||
self.start
|
||||
}
|
||||
|
||||
pub fn end(&self) -> usize { self.end }
|
||||
pub fn end(&self) -> usize {
|
||||
self.end
|
||||
}
|
||||
|
||||
pub fn start_end(&self) -> (usize, usize) { (self.start, self.end) }
|
||||
pub fn start_end(&self) -> (usize, usize) {
|
||||
(self.start, self.end)
|
||||
}
|
||||
|
||||
pub fn is_before(&self, val: usize) -> bool { self.end <= val }
|
||||
pub fn is_before(&self, val: usize) -> bool {
|
||||
self.end <= val
|
||||
}
|
||||
|
||||
pub fn contains(&self, val: usize) -> bool { self.start <= val && val < self.end }
|
||||
pub fn contains(&self, val: usize) -> bool {
|
||||
self.start <= val && val < self.end
|
||||
}
|
||||
|
||||
pub fn contains_range(&self, start: usize, end: usize) -> bool {
|
||||
!self.intersect(Interval::new(start, end)).is_empty()
|
||||
}
|
||||
|
||||
pub fn is_after(&self, val: usize) -> bool { self.start > val }
|
||||
pub fn is_after(&self, val: usize) -> bool {
|
||||
self.start > val
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool { self.end <= self.start }
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.end <= self.start
|
||||
}
|
||||
|
||||
pub fn intersect(&self, other: Interval) -> Interval {
|
||||
let start = max(self.start, other.start);
|
||||
@ -93,19 +107,27 @@ impl Interval {
|
||||
Interval { start, end }
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize { self.end - self.start }
|
||||
pub fn size(&self) -> usize {
|
||||
self.end - self.start
|
||||
}
|
||||
}
|
||||
|
||||
impl std::default::Default for Interval {
|
||||
fn default() -> Self { Interval::new(0, 0) }
|
||||
fn default() -> Self {
|
||||
Interval::new(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Interval {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "[{}, {})", self.start(), self.end()) }
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[{}, {})", self.start(), self.end())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Interval {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self, f) }
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Range<usize>> for Interval {
|
||||
@ -116,15 +138,21 @@ impl From<Range<usize>> for Interval {
|
||||
}
|
||||
|
||||
impl From<RangeTo<usize>> for Interval {
|
||||
fn from(src: RangeTo<usize>) -> Interval { Interval::new(0, src.end) }
|
||||
fn from(src: RangeTo<usize>) -> Interval {
|
||||
Interval::new(0, src.end)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RangeInclusive<usize>> for Interval {
|
||||
fn from(src: RangeInclusive<usize>) -> Interval { Interval::new(*src.start(), src.end().saturating_add(1)) }
|
||||
fn from(src: RangeInclusive<usize>) -> Interval {
|
||||
Interval::new(*src.start(), src.end().saturating_add(1))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RangeToInclusive<usize>> for Interval {
|
||||
fn from(src: RangeToInclusive<usize>) -> Interval { Interval::new(0, src.end.saturating_add(1)) }
|
||||
fn from(src: RangeToInclusive<usize>) -> Interval {
|
||||
Interval::new(0, src.end.saturating_add(1))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -21,11 +21,17 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn retain(n: usize) -> OpBuilder<T> { OpBuilder::new(Operation::Retain(n.into())) }
|
||||
pub fn retain(n: usize) -> OpBuilder<T> {
|
||||
OpBuilder::new(Operation::Retain(n.into()))
|
||||
}
|
||||
|
||||
pub fn delete(n: usize) -> OpBuilder<T> { OpBuilder::new(Operation::Delete(n)) }
|
||||
pub fn delete(n: usize) -> OpBuilder<T> {
|
||||
OpBuilder::new(Operation::Delete(n))
|
||||
}
|
||||
|
||||
pub fn insert(s: &str) -> OpBuilder<T> { OpBuilder::new(Operation::Insert(s.into())) }
|
||||
pub fn insert(s: &str) -> OpBuilder<T> {
|
||||
OpBuilder::new(Operation::Insert(s.into()))
|
||||
}
|
||||
|
||||
pub fn attributes(mut self, attrs: T) -> OpBuilder<T> {
|
||||
self.attrs = attrs;
|
||||
@ -35,7 +41,7 @@ where
|
||||
pub fn build(self) -> Operation<T> {
|
||||
let mut operation = self.ty;
|
||||
match &mut operation {
|
||||
Operation::Delete(_) => {},
|
||||
Operation::Delete(_) => {}
|
||||
Operation::Retain(retain) => retain.attributes = self.attrs,
|
||||
Operation::Insert(insert) => insert.attributes = self.attrs,
|
||||
}
|
||||
|
@ -61,7 +61,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_attribute(&self) -> bool { !self.get_attributes().is_empty() }
|
||||
pub fn has_attribute(&self) -> bool {
|
||||
!self.get_attributes().is_empty()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
match self {
|
||||
@ -71,7 +73,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn split(&self, index: usize) -> (Option<Operation<T>>, Option<Operation<T>>) {
|
||||
@ -82,11 +86,11 @@ where
|
||||
Operation::Delete(n) => {
|
||||
left = Some(OpBuilder::<T>::delete(index).build());
|
||||
right = Some(OpBuilder::<T>::delete(*n - index).build());
|
||||
},
|
||||
}
|
||||
Operation::Retain(retain) => {
|
||||
left = Some(OpBuilder::<T>::delete(index).build());
|
||||
right = Some(OpBuilder::<T>::delete(retain.n - index).build());
|
||||
},
|
||||
}
|
||||
Operation::Insert(insert) => {
|
||||
let attributes = self.get_attributes();
|
||||
left = Some(
|
||||
@ -99,7 +103,7 @@ where
|
||||
.attributes(attributes)
|
||||
.build(),
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
(left, right)
|
||||
@ -118,7 +122,7 @@ where
|
||||
let s = insert.s.sub_str(interval).unwrap_or_else(|| "".to_owned());
|
||||
OpBuilder::insert(&s).attributes(insert.attributes.clone()).build()
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
match op.is_empty() {
|
||||
@ -166,13 +170,13 @@ where
|
||||
match self {
|
||||
Operation::Delete(n) => {
|
||||
f.write_fmt(format_args!("delete: {}", n))?;
|
||||
},
|
||||
}
|
||||
Operation::Retain(r) => {
|
||||
f.write_fmt(format_args!("{}", r))?;
|
||||
},
|
||||
}
|
||||
Operation::Insert(i) => {
|
||||
f.write_fmt(format_args!("{}", i))?;
|
||||
},
|
||||
}
|
||||
}
|
||||
f.write_str("}")?;
|
||||
Ok(())
|
||||
@ -219,7 +223,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_plain(&self) -> bool { self.attributes.is_empty() }
|
||||
pub fn is_plain(&self) -> bool {
|
||||
self.attributes.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::convert::From<usize> for Retain<T>
|
||||
@ -240,14 +246,18 @@ where
|
||||
{
|
||||
type Target = usize;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.n }
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.n
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for Retain<T>
|
||||
where
|
||||
T: Attributes,
|
||||
{
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.n }
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.n
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
@ -284,7 +294,9 @@ impl<T> Insert<T>
|
||||
where
|
||||
T: Attributes,
|
||||
{
|
||||
pub fn utf16_size(&self) -> usize { self.s.utf16_size() }
|
||||
pub fn utf16_size(&self) -> usize {
|
||||
self.s.utf16_size()
|
||||
}
|
||||
|
||||
pub fn merge_or_new_op(&mut self, s: &str, attributes: T) -> Option<Operation<T>> {
|
||||
if self.attributes == attributes {
|
||||
@ -295,7 +307,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_plain(&self) -> bool { self.attributes.is_empty() }
|
||||
pub fn is_plain(&self) -> bool {
|
||||
self.attributes.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::convert::From<String> for Insert<T>
|
||||
@ -314,7 +328,9 @@ impl<T> std::convert::From<&str> for Insert<T>
|
||||
where
|
||||
T: Attributes,
|
||||
{
|
||||
fn from(s: &str) -> Self { Insert::from(s.to_owned()) }
|
||||
fn from(s: &str) -> Self {
|
||||
Insert::from(s.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::convert::From<FlowyStr> for Insert<T>
|
||||
|
@ -3,10 +3,7 @@ use serde::{
|
||||
de,
|
||||
de::{MapAccess, SeqAccess, Visitor},
|
||||
ser::SerializeMap,
|
||||
Deserialize,
|
||||
Deserializer,
|
||||
Serialize,
|
||||
Serializer,
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
};
|
||||
use std::{fmt, marker::PhantomData};
|
||||
|
||||
@ -24,7 +21,7 @@ where
|
||||
let mut map = serializer.serialize_map(Some(1))?;
|
||||
map.serialize_entry("delete", i)?;
|
||||
map.end()
|
||||
},
|
||||
}
|
||||
Operation::Insert(insert) => insert.serialize(serializer),
|
||||
}
|
||||
}
|
||||
@ -64,28 +61,28 @@ where
|
||||
return Err(de::Error::duplicate_field("operation"));
|
||||
}
|
||||
operation = Some(Operation::<T>::Delete(map.next_value()?));
|
||||
},
|
||||
}
|
||||
"retain" => {
|
||||
if operation.is_some() {
|
||||
return Err(de::Error::duplicate_field("operation"));
|
||||
}
|
||||
let i: usize = map.next_value()?;
|
||||
operation = Some(Operation::<T>::Retain(i.into()));
|
||||
},
|
||||
}
|
||||
"insert" => {
|
||||
if operation.is_some() {
|
||||
return Err(de::Error::duplicate_field("operation"));
|
||||
}
|
||||
let i: String = map.next_value()?;
|
||||
operation = Some(Operation::<T>::Insert(i.into()));
|
||||
},
|
||||
}
|
||||
"attributes" => {
|
||||
if attributes.is_some() {
|
||||
return Err(de::Error::duplicate_field("attributes"));
|
||||
}
|
||||
let map: T = map.next_value()?;
|
||||
attributes = Some(map);
|
||||
},
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -96,7 +93,7 @@ where
|
||||
operation.set_attributes(attributes.unwrap_or_default());
|
||||
}
|
||||
Ok(operation)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,7 +136,9 @@ where
|
||||
{
|
||||
type Value = Retain<T>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("struct Retain") }
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("struct Retain")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
@ -150,14 +149,14 @@ where
|
||||
Some(val) => val,
|
||||
None => {
|
||||
return Err(de::Error::invalid_length(0, &"struct Retain with 2 elements"));
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
let attributes = match serde::de::SeqAccess::next_element::<T>(&mut seq)? {
|
||||
Some(val) => val,
|
||||
None => {
|
||||
return Err(de::Error::invalid_length(1, &"struct Retain with 2 elements"));
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Retain::<T> { n: len, attributes })
|
||||
@ -177,13 +176,13 @@ where
|
||||
return Err(de::Error::duplicate_field("retain"));
|
||||
}
|
||||
len = Some(map.next_value()?);
|
||||
},
|
||||
}
|
||||
"attributes" => {
|
||||
if attributes.is_some() {
|
||||
return Err(de::Error::duplicate_field("attributes"));
|
||||
}
|
||||
attributes = Some(map.next_value()?);
|
||||
},
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -240,7 +239,9 @@ where
|
||||
{
|
||||
type Value = Insert<T>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("struct Insert") }
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("struct Insert")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
@ -251,14 +252,14 @@ where
|
||||
Some(val) => val,
|
||||
None => {
|
||||
return Err(de::Error::invalid_length(0, &"struct Insert with 2 elements"));
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
let attributes = match serde::de::SeqAccess::next_element::<T>(&mut seq)? {
|
||||
Some(val) => val,
|
||||
None => {
|
||||
return Err(de::Error::invalid_length(1, &"struct Retain with 2 elements"));
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Insert::<T> { s, attributes })
|
||||
@ -278,13 +279,13 @@ where
|
||||
return Err(de::Error::duplicate_field("insert"));
|
||||
}
|
||||
s = Some(map.next_value()?);
|
||||
},
|
||||
}
|
||||
"attributes" => {
|
||||
if attributes.is_some() {
|
||||
return Err(de::Error::duplicate_field("attributes"));
|
||||
}
|
||||
attributes = Some(map.next_value()?);
|
||||
},
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,9 @@ pub struct OTError {
|
||||
macro_rules! static_ot_error {
|
||||
($name:ident, $code:expr) => {
|
||||
#[allow(non_snake_case, missing_docs)]
|
||||
pub fn $name() -> OTError { $code.into() }
|
||||
pub fn $name() -> OTError {
|
||||
$code.into()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -41,15 +43,21 @@ impl OTError {
|
||||
}
|
||||
|
||||
impl fmt::Display for OTError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "incompatible lengths") }
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "incompatible lengths")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<serde_json::Error> for OTError {
|
||||
fn from(error: serde_json::Error) -> Self { ErrorBuilder::new(OTErrorCode::SerdeError).error(error).build() }
|
||||
fn from(error: serde_json::Error) -> Self {
|
||||
ErrorBuilder::new(OTErrorCode::SerdeError).error(error).build()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<Utf8Error> for OTError {
|
||||
fn from(error: Utf8Error) -> Self { ErrorBuilder::new(OTErrorCode::SerdeError).error(error).build() }
|
||||
fn from(error: Utf8Error) -> Self {
|
||||
ErrorBuilder::new(OTErrorCode::SerdeError).error(error).build()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -74,7 +82,9 @@ pub struct ErrorBuilder {
|
||||
}
|
||||
|
||||
impl ErrorBuilder {
|
||||
pub fn new(code: OTErrorCode) -> Self { ErrorBuilder { code, msg: None } }
|
||||
pub fn new(code: OTErrorCode) -> Self {
|
||||
ErrorBuilder { code, msg: None }
|
||||
}
|
||||
|
||||
pub fn msg<T>(mut self, msg: T) -> Self
|
||||
where
|
||||
@ -92,5 +102,7 @@ impl ErrorBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(mut self) -> OTError { OTError::new(self.code, &self.msg.take().unwrap_or_else(|| "".to_owned())) }
|
||||
pub fn build(mut self) -> OTError {
|
||||
OTError::new(self.code, &self.msg.take().unwrap_or_else(|| "".to_owned()))
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,7 @@ use crate::{
|
||||
block_attribute,
|
||||
core::{Attributes, OperationTransformable, RichTextOperation},
|
||||
errors::OTError,
|
||||
ignore_attribute,
|
||||
inline_attribute,
|
||||
list_attribute,
|
||||
ignore_attribute, inline_attribute, list_attribute,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use std::{
|
||||
@ -30,15 +28,23 @@ impl std::default::Default for RichTextAttributes {
|
||||
}
|
||||
|
||||
impl fmt::Display for RichTextAttributes {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_fmt(format_args!("{:?}", self.inner)) }
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_fmt(format_args!("{:?}", self.inner))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn plain_attributes() -> RichTextAttributes { RichTextAttributes::default() }
|
||||
pub fn plain_attributes() -> RichTextAttributes {
|
||||
RichTextAttributes::default()
|
||||
}
|
||||
|
||||
impl RichTextAttributes {
|
||||
pub fn new() -> Self { RichTextAttributes { inner: HashMap::new() } }
|
||||
pub fn new() -> Self {
|
||||
RichTextAttributes { inner: HashMap::new() }
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool { self.inner.is_empty() }
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.inner.is_empty()
|
||||
}
|
||||
|
||||
pub fn add(&mut self, attribute: RichTextAttribute) {
|
||||
let RichTextAttribute { key, value, scope: _ } = attribute;
|
||||
@ -57,18 +63,20 @@ impl RichTextAttributes {
|
||||
match attribute {
|
||||
None => {
|
||||
self.inner.iter_mut().for_each(|(_k, v)| v.0 = None);
|
||||
},
|
||||
}
|
||||
Some(attribute) => {
|
||||
self.inner.iter_mut().for_each(|(k, v)| {
|
||||
if k != &attribute {
|
||||
v.0 = None;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, key: RichTextAttributeKey) { self.inner.retain(|k, _| k != &key); }
|
||||
pub fn remove(&mut self, key: RichTextAttributeKey) {
|
||||
self.inner.retain(|k, _| k != &key);
|
||||
}
|
||||
|
||||
// pub fn block_attributes_except_header(attributes: &Attributes) -> Attributes
|
||||
// { let mut new_attributes = Attributes::new();
|
||||
@ -97,11 +105,17 @@ impl RichTextAttributes {
|
||||
}
|
||||
|
||||
impl Attributes for RichTextAttributes {
|
||||
fn is_empty(&self) -> bool { self.inner.is_empty() }
|
||||
fn is_empty(&self) -> bool {
|
||||
self.inner.is_empty()
|
||||
}
|
||||
|
||||
fn remove_empty(&mut self) { self.inner.retain(|_, v| v.0.is_some()); }
|
||||
fn remove_empty(&mut self) {
|
||||
self.inner.retain(|_, v| v.0.is_some());
|
||||
}
|
||||
|
||||
fn extend_other(&mut self, other: Self) { self.inner.extend(other.inner); }
|
||||
fn extend_other(&mut self, other: Self) {
|
||||
self.inner.extend(other.inner);
|
||||
}
|
||||
}
|
||||
|
||||
impl OperationTransformable for RichTextAttributes {
|
||||
@ -161,11 +175,15 @@ impl OperationTransformable for RichTextAttributes {
|
||||
impl std::ops::Deref for RichTextAttributes {
|
||||
type Target = HashMap<RichTextAttributeKey, RichTextAttributeValue>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.inner }
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for RichTextAttributes {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner }
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
|
||||
pub fn attributes_except_header(op: &RichTextOperation) -> RichTextAttributes {
|
||||
@ -218,7 +236,7 @@ impl RichTextAttribute {
|
||||
Err(e) => {
|
||||
log::error!("Attribute serialize to str failed: {}", e);
|
||||
"".to_owned()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -285,7 +303,9 @@ pub enum RichTextAttributeKey {
|
||||
pub struct RichTextAttributeValue(pub Option<String>);
|
||||
|
||||
impl std::convert::From<&usize> for RichTextAttributeValue {
|
||||
fn from(val: &usize) -> Self { RichTextAttributeValue::from(*val) }
|
||||
fn from(val: &usize) -> Self {
|
||||
RichTextAttributeValue::from(*val)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<usize> for RichTextAttributeValue {
|
||||
@ -299,7 +319,9 @@ impl std::convert::From<usize> for RichTextAttributeValue {
|
||||
}
|
||||
|
||||
impl std::convert::From<&str> for RichTextAttributeValue {
|
||||
fn from(val: &str) -> Self { val.to_owned().into() }
|
||||
fn from(val: &str) -> Self {
|
||||
val.to_owned().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<String> for RichTextAttributeValue {
|
||||
@ -313,7 +335,9 @@ impl std::convert::From<String> for RichTextAttributeValue {
|
||||
}
|
||||
|
||||
impl std::convert::From<&bool> for RichTextAttributeValue {
|
||||
fn from(val: &bool) -> Self { RichTextAttributeValue::from(*val) }
|
||||
fn from(val: &bool) -> Self {
|
||||
RichTextAttributeValue::from(*val)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<bool> for RichTextAttributeValue {
|
||||
|
@ -4,10 +4,7 @@ use serde::{
|
||||
de,
|
||||
de::{MapAccess, Visitor},
|
||||
ser::SerializeMap,
|
||||
Deserialize,
|
||||
Deserializer,
|
||||
Serialize,
|
||||
Serializer,
|
||||
Deserialize, Deserializer, Serialize, Serializer,
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
@ -77,7 +74,7 @@ where
|
||||
| RichTextAttributeKey::Align
|
||||
| RichTextAttributeKey::List => {
|
||||
map_serializer.serialize_entry(&key, v)?;
|
||||
},
|
||||
}
|
||||
}
|
||||
} else {
|
||||
map_serializer.serialize_entry(&key, "")?;
|
||||
@ -93,7 +90,9 @@ impl<'de> Deserialize<'de> for RichTextAttributes {
|
||||
struct AttributesVisitor;
|
||||
impl<'de> Visitor<'de> for AttributesVisitor {
|
||||
type Value = RichTextAttributes;
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("Expect map") }
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("Expect map")
|
||||
}
|
||||
|
||||
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(clippy::derivable_impls)]
|
||||
use crate::rich_text::{RichTextAttribute, RichTextAttributes};
|
||||
|
||||
pub struct AttributeBuilder {
|
||||
@ -14,12 +15,16 @@ impl std::default::Default for AttributeBuilder {
|
||||
}
|
||||
|
||||
impl AttributeBuilder {
|
||||
pub fn new() -> Self { AttributeBuilder::default() }
|
||||
pub fn new() -> Self {
|
||||
AttributeBuilder::default()
|
||||
}
|
||||
|
||||
pub fn add_attr(mut self, attribute: RichTextAttribute) -> Self {
|
||||
self.inner.add(attribute);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> RichTextAttributes { self.inner }
|
||||
pub fn build(self) -> RichTextAttributes {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user