attributes.rs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. use crate::core::{Attribute, AttributeKey, AttributeValue, Operation};
  2. use std::{collections::HashMap, fmt};
  3. pub const REMOVE_FLAG: &'static str = "";
  4. pub(crate) fn should_remove(val: &AttributeValue) -> bool { val.0 == REMOVE_FLAG }
  5. #[derive(Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize)]
  6. pub struct Attributes {
  7. #[serde(skip_serializing_if = "HashMap::is_empty")]
  8. #[serde(flatten)]
  9. pub(crate) inner: HashMap<AttributeKey, AttributeValue>,
  10. }
  11. impl fmt::Display for Attributes {
  12. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  13. f.write_fmt(format_args!("{:?}", self.inner))
  14. }
  15. }
  16. impl Attributes {
  17. pub fn new() -> Self {
  18. Attributes {
  19. inner: HashMap::new(),
  20. }
  21. }
  22. pub fn empty() -> Self { Self::default() }
  23. pub fn is_empty(&self) -> bool { self.inner.is_empty() }
  24. pub fn add(&mut self, attribute: Attribute) {
  25. let Attribute {
  26. key,
  27. value,
  28. scope: _,
  29. } = attribute;
  30. self.inner.insert(key, value);
  31. }
  32. pub fn mark_as_removed(&mut self, key: &AttributeKey) {
  33. let value: AttributeValue = REMOVE_FLAG.into();
  34. self.inner.insert(key.clone(), value);
  35. }
  36. pub fn mark_all_as_removed_except(&mut self, attribute: Option<AttributeKey>) {
  37. match attribute {
  38. None => {
  39. self.inner
  40. .iter_mut()
  41. .for_each(|(k, v)| v.0 = REMOVE_FLAG.into());
  42. },
  43. Some(attribute) => {
  44. self.inner.iter_mut().for_each(|(k, v)| {
  45. if k != &attribute {
  46. v.0 = REMOVE_FLAG.into();
  47. }
  48. });
  49. },
  50. }
  51. }
  52. pub fn remove(&mut self, key: AttributeKey) { self.inner.retain(|k, _| k != &key); }
  53. // pub fn block_attributes_except_header(attributes: &Attributes) -> Attributes
  54. // { let mut new_attributes = Attributes::new();
  55. // attributes.iter().for_each(|(k, v)| {
  56. // if k != &AttributeKey::Header {
  57. // new_attributes.insert(k.clone(), v.clone());
  58. // }
  59. // });
  60. //
  61. // new_attributes
  62. // }
  63. // Remove the empty attribute which value is empty. e.g. {bold: ""}.
  64. pub fn remove_empty(&mut self) { self.inner.retain(|_, v| !should_remove(v)); }
  65. pub fn extend(&mut self, other: Attributes) { self.inner.extend(other.inner); }
  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<Attributes>) {
  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 std::ops::Deref for Attributes {
  80. type Target = HashMap<AttributeKey, AttributeValue>;
  81. fn deref(&self) -> &Self::Target { &self.inner }
  82. }
  83. impl std::ops::DerefMut for Attributes {
  84. fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner }
  85. }
  86. pub(crate) fn attributes_from(operation: &Option<Operation>) -> Option<Attributes> {
  87. match operation {
  88. None => None,
  89. Some(operation) => Some(operation.get_attributes()),
  90. }
  91. }
  92. pub fn compose_operation(left: &Option<Operation>, right: &Option<Operation>) -> Attributes {
  93. if left.is_none() && right.is_none() {
  94. return Attributes::default();
  95. }
  96. let attr_left = attributes_from(left);
  97. let attr_right = attributes_from(right);
  98. if attr_left.is_none() {
  99. return attr_right.unwrap();
  100. }
  101. if attr_right.is_none() {
  102. return attr_left.unwrap();
  103. }
  104. let left = attr_left.unwrap();
  105. let right = attr_right.unwrap();
  106. log::trace!("compose attributes: a: {:?}, b: {:?}", left, right);
  107. let attr = merge_attributes(left, right);
  108. log::trace!("compose attributes result: {:?}", attr);
  109. attr
  110. }
  111. pub fn compose_attributes(left: Attributes, right: Attributes) -> Attributes {
  112. log::trace!("compose attributes: a: {:?}, b: {:?}", left, right);
  113. let attr = merge_attributes(left, right);
  114. log::trace!("compose attributes result: {:?}", attr);
  115. attr
  116. }
  117. pub fn transform_operation(left: &Option<Operation>, right: &Option<Operation>) -> Attributes {
  118. let attr_l = attributes_from(left);
  119. let attr_r = attributes_from(right);
  120. if attr_l.is_none() {
  121. if attr_r.is_none() {
  122. return Attributes::default();
  123. }
  124. return attr_r.unwrap();
  125. }
  126. let left = attr_l.unwrap();
  127. let right = attr_r.unwrap();
  128. left.iter()
  129. .fold(Attributes::new(), |mut new_attributes, (k, v)| {
  130. if !right.contains_key(k) {
  131. new_attributes.insert(k.clone(), v.clone());
  132. }
  133. new_attributes
  134. })
  135. }
  136. pub fn invert_attributes(attr: Attributes, base: Attributes) -> Attributes {
  137. let base_inverted = base
  138. .iter()
  139. .fold(Attributes::new(), |mut attributes, (k, v)| {
  140. if base.get(k) != attr.get(k) && attr.contains_key(k) {
  141. attributes.insert(k.clone(), v.clone());
  142. }
  143. attributes
  144. });
  145. let inverted = attr.iter().fold(base_inverted, |mut attributes, (k, _)| {
  146. if base.get(k) != attr.get(k) && !base.contains_key(k) {
  147. attributes.mark_as_removed(k);
  148. }
  149. attributes
  150. });
  151. return inverted;
  152. }
  153. pub fn merge_attributes(mut attributes: Attributes, other: Attributes) -> Attributes {
  154. attributes.extend(other);
  155. attributes
  156. }
  157. pub fn attributes_except_header(op: &Operation) -> Attributes {
  158. let mut attributes = op.get_attributes();
  159. attributes.remove(AttributeKey::Header);
  160. attributes
  161. }