floe_core/
lib.rs

1use std::path::Path;
2use yaml_schema::{Engine, RootSchema};
3
4pub mod config;
5pub mod checks;
6pub mod report;
7pub mod run;
8mod io;
9
10pub use checks as check;
11pub use run::run;
12
13pub type FloeResult<T> = Result<T, Box<dyn std::error::Error + Send + Sync>>;
14
15const SCHEMA_YAML: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/config.schema.yaml"));
16
17#[derive(Debug)]
18pub(crate) struct ConfigError(pub(crate) String);
19
20impl std::fmt::Display for ConfigError {
21    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22        write!(f, "{}", self.0)
23    }
24}
25
26impl std::error::Error for ConfigError {}
27
28#[derive(Debug, Default)]
29pub struct ValidateOptions {
30    pub entities: Vec<String>,
31}
32
33#[derive(Debug, Default)]
34pub struct RunOptions {
35    pub run_id: Option<String>,
36    pub entities: Vec<String>,
37}
38
39pub fn validate(config_path: &Path, options: ValidateOptions) -> FloeResult<()> {
40    let root_schema =
41        RootSchema::load_from_str(SCHEMA_YAML).map_err(|err| {
42            Box::new(ConfigError(format!(
43                "failed to load embedded schema: {err}"
44            )))
45        })?;
46
47    let yaml_contents = std::fs::read_to_string(config_path)?;
48    let context = Engine::evaluate(&root_schema, &yaml_contents, false)
49        .map_err(|err| Box::new(ConfigError(format!("schema validation failed: {err}"))))?;
50
51    if context.has_errors() {
52        let errors = context.errors.borrow();
53        let message = errors
54            .iter()
55            .map(|error| error.to_string())
56            .collect::<Vec<_>>()
57            .join("\n");
58        return Err(Box::new(ConfigError(message)));
59    }
60    let config = config::parse_config(config_path)?;
61    if !options.entities.is_empty() {
62        run::validate_entities(&config, &options.entities)?;
63    }
64
65    Ok(())
66}
67
68pub fn load_config(config_path: &Path) -> FloeResult<config::RootConfig> {
69    config::parse_config(config_path)
70}