Skip to main content

systemprompt_config/services/
schema_validation.rs

1use schemars::JsonSchema;
2use serde::de::DeserializeOwned;
3use std::path::Path;
4use thiserror::Error;
5
6#[derive(Debug, Error)]
7pub enum ConfigValidationError {
8    #[error("Failed to read config file: {0}")]
9    Read(#[from] std::io::Error),
10
11    #[error("Failed to parse YAML config: {0}")]
12    Parse(#[from] serde_yaml::Error),
13
14    #[error("Schema validation failed: {0}")]
15    Schema(String),
16}
17
18pub fn validate_config<T: DeserializeOwned + JsonSchema>(
19    yaml_path: impl AsRef<Path>,
20) -> Result<T, ConfigValidationError> {
21    let content = std::fs::read_to_string(yaml_path)?;
22    let config: T = serde_yaml::from_str(&content)?;
23    Ok(config)
24}
25
26pub fn generate_schema<T: JsonSchema>() -> Result<serde_json::Value, serde_json::Error> {
27    let schema = schemars::schema_for!(T);
28    serde_json::to_value(schema)
29}
30
31pub fn validate_yaml_str<T: DeserializeOwned>(yaml: &str) -> Result<T, ConfigValidationError> {
32    let config: T = serde_yaml::from_str(yaml)?;
33    Ok(config)
34}
35
36#[allow(
37    clippy::print_stderr,
38    clippy::exit,
39    clippy::print_stdout,
40    clippy::type_complexity
41)]
42pub fn build_validate_configs(configs: &[(&str, fn(&str) -> Result<(), String>)]) {
43    for (path, validator) in configs {
44        println!("cargo:rerun-if-changed={path}");
45        if let Err(e) = validator(path) {
46            eprintln!("Config validation failed for {path}: {e}");
47            std::process::exit(1);
48        }
49    }
50}
51
52pub fn validate_yaml_file(
53    path: impl AsRef<Path>,
54) -> Result<serde_yaml::Value, ConfigValidationError> {
55    let content = std::fs::read_to_string(path)?;
56    let value: serde_yaml::Value = serde_yaml::from_str(&content)?;
57    Ok(value)
58}