greentic-flow-builder 0.1.0

AI-powered Adaptive Card flow builder with visual graph editor and demo runner
Documentation
//! JSON Schema validation for preset data.

use anyhow::{Context, bail};
use serde_json::Value;

pub fn validate_data_against_schema(data: &Value, schema: &Value) -> anyhow::Result<()> {
    if schema.is_null() {
        return Ok(());
    }
    let validator = jsonschema::validator_for(schema).context("invalid JSON Schema")?;
    let errors: Vec<String> = validator
        .iter_errors(data)
        .map(|e| {
            let path = e.instance_path.to_string();
            if path.is_empty() {
                e.to_string()
            } else {
                format!("{}: {}", path, e)
            }
        })
        .collect();
    if errors.is_empty() {
        Ok(())
    } else {
        bail!("data validation failed:\n  - {}", errors.join("\n  - "));
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;

    #[test]
    fn test_valid_data() {
        let schema = json!({
            "type": "object",
            "required": ["name"],
            "properties": { "name": { "type": "string" } }
        });
        let data = json!({"name": "Alice"});
        assert!(validate_data_against_schema(&data, &schema).is_ok());
    }

    #[test]
    fn test_missing_required_field() {
        let schema = json!({
            "type": "object",
            "required": ["name"],
            "properties": { "name": { "type": "string" } }
        });
        let data = json!({});
        assert!(validate_data_against_schema(&data, &schema).is_err());
    }

    #[test]
    fn test_wrong_type() {
        let schema = json!({
            "type": "object",
            "properties": { "age": { "type": "integer" } }
        });
        let data = json!({"age": "not a number"});
        assert!(validate_data_against_schema(&data, &schema).is_err());
    }

    #[test]
    fn test_null_schema_skips_validation() {
        let data = json!({"anything": "goes"});
        assert!(validate_data_against_schema(&data, &Value::Null).is_ok());
    }
}