attributes.rs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. use crate::{
  2. core::{
  3. Attributes,
  4. OperationTransformable,
  5. RichTextAttribute,
  6. RichTextAttributeKey,
  7. RichTextAttributeValue,
  8. RichTextOperation,
  9. },
  10. errors::OTError,
  11. };
  12. use std::{collections::HashMap, fmt};
  13. #[derive(Debug, Clone, Eq, PartialEq)]
  14. pub struct RichTextAttributes {
  15. pub(crate) inner: HashMap<RichTextAttributeKey, RichTextAttributeValue>,
  16. }
  17. impl std::default::Default for RichTextAttributes {
  18. fn default() -> Self {
  19. Self {
  20. inner: HashMap::with_capacity(0),
  21. }
  22. }
  23. }
  24. impl fmt::Display for RichTextAttributes {
  25. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_fmt(format_args!("{:?}", self.inner)) }
  26. }
  27. pub fn plain_attributes() -> RichTextAttributes { RichTextAttributes::default() }
  28. impl RichTextAttributes {
  29. pub fn new() -> Self { RichTextAttributes { inner: HashMap::new() } }
  30. pub fn is_empty(&self) -> bool { self.inner.is_empty() }
  31. pub fn add(&mut self, attribute: RichTextAttribute) {
  32. let RichTextAttribute { key, value, scope: _ } = attribute;
  33. self.inner.insert(key, value);
  34. }
  35. pub fn add_kv(&mut self, key: RichTextAttributeKey, value: RichTextAttributeValue) {
  36. self.inner.insert(key, value);
  37. }
  38. pub fn delete(&mut self, key: &RichTextAttributeKey) {
  39. self.inner.insert(key.clone(), RichTextAttributeValue(None));
  40. }
  41. pub fn mark_all_as_removed_except(&mut self, attribute: Option<RichTextAttributeKey>) {
  42. match attribute {
  43. None => {
  44. self.inner.iter_mut().for_each(|(_k, v)| v.0 = None);
  45. },
  46. Some(attribute) => {
  47. self.inner.iter_mut().for_each(|(k, v)| {
  48. if k != &attribute {
  49. v.0 = None;
  50. }
  51. });
  52. },
  53. }
  54. }
  55. pub fn remove(&mut self, key: RichTextAttributeKey) { self.inner.retain(|k, _| k != &key); }
  56. // pub fn block_attributes_except_header(attributes: &Attributes) -> Attributes
  57. // { let mut new_attributes = Attributes::new();
  58. // attributes.iter().for_each(|(k, v)| {
  59. // if k != &AttributeKey::Header {
  60. // new_attributes.insert(k.clone(), v.clone());
  61. // }
  62. // });
  63. //
  64. // new_attributes
  65. // }
  66. // Update inner by constructing new attributes from the other if it's
  67. // not None and replace the key/value with self key/value.
  68. pub fn merge(&mut self, other: Option<RichTextAttributes>) {
  69. if other.is_none() {
  70. return;
  71. }
  72. let mut new_attributes = other.unwrap().inner;
  73. self.inner.iter().for_each(|(k, v)| {
  74. new_attributes.insert(k.clone(), v.clone());
  75. });
  76. self.inner = new_attributes;
  77. }
  78. }
  79. impl Attributes for RichTextAttributes {
  80. fn is_empty(&self) -> bool { self.inner.is_empty() }
  81. fn remove_empty(&mut self) { self.inner.retain(|_, v| v.0.is_some()); }
  82. fn extend_other(&mut self, other: Self) { self.inner.extend(other.inner); }
  83. }
  84. impl OperationTransformable for RichTextAttributes {
  85. fn compose(&self, other: &Self) -> Result<Self, OTError>
  86. where
  87. Self: Sized,
  88. {
  89. let mut attributes = self.clone();
  90. attributes.extend_other(other.clone());
  91. Ok(attributes)
  92. }
  93. fn transform(&self, other: &Self) -> Result<(Self, Self), OTError>
  94. where
  95. Self: Sized,
  96. {
  97. let a = self
  98. .iter()
  99. .fold(RichTextAttributes::new(), |mut new_attributes, (k, v)| {
  100. if !other.contains_key(k) {
  101. new_attributes.insert(k.clone(), v.clone());
  102. }
  103. new_attributes
  104. });
  105. let b = other
  106. .iter()
  107. .fold(RichTextAttributes::new(), |mut new_attributes, (k, v)| {
  108. if !self.contains_key(k) {
  109. new_attributes.insert(k.clone(), v.clone());
  110. }
  111. new_attributes
  112. });
  113. Ok((a, b))
  114. }
  115. fn invert(&self, other: &Self) -> Self {
  116. let base_inverted = other.iter().fold(RichTextAttributes::new(), |mut attributes, (k, v)| {
  117. if other.get(k) != self.get(k) && self.contains_key(k) {
  118. attributes.insert(k.clone(), v.clone());
  119. }
  120. attributes
  121. });
  122. let inverted = self.iter().fold(base_inverted, |mut attributes, (k, _)| {
  123. if other.get(k) != self.get(k) && !other.contains_key(k) {
  124. attributes.delete(k);
  125. }
  126. attributes
  127. });
  128. inverted
  129. }
  130. }
  131. impl std::ops::Deref for RichTextAttributes {
  132. type Target = HashMap<RichTextAttributeKey, RichTextAttributeValue>;
  133. fn deref(&self) -> &Self::Target { &self.inner }
  134. }
  135. impl std::ops::DerefMut for RichTextAttributes {
  136. fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner }
  137. }
  138. pub fn attributes_except_header(op: &RichTextOperation) -> RichTextAttributes {
  139. let mut attributes = op.get_attributes();
  140. attributes.remove(RichTextAttributeKey::Header);
  141. attributes
  142. }