use cuddle_actions::Actions; use cuddle_actions_api::ExecutableActions; use validated_project::Project; use crate::{ plan::{self, ClonedPlan, PlanPathExt}, project::{self, ProjectPlan}, schema_validator::SchemaValidator, }; pub mod validated_project; pub struct State {} impl State { pub fn new() -> Self { Self {} } pub async fn build_state( &self, project_plan: &ProjectPlan, cloned_plan: &Option, ) -> anyhow::Result { let project = project::RawProject::from_path(&project_plan.root).await?; let plan = if let Some(_cloned_plan) = cloned_plan { Some(plan::RawPlan::from_path(&project_plan.plan_path()).await?) } else { None }; Ok(RawState { project, plan }) } pub async fn validate_state(&self, state: &RawState) -> anyhow::Result { // 2. Prepare context for actions and components if let Some(plan) = &state.plan { SchemaValidator::new().validate(plan, &state.project)?; } // 3. Match against schema from plan let project = validated_project::Project::from_path(&state.project.root).await?; Ok(ValidatedState { project: Some(project), plan: None, actions: ExecutableActions::default(), }) } } pub struct RawState { project: project::RawProject, plan: Option, } #[derive(Default)] pub struct ValidatedState { pub project: Option, pub plan: Option, pub actions: ExecutableActions, } impl ValidatedState { pub(crate) async fn build_actions(&mut self) -> anyhow::Result<&mut Self> { tracing::debug!("building actions"); let mut local_actions = LocalActions::default(); if let Some(project) = &self.project { if let Some(actions) = Actions::new(&project.root, &project.value).await? { local_actions.add(actions); } } self.actions = local_actions.build().await?; Ok(self) } } pub struct Plan {} #[derive(Default)] pub struct LocalActions(Vec); impl LocalActions { pub fn add(&mut self, actions: Actions) -> &mut Self { self.0.push(actions); self } pub async fn build(&mut self) -> anyhow::Result { let mut executable_actions = ExecutableActions::default(); for actions in &mut self.0 { let mut exec_actions = actions.build().await?; executable_actions.actions.append(&mut exec_actions.actions) } Ok(executable_actions) } } impl std::ops::Deref for LocalActions { type Target = Vec; fn deref(&self) -> &Self::Target { &self.0 } }