use crate::{Element, Value};
use super::{Module, Segment, Visitor};
pub struct Sequential<E> {
stages: Vec<Box<dyn Module<E>>>,
}
impl<E: Element> Sequential<E> {
pub fn new() -> Self {
Self { stages: Vec::new() }
}
pub fn then(mut self, stage: impl Module<E> + 'static) -> Self {
self.stages.push(Box::new(stage));
self
}
pub fn len(&self) -> usize {
self.stages.len()
}
pub fn is_empty(&self) -> bool {
self.stages.is_empty()
}
}
impl<E: Element> Default for Sequential<E> {
fn default() -> Self {
Self::new()
}
}
impl<E: Element> Module<E> for Sequential<E> {
fn express<'tape>(&self, input: Value<'tape, E>) -> Value<'tape, E> {
self.stages
.iter()
.fold(input, |value, stage| stage.express(value))
}
fn visit(&self, visitor: &mut dyn Visitor) {
for (index, stage) in self.stages.iter().enumerate() {
visitor.enter(Segment::Index(index));
stage.visit(visitor);
visitor.leave();
}
}
}
#[cfg(test)]
#[path = "tests/sequential_tests.rs"]
mod tests;