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