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",
),
}
}
}