cuddle-v2/crates/cuddle/src/state.rs

108 lines
2.4 KiB
Rust
Raw Normal View History

use validated_project::Project;
use crate::{
actions::Actions,
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<ClonedPlan>,
) -> anyhow::Result<RawState> {
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<ValidatedState> {
// 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: LocalActions::default(),
})
}
}
pub struct RawState {
project: project::RawProject,
plan: Option<plan::RawPlan>,
}
#[derive(Default)]
pub struct ValidatedState {
pub project: Option<Project>,
pub plan: Option<Plan>,
pub actions: LocalActions,
}
impl ValidatedState {
pub(crate) async fn build_actions(&mut self) -> anyhow::Result<&mut Self> {
tracing::debug!("building actions");
if let Some(project) = &self.project {
if let Some(actions) = Actions::new(&project.root, &project.value).await? {
self.actions.add(actions);
}
}
self.actions.build().await?;
Ok(self)
}
}
pub struct Plan {}
#[derive(Default)]
pub struct LocalActions(Vec<Actions>);
impl LocalActions {
pub fn add(&mut self, actions: Actions) -> &mut Self {
self.0.push(actions);
self
}
pub async fn build(&mut self) -> anyhow::Result<&mut Self> {
for actions in &mut self.0 {
actions.build().await?;
}
Ok(self)
}
}
impl std::ops::Deref for LocalActions {
type Target = Vec<Actions>;
fn deref(&self) -> &Self::Target {
&self.0
}
}