attributes.rs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. use crate::core::Operation;
  2. use std::{collections::HashMap, fmt};
  3. const PLAIN: &'static str = "";
  4. fn is_plain(s: &str) -> bool { s == PLAIN }
  5. #[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
  6. #[serde(untagged)]
  7. pub enum Attributes {
  8. #[serde(skip)]
  9. Follow,
  10. Custom(AttributesData),
  11. #[serde(skip)]
  12. Empty,
  13. }
  14. impl Attributes {
  15. pub fn extend(&self, other: Option<Attributes>) -> Attributes {
  16. log::debug!("Attribute extend: {:?} with {:?}", self, other);
  17. let other = other.unwrap_or(Attributes::Empty);
  18. let result = match (self, &other) {
  19. (Attributes::Custom(data), Attributes::Custom(o_data)) => {
  20. if !data.is_plain() {
  21. let mut data = data.clone();
  22. data.extend(o_data.clone());
  23. Attributes::Custom(data)
  24. } else {
  25. Attributes::Custom(data.clone())
  26. }
  27. },
  28. (Attributes::Custom(data), _) => Attributes::Custom(data.clone()),
  29. // (Attributes::Empty, _) => Attributes::Empty,
  30. _ => other,
  31. };
  32. log::debug!("result {:?}", result);
  33. result
  34. }
  35. // remove attribute if the value is PLAIN
  36. // { "k": PLAIN } -> {}
  37. pub fn remove_plain(&mut self) {
  38. match self {
  39. Attributes::Follow => {},
  40. Attributes::Custom(data) => {
  41. data.remove_plain();
  42. },
  43. Attributes::Empty => {},
  44. }
  45. }
  46. pub fn get_attributes_data(&self) -> Option<AttributesData> {
  47. match self {
  48. Attributes::Follow => None,
  49. Attributes::Custom(data) => Some(data.clone()),
  50. Attributes::Empty => None,
  51. }
  52. }
  53. }
  54. impl std::default::Default for Attributes {
  55. fn default() -> Self { Attributes::Empty }
  56. }
  57. impl fmt::Display for Attributes {
  58. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  59. match self {
  60. Attributes::Follow => {
  61. f.write_str("")?;
  62. },
  63. Attributes::Custom(data) => {
  64. f.write_fmt(format_args!("{:?}", data.inner))?;
  65. },
  66. Attributes::Empty => {
  67. f.write_str("")?;
  68. },
  69. }
  70. Ok(())
  71. }
  72. }
  73. #[derive(Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize)]
  74. pub struct AttributesData {
  75. #[serde(skip_serializing_if = "HashMap::is_empty")]
  76. #[serde(flatten)]
  77. inner: HashMap<String, String>,
  78. }
  79. impl AttributesData {
  80. pub fn new() -> Self {
  81. AttributesData {
  82. inner: HashMap::new(),
  83. }
  84. }
  85. pub fn remove_plain(&mut self) { self.inner.retain(|_, v| !is_plain(v)); }
  86. pub fn extend(&mut self, other: AttributesData) { self.inner.extend(other.inner); }
  87. pub fn is_plain(&self) -> bool { self.inner.values().filter(|v| !is_plain(v)).count() == 0 }
  88. }
  89. impl std::convert::From<HashMap<String, String>> for AttributesData {
  90. fn from(attributes: HashMap<String, String>) -> Self { AttributesData { inner: attributes } }
  91. }
  92. impl std::ops::Deref for AttributesData {
  93. type Target = HashMap<String, String>;
  94. fn deref(&self) -> &Self::Target { &self.inner }
  95. }
  96. impl std::ops::DerefMut for AttributesData {
  97. fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner }
  98. }
  99. pub struct AttrsBuilder {
  100. inner: AttributesData,
  101. }
  102. impl AttrsBuilder {
  103. pub fn new() -> Self {
  104. Self {
  105. inner: AttributesData::default(),
  106. }
  107. }
  108. pub fn bold(mut self, bold: bool) -> Self {
  109. let val = match bold {
  110. true => "true",
  111. false => PLAIN,
  112. };
  113. self.inner.insert("bold".to_owned(), val.to_owned());
  114. self
  115. }
  116. pub fn italic(mut self, italic: bool) -> Self {
  117. let val = match italic {
  118. true => "true",
  119. false => PLAIN,
  120. };
  121. self.inner.insert("italic".to_owned(), val.to_owned());
  122. self
  123. }
  124. pub fn underline(mut self) -> Self {
  125. self.inner.insert("underline".to_owned(), "true".to_owned());
  126. self
  127. }
  128. pub fn build(self) -> Attributes { Attributes::Custom(self.inner) }
  129. }
  130. pub(crate) fn attributes_from(operation: &Option<Operation>) -> Option<Attributes> {
  131. match operation {
  132. None => None,
  133. Some(operation) => Some(operation.get_attributes()),
  134. }
  135. }
  136. pub fn compose_attributes(left: &Option<Operation>, right: &Option<Operation>) -> Attributes {
  137. if left.is_none() && right.is_none() {
  138. return Attributes::Empty;
  139. }
  140. let attr_l = attributes_from(left);
  141. let attr_r = attributes_from(right);
  142. log::trace!("compose_attributes: a: {:?}, b: {:?}", attr_l, attr_r);
  143. let mut attr = match (&attr_l, &attr_r) {
  144. (_, Some(Attributes::Custom(_))) => match attr_l {
  145. None => attr_r.unwrap(),
  146. Some(_) => attr_l.unwrap().extend(attr_r.clone()),
  147. // Some(attr_l) => merge_attributes(attr_l, attr_r),
  148. },
  149. (Some(Attributes::Custom(_)), _) => attr_l.unwrap().extend(attr_r),
  150. // (Some(Attributes::Custom(_)), _) => merge_attributes(attr_l.unwrap(), attr_r),
  151. (Some(Attributes::Follow), Some(Attributes::Follow)) => Attributes::Follow,
  152. _ => Attributes::Empty,
  153. };
  154. log::trace!("composed_attributes: a: {:?}", attr);
  155. match &mut attr {
  156. Attributes::Custom(data) => {
  157. data.remove_plain();
  158. match data.is_plain() {
  159. true => Attributes::Empty,
  160. false => attr,
  161. }
  162. },
  163. _ => attr,
  164. }
  165. }
  166. pub fn transform_attributes(
  167. left: &Option<Operation>,
  168. right: &Option<Operation>,
  169. priority: bool,
  170. ) -> Attributes {
  171. let attr_l = attributes_from(left);
  172. let attr_r = attributes_from(right);
  173. if attr_l.is_none() {
  174. if attr_r.is_none() {
  175. return Attributes::Empty;
  176. }
  177. return match attr_r.as_ref().unwrap() {
  178. Attributes::Follow => Attributes::Follow,
  179. Attributes::Custom(_) => attr_r.unwrap(),
  180. Attributes::Empty => Attributes::Empty,
  181. };
  182. }
  183. if !priority {
  184. return attr_r.unwrap();
  185. }
  186. match (attr_l.unwrap(), attr_r.unwrap()) {
  187. (Attributes::Custom(attr_data_l), Attributes::Custom(attr_data_r)) => {
  188. let result = transform_attribute_data(attr_data_l, attr_data_r);
  189. Attributes::Custom(result)
  190. },
  191. _ => Attributes::Empty,
  192. }
  193. }
  194. pub fn invert_attributes(attr: Attributes, base: Attributes) -> Attributes {
  195. let attr = attr.get_attributes_data();
  196. let base = base.get_attributes_data();
  197. if attr.is_none() && base.is_none() {
  198. return Attributes::Empty;
  199. }
  200. let attr = attr.unwrap_or(AttributesData::new());
  201. let base = base.unwrap_or(AttributesData::new());
  202. let base_inverted = base
  203. .iter()
  204. .fold(AttributesData::new(), |mut attributes, (k, v)| {
  205. if base.get(k) != attr.get(k) && attr.contains_key(k) {
  206. attributes.insert(k.clone(), v.clone());
  207. }
  208. attributes
  209. });
  210. let inverted = attr.iter().fold(base_inverted, |mut attributes, (k, _)| {
  211. if base.get(k) != attr.get(k) && !base.contains_key(k) {
  212. // attributes.insert(k.clone(), "".to_owned());
  213. attributes.remove(k);
  214. }
  215. attributes
  216. });
  217. return Attributes::Custom(inverted);
  218. }
  219. fn transform_attribute_data(left: AttributesData, right: AttributesData) -> AttributesData {
  220. let result = right
  221. .iter()
  222. .fold(AttributesData::new(), |mut new_attr_data, (k, v)| {
  223. if !left.contains_key(k) {
  224. new_attr_data.insert(k.clone(), v.clone());
  225. }
  226. new_attr_data
  227. });
  228. result
  229. }
  230. pub fn merge_attributes(attributes: Attributes, other: Option<Attributes>) -> Attributes {
  231. let other = other.unwrap_or(Attributes::Empty);
  232. match (&attributes, &other) {
  233. (Attributes::Custom(data), Attributes::Custom(o_data)) => {
  234. let mut data = data.clone();
  235. data.extend(o_data.clone());
  236. Attributes::Custom(data)
  237. },
  238. (Attributes::Custom(data), _) => Attributes::Custom(data.clone()),
  239. _ => other,
  240. }
  241. }