pub mod stage1;
pub mod stage2;
use std::any::Any;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use crate::error::ErrorSection;
use crate::exit;
#[derive(Debug)]
pub struct AlpacaPipelineInfo {
data: HashMap<&'static str, Box<dyn Any>>,
}
impl AlpacaPipelineInfo {
pub fn new() -> Self {
Self { data: HashMap::new() }
}
pub fn add_data<T: 'static>(&mut self, key: &'static str, value: T) {
if self.data.contains_key(key) {
log::error!("key already exists!");
exit!(ErrorSection::Pipeline, 13474);
}
self.data.insert(key, Box::new(value));
}
pub fn get_data_ref<T: 'static>(&self, key: &'static str) -> Option<&T> {
self.data.get(key)?.downcast_ref::<T>()
}
pub fn get_data_mut<T: 'static>(&mut self, key: &'static str) -> Option<&mut T> {
self.data.get_mut(key)?.downcast_mut::<T>()
}
pub fn remove_data(&mut self, key: &str) { self.data.remove(key); }
}
pub trait CriaPipelineModule {
fn build(&self, pipeline: &mut AlpacaPipeline);
}
pub struct AlpacaPipeline {
info: Rc<RefCell<AlpacaPipelineInfo>>,
passes: Vec<Box<dyn Fn(Rc<RefCell<AlpacaPipelineInfo>>) -> u32>>,
}
impl Default for AlpacaPipeline {
fn default() -> Self {
env_logger::init();
Self { info: Rc::new(RefCell::new(AlpacaPipelineInfo::new())), passes: Vec::new() }
}
}
impl AlpacaPipeline {
pub fn add_pass<F>(&mut self, pass: F) -> &mut Self
where
F: Fn(Rc<RefCell<AlpacaPipelineInfo>>) -> u32 + 'static,
{
self.passes.push(Box::new(pass));
self
}
pub fn add_modules(&mut self, modules: &[&dyn CriaPipelineModule]) -> &mut Self {
for module in modules {
module.build(self);
}
self
}
pub fn run(&mut self) {
for pass in &mut self.passes {
let exit_code = pass(self.info.clone());
if exit_code != 0 {
exit!(ErrorSection::Pipeline, exit_code);
}
}
}
}