use crate::{
error::{parse::validate::ValidationError, utils::MetaData},
knot::Address,
line::LineChunk,
story::validate::{ValidateContent, ValidationData},
};
#[cfg(feature = "serde_support")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde_support", derive(Deserialize, Serialize))]
pub struct Alternative {
pub current_index: Option<usize>,
pub kind: AlternativeKind,
pub items: Vec<LineChunk>,
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde_support", derive(Deserialize, Serialize))]
pub enum AlternativeKind {
Cycle,
OnceOnly,
Sequence,
}
impl ValidateContent for Alternative {
fn validate(
&mut self,
error: &mut ValidationError,
current_location: &Address,
meta_data: &MetaData,
data: &ValidationData,
) {
self.items
.iter_mut()
.for_each(|item| item.validate(error, current_location, meta_data, data));
}
}
pub struct AlternativeBuilder {
kind: AlternativeKind,
items: Vec<LineChunk>,
}
impl AlternativeBuilder {
pub fn from_kind(kind: AlternativeKind) -> Self {
AlternativeBuilder {
kind,
items: Vec::new(),
}
}
pub fn build(self) -> Alternative {
Alternative {
current_index: None,
kind: self.kind,
items: self.items,
}
}
pub fn with_items(mut self, items: Vec<LineChunk>) -> Self {
self.items = items;
self
}
#[cfg(test)]
pub fn cycle() -> Self {
AlternativeBuilder::from_kind(AlternativeKind::Cycle)
}
#[cfg(test)]
pub fn once_only() -> Self {
AlternativeBuilder::from_kind(AlternativeKind::OnceOnly)
}
#[cfg(test)]
pub fn sequence() -> Self {
AlternativeBuilder::from_kind(AlternativeKind::Sequence)
}
#[cfg(test)]
pub fn add_line(&mut self, line: LineChunk) {
self.items.push(line);
}
#[cfg(test)]
pub fn with_line(mut self, line: LineChunk) -> Self {
self.add_line(line);
self
}
}