1use super::{Attribute, Body, BodyBuilder, Structure};
4use crate::Identifier;
5use serde::{Deserialize, Serialize};
6use std::borrow::Cow;
7
8#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
19pub struct Block {
20 pub identifier: Identifier,
22 pub labels: Vec<BlockLabel>,
24 pub body: Body,
26}
27
28impl Block {
29 pub fn new<I>(ident: I) -> Block
31 where
32 I: Into<Identifier>,
33 {
34 Block {
35 identifier: ident.into(),
36 labels: Vec::new(),
37 body: Body::default(),
38 }
39 }
40
41 pub fn builder<I>(identifier: I) -> BlockBuilder
44 where
45 I: Into<Identifier>,
46 {
47 BlockBuilder::new(identifier)
48 }
49
50 pub fn identifier(&self) -> &str {
52 &self.identifier
53 }
54
55 pub fn labels(&self) -> &[BlockLabel] {
57 &self.labels
58 }
59
60 pub fn body(&self) -> &Body {
62 &self.body
63 }
64}
65
66impl<I, B> From<(I, B)> for Block
67where
68 I: Into<Identifier>,
69 B: IntoIterator,
70 B::Item: Into<Structure>,
71{
72 fn from((ident, body): (I, B)) -> Block {
73 Block {
74 identifier: ident.into(),
75 labels: Vec::new(),
76 body: body.into_iter().collect(),
77 }
78 }
79}
80
81impl<I, L, B> From<(I, L, B)> for Block
82where
83 I: Into<Identifier>,
84 L: IntoIterator,
85 L::Item: Into<BlockLabel>,
86 B: IntoIterator,
87 B::Item: Into<Structure>,
88{
89 fn from((ident, labels, body): (I, L, B)) -> Block {
90 Block {
91 identifier: ident.into(),
92 labels: labels.into_iter().map(Into::into).collect(),
93 body: body.into_iter().collect(),
94 }
95 }
96}
97
98#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
116pub enum BlockLabel {
117 Identifier(Identifier),
119 String(String),
121}
122
123impl BlockLabel {
124 pub fn into_inner(self) -> String {
129 match self {
130 BlockLabel::Identifier(ident) => ident.into_inner(),
131 BlockLabel::String(string) => string,
132 }
133 }
134
135 pub fn as_str(&self) -> &str {
137 match self {
138 BlockLabel::Identifier(ident) => ident.as_str(),
139 BlockLabel::String(string) => string.as_str(),
140 }
141 }
142}
143
144impl From<String> for BlockLabel {
145 fn from(s: String) -> BlockLabel {
146 BlockLabel::String(s)
147 }
148}
149
150impl From<&String> for BlockLabel {
151 fn from(s: &String) -> BlockLabel {
152 BlockLabel::String(s.clone())
153 }
154}
155
156impl From<&str> for BlockLabel {
157 fn from(s: &str) -> BlockLabel {
158 BlockLabel::String(s.to_string())
159 }
160}
161
162impl<'a> From<Cow<'a, str>> for BlockLabel {
163 fn from(s: Cow<'a, str>) -> BlockLabel {
164 BlockLabel::String(s.into_owned())
165 }
166}
167
168impl From<Identifier> for BlockLabel {
169 fn from(ident: Identifier) -> Self {
170 BlockLabel::Identifier(ident)
171 }
172}
173
174#[derive(Debug)]
197pub struct BlockBuilder {
198 identifier: Identifier,
199 labels: Vec<BlockLabel>,
200 body: BodyBuilder,
201}
202
203impl BlockBuilder {
204 pub fn new<I>(identifier: I) -> BlockBuilder
207 where
208 I: Into<Identifier>,
209 {
210 BlockBuilder {
211 identifier: identifier.into(),
212 labels: Vec::new(),
213 body: Body::builder(),
214 }
215 }
216
217 pub fn add_label<L>(mut self, label: L) -> BlockBuilder
221 where
222 L: Into<BlockLabel>,
223 {
224 self.labels.push(label.into());
225 self
226 }
227
228 pub fn add_labels<I>(mut self, iter: I) -> BlockBuilder
232 where
233 I: IntoIterator,
234 I::Item: Into<BlockLabel>,
235 {
236 self.labels.extend(iter.into_iter().map(Into::into));
237 self
238 }
239
240 pub fn add_attribute<A>(mut self, attr: A) -> BlockBuilder
244 where
245 A: Into<Attribute>,
246 {
247 self.body = self.body.add_attribute(attr);
248 self
249 }
250
251 pub fn add_attributes<I>(mut self, iter: I) -> BlockBuilder
255 where
256 I: IntoIterator,
257 I::Item: Into<Attribute>,
258 {
259 self.body = self.body.add_attributes(iter.into_iter().map(Into::into));
260 self
261 }
262
263 pub fn add_block<B>(mut self, block: B) -> BlockBuilder
267 where
268 B: Into<Block>,
269 {
270 self.body = self.body.add_block(block);
271 self
272 }
273
274 pub fn add_blocks<I>(mut self, iter: I) -> BlockBuilder
278 where
279 I: IntoIterator,
280 I::Item: Into<Block>,
281 {
282 self.body = self.body.add_blocks(iter.into_iter().map(Into::into));
283 self
284 }
285
286 pub fn add_structure<S>(mut self, structure: S) -> BlockBuilder
290 where
291 S: Into<Structure>,
292 {
293 self.body = self.body.add_structure(structure);
294 self
295 }
296
297 pub fn add_structures<I>(mut self, iter: I) -> BlockBuilder
301 where
302 I: IntoIterator,
303 I::Item: Into<Structure>,
304 {
305 self.body = self.body.add_structures(iter.into_iter().map(Into::into));
306 self
307 }
308
309 pub fn build(self) -> Block {
311 Block {
312 identifier: self.identifier,
313 labels: self.labels,
314 body: self.body.build(),
315 }
316 }
317}