acdc_parser/model/
metadata.rs1use serde::{Deserialize, Serialize};
4
5use super::anchor::Anchor;
6use super::attributes::{AttributeValue, ElementAttributes};
7
8pub type Role = String;
9
10#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
12#[non_exhaustive]
13pub struct BlockMetadata {
14 #[serde(default, skip_serializing_if = "ElementAttributes::is_empty")]
15 pub attributes: ElementAttributes,
16 #[serde(default, skip_serializing)]
17 pub positional_attributes: Vec<String>,
18 #[serde(default, skip_serializing_if = "Vec::is_empty")]
19 pub roles: Vec<Role>,
20 #[serde(default, skip_serializing_if = "Vec::is_empty")]
21 pub options: Vec<String>,
22 #[serde(default, skip_serializing_if = "Option::is_none")]
23 pub style: Option<String>,
24 #[serde(default, skip_serializing_if = "Option::is_none")]
25 pub id: Option<Anchor>,
26 #[serde(default, skip_serializing_if = "Vec::is_empty")]
27 pub anchors: Vec<Anchor>,
28}
29
30impl BlockMetadata {
31 #[must_use]
33 pub fn new() -> Self {
34 Self::default()
35 }
36
37 #[must_use]
39 pub fn with_attributes(mut self, attributes: ElementAttributes) -> Self {
40 self.attributes = attributes;
41 self
42 }
43
44 #[must_use]
46 pub fn with_options(mut self, options: Vec<String>) -> Self {
47 self.options = options;
48 self
49 }
50
51 #[must_use]
53 pub fn with_roles(mut self, roles: Vec<Role>) -> Self {
54 self.roles = roles;
55 self
56 }
57
58 #[must_use]
60 pub fn with_style(mut self, style: Option<String>) -> Self {
61 self.style = style;
62 self
63 }
64
65 #[must_use]
67 pub fn with_id(mut self, id: Option<Anchor>) -> Self {
68 self.id = id;
69 self
70 }
71
72 pub fn move_positional_attributes_to_attributes(&mut self) {
73 for positional_attribute in self.positional_attributes.drain(..) {
74 self.attributes
75 .insert(positional_attribute, AttributeValue::None);
76 }
77 }
78
79 pub fn set_attributes(&mut self, attributes: ElementAttributes) {
80 self.attributes = attributes;
81 }
82
83 #[must_use]
84 pub fn is_default(&self) -> bool {
85 self.roles.is_empty()
86 && self.options.is_empty()
87 && self.style.is_none()
88 && self.id.is_none()
89 && self.anchors.is_empty()
90 && self.attributes.is_empty()
91 && self.positional_attributes.is_empty()
92 }
93
94 #[tracing::instrument(level = "debug")]
95 pub fn merge(&mut self, other: &BlockMetadata) {
96 self.attributes.merge(other.attributes.clone());
97 self.positional_attributes
98 .extend(other.positional_attributes.clone());
99 self.roles.extend(other.roles.clone());
100 self.options.extend(other.options.clone());
101 if self.style.is_none() {
102 self.style.clone_from(&other.style);
103 }
104 if self.id.is_none() {
105 self.id.clone_from(&other.id);
106 }
107 self.anchors.extend(other.anchors.clone());
108 }
109}