liteguard 0.7.20260603

Feature guards, observability, and security response in a single import. Evaluated locally, zero network overhead per check
Documentation
use liteguard::evaluation::evaluate_guard;
use liteguard::{Guard, PropertyValue, Rule};
use serde::Deserialize;
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;

#[derive(Deserialize)]
struct FixtureBundle {
    version: u32,
    cases: Vec<FixtureCase>,
}

#[derive(Deserialize)]
struct FixtureCase {
    name: String,
    guard: FixtureGuard,
    properties: HashMap<String, PropertyValue>,
    expected: bool,
}

#[derive(Deserialize)]
struct FixtureGuard {
    default_value: bool,
    rules: Vec<FixtureRule>,
}

#[derive(Deserialize)]
struct FixtureRule {
    property_name: String,
    operator: liteguard::Operator,
    values: Vec<PropertyValue>,
    result: bool,
    enabled: bool,
}

fn fixture_path() -> PathBuf {
    if let Ok(repo_root) = std::env::var("LITEGUARD_REPO_ROOT") {
        return PathBuf::from(repo_root)
            .join("tests")
            .join("conformance")
            .join("evaluation_cases.json");
    }

    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .join("..")
        .join("..")
        .join("tests")
        .join("conformance")
        .join("evaluation_cases.json")
}

fn to_guard(spec: FixtureGuard) -> Guard {
    Guard {
        name: "test.guard".into(),
        rules: spec
            .rules
            .into_iter()
            .map(|rule| Rule {
                property_name: rule.property_name,
                operator: rule.operator,
                values: rule.values,
                result: rule.result,
                enabled: rule.enabled,
            })
            .collect(),
        default_value: spec.default_value,
        adopted: true,
        rate_limit: None,
        dry_run_rate_limit: None,
        disable_measurement: None,
    }
}

#[test]
fn evaluation_matches_shared_conformance_fixtures() {
    let raw = fs::read_to_string(fixture_path()).expect("read conformance fixtures");
    let bundle: FixtureBundle = serde_json::from_str(&raw).expect("parse conformance fixtures");
    assert_eq!(bundle.version, 1);

    for case in bundle.cases {
        assert_eq!(
            evaluate_guard(
                &to_guard(case.guard),
                &liteguard::Properties(case.properties),
            ),
            case.expected,
            "{}",
            case.name
        );
    }
}