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