use crate::item::Item;
use crate::stdlib::Funcall;
use std::collections::BTreeMap;
use std::rc::Rc;
#[derive(Debug, Clone)]
pub struct Sub {
pub from: Item,
pub to: SubTo,
pub before: Option<Item>,
pub not_before: Option<Item>,
pub after: Option<Item>,
pub not_after: Option<Item>,
pub group_count: usize,
pub reverse_run: Option<bool>,
}
#[derive(Debug, Clone)]
pub enum SubTo {
Upcase,
Downcase,
Item(Item),
}
impl Sub {
pub fn max_length(&self) -> usize {
let mut len = self.from.max_length();
for c in [&self.before, &self.not_before, &self.after, &self.not_after] {
if let Some(item) = c {
len += item.max_length();
}
}
len
}
}
#[derive(Debug, Clone)]
pub enum StageItem {
Parallel(Vec<Sub>),
Sequential(Vec<Sub>),
Run {
dep: Option<String>,
stage: String,
reverse_run: Option<bool>,
},
Funcall(Funcall),
}
#[derive(Debug, Clone)]
pub struct Stage {
pub name: String,
pub items: Vec<StageItem>,
pub reverse_run: Option<bool>,
}
#[derive(Debug, Clone)]
pub struct AliasDef {
pub name: String,
pub value: Item,
}
#[derive(Debug, Clone)]
pub struct Dependency {
pub target: String,
pub alias: Option<String>,
}
#[derive(Debug, Clone, Default)]
pub struct Tests {
pub data: Vec<(String, String)>,
}
pub struct Document {
pub name: String,
pub system_code: String,
pub aliases: BTreeMap<String, Item>,
pub stages: BTreeMap<String, Stage>,
pub dep_aliases: BTreeMap<String, Rc<Document>>,
pub imports: Vec<Rc<Document>>,
pub tests: Tests,
pub metadata: Vec<(String, String)>,
}
impl Document {
pub fn imported_aliases(&self) -> BTreeMap<String, Item> {
let mut merged: BTreeMap<String, Item> = BTreeMap::new();
for dep in &self.imports {
for (k, v) in &dep.aliases {
merged.entry(k.clone()).or_insert_with(|| v.clone());
}
}
for (k, v) in &self.aliases {
merged.insert(k.clone(), v.clone());
}
merged
}
pub fn imported_stages(&self) -> BTreeMap<String, Stage> {
let mut merged: BTreeMap<String, Stage> = BTreeMap::new();
for dep in &self.imports {
for (k, v) in &dep.stages {
merged.entry(k.clone()).or_insert_with(|| v.clone());
}
}
for (k, v) in &self.stages {
merged.insert(k.clone(), v.clone());
}
merged
}
pub fn lookup_alias(&self, name: &str) -> Option<Item> {
self.imported_aliases().get(name).cloned()
}
}