koala-core 1.0.4

Shared types, invariant evaluator, and primitives for the koala framework.
Documentation
use crate::invariant::{Category, Context, Invariant, Outcome};
use std::fs;

pub struct WorkspaceEditionPinned;

impl Invariant for WorkspaceEditionPinned {
    fn id(&self) -> &'static str {
        "arch.workspace-edition-pinned"
    }
    fn category(&self) -> Category {
        Category::Arch
    }
    fn intent(&self) -> &'static str {
        "Root Cargo.toml [workspace.package] declares an explicit edition."
    }
    fn adr(&self) -> Option<&'static str> {
        Some("ADR-0013")
    }

    fn evaluate(&self, ctx: &Context) -> Outcome {
        let path = ctx.root().join("Cargo.toml");
        let Ok(content) = fs::read_to_string(&path) else {
            return Outcome::skip("root Cargo.toml not found");
        };
        let parsed: toml::Value = match toml::from_str(&content) {
            Ok(v) => v,
            Err(e) => return Outcome::fail(format!("failed to parse Cargo.toml: {e}")),
        };
        let edition = parsed
            .get("workspace")
            .and_then(|w| w.get("package"))
            .and_then(|p| p.get("edition"))
            .and_then(|e| e.as_str());
        match edition {
            Some(ed) => Outcome::pass_with(format!("edition = \"{ed}\"")),
            None => Outcome::fail_repro(
                "Cargo.toml [workspace.package] missing `edition`",
                "grep -A2 '\\[workspace.package\\]' Cargo.toml",
            ),
        }
    }
}