use super::{Attribute, Body, BodyBuilder, Structure};
use crate::Identifier;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Block {
pub identifier: Identifier,
pub labels: Vec<BlockLabel>,
pub body: Body,
}
impl Block {
pub fn new<I>(ident: I) -> Block
where
I: Into<Identifier>,
{
Block {
identifier: ident.into(),
labels: Vec::new(),
body: Body::default(),
}
}
pub fn builder<I>(identifier: I) -> BlockBuilder
where
I: Into<Identifier>,
{
BlockBuilder::new(identifier)
}
pub fn identifier(&self) -> &str {
&self.identifier
}
pub fn labels(&self) -> &[BlockLabel] {
&self.labels
}
pub fn body(&self) -> &Body {
&self.body
}
}
impl<I, B> From<(I, B)> for Block
where
I: Into<Identifier>,
B: IntoIterator,
B::Item: Into<Structure>,
{
fn from((ident, body): (I, B)) -> Block {
Block {
identifier: ident.into(),
labels: Vec::new(),
body: body.into_iter().collect(),
}
}
}
impl<I, L, B> From<(I, L, B)> for Block
where
I: Into<Identifier>,
L: IntoIterator,
L::Item: Into<BlockLabel>,
B: IntoIterator,
B::Item: Into<Structure>,
{
fn from((ident, labels, body): (I, L, B)) -> Block {
Block {
identifier: ident.into(),
labels: labels.into_iter().map(Into::into).collect(),
body: body.into_iter().collect(),
}
}
}
#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)]
pub enum BlockLabel {
Identifier(Identifier),
String(String),
}
impl BlockLabel {
pub fn into_inner(self) -> String {
match self {
BlockLabel::Identifier(ident) => ident.into_inner(),
BlockLabel::String(string) => string,
}
}
pub fn as_str(&self) -> &str {
match self {
BlockLabel::Identifier(ident) => ident.as_str(),
BlockLabel::String(string) => string.as_str(),
}
}
}
impl From<String> for BlockLabel {
fn from(s: String) -> BlockLabel {
BlockLabel::String(s)
}
}
impl From<&String> for BlockLabel {
fn from(s: &String) -> BlockLabel {
BlockLabel::String(s.clone())
}
}
impl From<&str> for BlockLabel {
fn from(s: &str) -> BlockLabel {
BlockLabel::String(s.to_string())
}
}
impl<'a> From<Cow<'a, str>> for BlockLabel {
fn from(s: Cow<'a, str>) -> BlockLabel {
BlockLabel::String(s.into_owned())
}
}
impl From<Identifier> for BlockLabel {
fn from(ident: Identifier) -> Self {
BlockLabel::Identifier(ident)
}
}
#[derive(Debug)]
pub struct BlockBuilder {
identifier: Identifier,
labels: Vec<BlockLabel>,
body: BodyBuilder,
}
impl BlockBuilder {
pub fn new<I>(identifier: I) -> BlockBuilder
where
I: Into<Identifier>,
{
BlockBuilder {
identifier: identifier.into(),
labels: Vec::new(),
body: Body::builder(),
}
}
pub fn add_label<L>(mut self, label: L) -> BlockBuilder
where
L: Into<BlockLabel>,
{
self.labels.push(label.into());
self
}
pub fn add_labels<I>(mut self, iter: I) -> BlockBuilder
where
I: IntoIterator,
I::Item: Into<BlockLabel>,
{
self.labels.extend(iter.into_iter().map(Into::into));
self
}
pub fn add_attribute<A>(mut self, attr: A) -> BlockBuilder
where
A: Into<Attribute>,
{
self.body = self.body.add_attribute(attr);
self
}
pub fn add_attributes<I>(mut self, iter: I) -> BlockBuilder
where
I: IntoIterator,
I::Item: Into<Attribute>,
{
self.body = self.body.add_attributes(iter.into_iter().map(Into::into));
self
}
pub fn add_block<B>(mut self, block: B) -> BlockBuilder
where
B: Into<Block>,
{
self.body = self.body.add_block(block);
self
}
pub fn add_blocks<I>(mut self, iter: I) -> BlockBuilder
where
I: IntoIterator,
I::Item: Into<Block>,
{
self.body = self.body.add_blocks(iter.into_iter().map(Into::into));
self
}
pub fn add_structure<S>(mut self, structure: S) -> BlockBuilder
where
S: Into<Structure>,
{
self.body = self.body.add_structure(structure);
self
}
pub fn add_structures<I>(mut self, iter: I) -> BlockBuilder
where
I: IntoIterator,
I::Item: Into<Structure>,
{
self.body = self.body.add_structures(iter.into_iter().map(Into::into));
self
}
pub fn build(self) -> Block {
Block {
identifier: self.identifier,
labels: self.labels,
body: self.body.build(),
}
}
}