use trellis_core::{GraphResult, InputNode, Transaction};
pub(crate) type StageOperation<C> =
dyn for<'tx> Fn(&mut Transaction<'tx, C>) -> GraphResult<()> + 'static;
pub struct TransactionScript<C = ()> {
pub(crate) steps: Vec<TransactionScriptStep<C>>,
}
impl<C> TransactionScript<C> {
pub fn new() -> Self {
Self { steps: Vec::new() }
}
pub fn step(&mut self, name: impl Into<String>) -> TransactionScriptStepBuilder<'_, C> {
TransactionScriptStepBuilder {
script: self,
name: name.into(),
operations: Vec::new(),
}
}
pub fn steps(&self) -> &[TransactionScriptStep<C>] {
&self.steps
}
}
impl<C> Default for TransactionScript<C> {
fn default() -> Self {
Self::new()
}
}
pub struct TransactionScriptStepBuilder<'script, C> {
script: &'script mut TransactionScript<C>,
name: String,
operations: Vec<Box<StageOperation<C>>>,
}
impl<C> TransactionScriptStepBuilder<'_, C> {
pub fn input<T>(mut self, input: InputNode<T>, value: T) -> Self
where
T: Clone + PartialEq + Send + Sync + 'static,
{
self.operations
.push(Box::new(move |tx| tx.set_input(input, value.clone())));
self
}
pub fn operation(
mut self,
operation: impl for<'tx> Fn(&mut Transaction<'tx, C>) -> GraphResult<()> + 'static,
) -> Self {
self.operations.push(Box::new(operation));
self
}
pub fn commit(self) {
self.script.steps.push(TransactionScriptStep {
name: self.name,
operations: self.operations,
});
}
}
pub struct TransactionScriptStep<C = ()> {
pub(crate) name: String,
pub(crate) operations: Vec<Box<StageOperation<C>>>,
}
impl<C> TransactionScriptStep<C> {
pub fn name(&self) -> &str {
&self.name
}
}