1use crate::error::{CapsulaError, CoreResult};
2use clap::ValueEnum;
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, Serialize, Deserialize)]
7#[serde(rename_all = "lowercase")]
8pub enum ContextPhase {
9 Pre,
10 Post,
11}
12
13#[derive(Debug, Clone)]
14pub struct RuntimeParams {
15 pub phase: ContextPhase,
16 pub run_dir: Option<std::path::PathBuf>,
17 pub project_root: std::path::PathBuf,
18}
19
20pub trait Context {
21 type Output: super::captured::Captured;
22 fn run(&self, params: &RuntimeParams) -> CoreResult<Self::Output>;
23}
24
25pub trait ContextErased: Send + Sync {
27 fn run_erased(
28 &self,
29 parmas: &RuntimeParams,
30 ) -> Result<Box<dyn super::captured::Captured>, CapsulaError>;
31}
32
33impl<T> ContextErased for T
34where
35 T: Context + Send + Sync + 'static,
36{
37 fn run_erased(
38 &self,
39 params: &RuntimeParams,
40 ) -> Result<Box<dyn super::captured::Captured>, CapsulaError> {
41 let out = <T as Context>::run(self, params)?;
42 Ok(Box::new(out))
43 }
44}
45
46pub trait ContextFactory: Send + Sync {
48 fn key(&self) -> &'static str;
50
51 fn create_context(
53 &self,
54 config: &Value,
55 project_root: &std::path::Path,
56 ) -> CoreResult<Box<dyn ContextErased>>;
57}