2024-08-24 15:16:30 +02:00
|
|
|
use validated_project::Project;
|
|
|
|
|
2024-08-24 14:55:26 +02:00
|
|
|
use crate::{
|
|
|
|
plan::{self, ClonedPlan, PlanPathExt},
|
|
|
|
project::{self, ProjectPlan},
|
|
|
|
schema_validator::SchemaValidator,
|
|
|
|
};
|
|
|
|
|
|
|
|
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
|
2024-08-24 15:16:30 +02:00
|
|
|
let project = validated_project::Project::from_path(&state.project.root).await?;
|
2024-08-24 14:55:26 +02:00
|
|
|
|
2024-08-24 15:16:30 +02:00
|
|
|
Ok(ValidatedState {
|
|
|
|
project: Some(project),
|
|
|
|
plan: None,
|
|
|
|
})
|
2024-08-24 14:55:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct RawState {
|
|
|
|
project: project::RawProject,
|
|
|
|
plan: Option<plan::RawPlan>,
|
|
|
|
}
|
2024-08-24 15:16:30 +02:00
|
|
|
|
|
|
|
#[derive(Default)]
|
|
|
|
pub struct ValidatedState {
|
|
|
|
project: Option<Project>,
|
|
|
|
plan: Option<Plan>,
|
|
|
|
}
|
|
|
|
|
|
|
|
mod validated_project {
|
|
|
|
use std::{
|
|
|
|
collections::BTreeMap,
|
|
|
|
path::{Path, PathBuf},
|
|
|
|
};
|
|
|
|
|
|
|
|
use anyhow::anyhow;
|
|
|
|
use toml::Table;
|
|
|
|
|
|
|
|
use crate::project::CUDDLE_PROJECT_FILE;
|
|
|
|
|
|
|
|
pub struct Project {
|
|
|
|
value: Value,
|
|
|
|
pub root: PathBuf,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Project {
|
|
|
|
pub fn new(value: Value, root: &Path) -> Self {
|
|
|
|
Self {
|
|
|
|
value,
|
|
|
|
root: root.to_path_buf(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_file(content: &str, root: &Path) -> anyhow::Result<Self> {
|
|
|
|
let table: Table = toml::from_str(content)?;
|
|
|
|
let config = Config::default();
|
|
|
|
|
|
|
|
let project = table
|
|
|
|
.get("project")
|
|
|
|
.ok_or(anyhow!("cuddle.toml doesn't provide a [project] table"))?;
|
|
|
|
|
|
|
|
let value: Value = project.into();
|
|
|
|
|
|
|
|
Ok(Self::new(value, root))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn from_path(path: &Path) -> anyhow::Result<Self> {
|
|
|
|
let cuddle_file = path.join(CUDDLE_PROJECT_FILE);
|
|
|
|
|
|
|
|
if !cuddle_file.exists() {
|
|
|
|
anyhow::bail!("no cuddle.toml project file found");
|
|
|
|
}
|
|
|
|
|
|
|
|
let cuddle_project_file = tokio::fs::read_to_string(cuddle_file).await?;
|
|
|
|
|
|
|
|
Self::from_file(&cuddle_project_file, path)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Default)]
|
|
|
|
struct Config {
|
|
|
|
project: BTreeMap<String, Value>,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub enum Value {
|
|
|
|
String(String),
|
|
|
|
Bool(bool),
|
|
|
|
Array(Vec<Value>),
|
|
|
|
Map(BTreeMap<String, Value>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&toml::Value> for Value {
|
|
|
|
fn from(value: &toml::Value) -> Self {
|
|
|
|
match value {
|
|
|
|
toml::Value::String(s) => Self::String(s.clone()),
|
|
|
|
toml::Value::Integer(i) => Self::String(i.to_string()),
|
|
|
|
toml::Value::Float(f) => Self::String(f.to_string()),
|
|
|
|
toml::Value::Boolean(b) => Self::Bool(*b),
|
|
|
|
toml::Value::Datetime(dt) => Self::String(dt.to_string()),
|
|
|
|
toml::Value::Array(array) => Self::Array(array.iter().map(|i| i.into()).collect()),
|
|
|
|
toml::Value::Table(tbl) => {
|
|
|
|
Self::Map(tbl.iter().map(|(k, v)| (k.clone(), v.into())).collect())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Plan {}
|