use crate::base::{AuthoredPath, StepKind};
use crate::def::{FailurePolicy, RejectionPolicy};
use crate::expr::{Expr, ExprVisitor, Path};
use crate::function::BoundCall;
use crate::function::builtins::Builtin;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum CondKind {
Workflow,
Group,
Task,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum Op {
Cond {
cond: u32,
kind: CondKind,
else_to: u32,
},
Call {
site: u32,
fail_to: u32,
},
FanOut {
site: u32,
fan: u32,
fail_to: u32,
},
LoopInit {
lp: u32,
exit_to: u32,
},
LoopNext {
lp: u32,
body_to: u32,
exit_to: u32,
},
Halt,
}
impl Op {
pub(crate) fn forward_mut(&mut self) -> Option<&mut u32> {
match self {
Self::Cond { else_to: to, .. }
| Self::Call { fail_to: to, .. }
| Self::FanOut { fail_to: to, .. }
| Self::LoopInit { exit_to: to, .. }
| Self::LoopNext { exit_to: to, .. } => Some(to),
Self::Halt => None,
}
}
pub(crate) fn forward(mut self) -> Option<u32> {
self.forward_mut().copied()
}
}
const _: () = assert!(size_of::<Op>() == 16);
pub(crate) struct CondSite {
pub(crate) expr: Expr,
pub(crate) step: Option<String>,
}
pub(crate) struct CallSite {
pub(crate) task: u32,
pub(crate) callee: Callee,
pub(crate) policy: Policy,
}
#[derive(Clone, Copy, Debug)]
pub(crate) struct Policy {
pub(crate) on_failure: FailurePolicy,
pub(crate) on_rejection: RejectionPolicy,
pub(crate) terminal: bool,
}
pub(crate) enum Callee {
Builtin(Builtin),
Host(Box<dyn BoundCall>),
}
impl Callee {
pub(crate) fn visit(&self, v: &mut dyn ExprVisitor) {
match self {
Self::Builtin(builtin) => builtin.visit(v),
Self::Host(bound) => bound.visit(v),
}
}
}
pub(crate) struct FanSite {
pub(crate) over: Expr,
pub(crate) r#as: Path,
pub(crate) index: Path,
pub(crate) max_concurrency: usize,
pub(crate) collect: Option<Path>,
pub(crate) into: Option<Path>,
}
pub(crate) struct LoopSite {
pub(crate) init: i64,
pub(crate) increment: i64,
pub(crate) max: i64,
pub(crate) counter: Option<Path>,
pub(crate) over: Option<Expr>,
pub(crate) r#as: Option<Path>,
pub(crate) scratch: Option<Path>,
}
pub(crate) struct TaskMeta {
pub(crate) id: String,
pub(crate) function: String,
pub(crate) kind: StepKind,
pub(crate) path: AuthoredPath,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn call_site_fits_in_256_bytes() {
let size = std::mem::size_of::<CallSite>();
assert!(size <= 256, "a call site is {size} bytes");
}
}