use crate::step::BoxedStep;
use serde_json::Value;
use std::collections::HashMap;
pub type ContextRecipe = Box<dyn Fn() -> Vec<BoxedStep> + Send + Sync>;
pub type ContextRecipeWithArgs =
Box<dyn Fn(&Value) -> anyhow::Result<Vec<BoxedStep>> + Send + Sync>;
#[derive(Default)]
pub struct ContextRegistry {
recipes: HashMap<String, ContextRecipe>,
recipes_with_args: HashMap<String, ContextRecipeWithArgs>,
}
impl ContextRegistry {
pub fn new() -> Self {
Self::default()
}
pub fn register(&mut self, name: impl Into<String>, recipe: ContextRecipe) -> &mut Self {
self.recipes.insert(name.into(), recipe);
self
}
pub fn register_with_args(
&mut self,
name: impl Into<String>,
recipe: ContextRecipeWithArgs,
) -> &mut Self {
self.recipes_with_args.insert(name.into(), recipe);
self
}
pub fn resolve(&self, name: &str) -> Option<Vec<BoxedStep>> {
self.recipes.get(name).map(|recipe| (recipe)())
}
pub fn resolve_with_args(&self, name: &str, args: &Value) -> anyhow::Result<Vec<BoxedStep>> {
let recipe = self
.recipes_with_args
.get(name)
.ok_or_else(|| anyhow::anyhow!("Unknown context: {name}"))?;
(recipe)(args)
}
}