attributes.rs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. use crate::core::{Attribute, AttributesData, AttributesRule, Operation};
  2. use std::{collections::HashMap, fmt};
  3. #[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
  4. #[serde(untagged)]
  5. pub enum Attributes {
  6. #[serde(skip)]
  7. Follow,
  8. Custom(AttributesData),
  9. #[serde(skip)]
  10. Empty,
  11. }
  12. impl Attributes {
  13. pub fn data(&self) -> Option<AttributesData> {
  14. match self {
  15. Attributes::Follow => None,
  16. Attributes::Custom(data) => Some(data.clone()),
  17. Attributes::Empty => None,
  18. }
  19. }
  20. pub fn is_empty(&self) -> bool {
  21. match self {
  22. Attributes::Follow => true,
  23. Attributes::Custom(data) => data.is_empty(),
  24. Attributes::Empty => true,
  25. }
  26. }
  27. }
  28. impl std::default::Default for Attributes {
  29. fn default() -> Self { Attributes::Empty }
  30. }
  31. impl fmt::Display for Attributes {
  32. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  33. match self {
  34. Attributes::Follow => {
  35. f.write_str("")?;
  36. },
  37. Attributes::Custom(data) => {
  38. f.write_fmt(format_args!("{:?}", data.inner))?;
  39. },
  40. Attributes::Empty => {
  41. f.write_str("")?;
  42. },
  43. }
  44. Ok(())
  45. }
  46. }
  47. pub(crate) fn attributes_from(operation: &Option<Operation>) -> Option<Attributes> {
  48. match operation {
  49. None => None,
  50. Some(operation) => Some(operation.get_attributes()),
  51. }
  52. }
  53. pub fn compose_operation(left: &Option<Operation>, right: &Option<Operation>) -> Attributes {
  54. if left.is_none() && right.is_none() {
  55. return Attributes::Empty;
  56. }
  57. let attr_l = attributes_from(left);
  58. let attr_r = attributes_from(right);
  59. if attr_l.is_none() {
  60. return attr_r.unwrap();
  61. }
  62. if attr_r.is_none() {
  63. return attr_l.unwrap();
  64. }
  65. compose_attributes(attr_l.unwrap(), attr_r.unwrap())
  66. }
  67. pub fn transform_operation(left: &Option<Operation>, right: &Option<Operation>) -> Attributes {
  68. let attr_l = attributes_from(left);
  69. let attr_r = attributes_from(right);
  70. if attr_l.is_none() {
  71. if attr_r.is_none() {
  72. return Attributes::Empty;
  73. }
  74. return match attr_r.as_ref().unwrap() {
  75. Attributes::Follow => Attributes::Follow,
  76. Attributes::Custom(_) => attr_r.unwrap(),
  77. Attributes::Empty => Attributes::Empty,
  78. };
  79. }
  80. transform_attributes(attr_l.unwrap(), attr_r.unwrap())
  81. }
  82. pub fn invert_attributes(attr: Attributes, base: Attributes) -> Attributes {
  83. log::info!("Invert attributes: {:?} : {:?}", attr, base);
  84. let attr = attr.data();
  85. let base = base.data();
  86. if attr.is_none() && base.is_none() {
  87. return Attributes::Empty;
  88. }
  89. let attr = attr.unwrap_or(AttributesData::new());
  90. let base = base.unwrap_or(AttributesData::new());
  91. let base_inverted = base
  92. .iter()
  93. .fold(AttributesData::new(), |mut attributes, (k, v)| {
  94. if base.get(k) != attr.get(k) && attr.contains_key(k) {
  95. attributes.insert(k.clone(), v.clone());
  96. }
  97. attributes
  98. });
  99. let inverted = attr.iter().fold(base_inverted, |mut attributes, (k, _)| {
  100. if base.get(k) != attr.get(k) && !base.contains_key(k) {
  101. attributes.remove(k);
  102. }
  103. attributes
  104. });
  105. return Attributes::Custom(inverted);
  106. }
  107. pub fn merge_attributes(attributes: Attributes, other: Attributes) -> Attributes {
  108. match (&attributes, &other) {
  109. (Attributes::Custom(data), Attributes::Custom(o_data)) => {
  110. let mut data = data.clone();
  111. data.extend(Some(o_data.clone()), false);
  112. Attributes::Custom(data)
  113. },
  114. (Attributes::Custom(data), _) => Attributes::Custom(data.clone()),
  115. _ => other,
  116. }
  117. }
  118. fn compose_attributes(left: Attributes, right: Attributes) -> Attributes {
  119. log::trace!("compose_attributes: a: {:?}, b: {:?}", left, right);
  120. let attr = match (&left, &right) {
  121. (_, Attributes::Empty) => Attributes::Empty,
  122. (_, Attributes::Custom(_)) => merge_attributes(left, right),
  123. (Attributes::Custom(_), _) => merge_attributes(left, right),
  124. _ => Attributes::Follow,
  125. };
  126. log::trace!("composed_attributes: a: {:?}", attr);
  127. attr.apply_rule()
  128. }
  129. fn transform_attributes(left: Attributes, right: Attributes) -> Attributes {
  130. match (left, right) {
  131. (Attributes::Custom(data_l), Attributes::Custom(data_r)) => {
  132. let result = data_r
  133. .iter()
  134. .fold(AttributesData::new(), |mut new_attr_data, (k, v)| {
  135. if !data_l.contains_key(k) {
  136. new_attr_data.insert(k.clone(), v.clone());
  137. }
  138. new_attr_data
  139. });
  140. Attributes::Custom(result)
  141. },
  142. _ => Attributes::Empty,
  143. }
  144. }