Skip to main content

wowlab_tidy/languages/toml/rules/manifest/
schema_version.rs

1use wowlab_manifest_schema::CURRENT_SCHEMA_VERSION;
2
3use super::{ITEMS_REL, MANIFEST_PREFIX};
4use crate::{Example, TomlCtx, Violation, violation};
5
6#[rustfmt::skip]
7const EXAMPLES: &[Example] = &[
8    Example { label: "explicit current schema", code: "schema_version = 1\n\n[spec]\nid = 1\n", pass: true },
9    Example { label: "missing schema version", code: "[spec]\nid = 1\n", pass: false },
10    Example { label: "unsupported schema version", code: "schema_version = 99\n\n[spec]\nid = 1\n", pass: false },
11];
12
13crate::toml_rule!(
14    toml_manifest_schema_version,
15    "Require every root manifest to declare the current schema version explicitly.",
16    "An omitted version is indistinguishable from the current version after a future schema migration.",
17    High,
18);
19
20fn check_toml_manifest_schema_version(ctx: &TomlCtx<'_>) -> Vec<Violation> {
21    if !is_root_manifest(ctx.file.rel) || !ctx.parse.errors.is_empty() {
22        return Vec::new();
23    }
24
25    let Ok(document) = toml::from_str::<toml::Table>(ctx.file.contents) else {
26        return Vec::new();
27    };
28
29    match document
30        .get("schema_version")
31        .and_then(toml::Value::as_integer)
32    {
33        Some(version) if version == i64::from(CURRENT_SCHEMA_VERSION) => Vec::new(),
34        Some(version) => vec![violation(
35            ctx.file.rel,
36            1,
37            format!("schema_version is {version}, expected {CURRENT_SCHEMA_VERSION}"),
38        )],
39        None => vec![violation(
40            ctx.file.rel,
41            1,
42            format!("root manifest must declare schema_version = {CURRENT_SCHEMA_VERSION}"),
43        )],
44    }
45}
46
47fn is_root_manifest(rel: &str) -> bool {
48    rel == ITEMS_REL
49        || (rel.starts_with(MANIFEST_PREFIX) && rel.rsplit('/').next() == Some("manifest.toml"))
50}
51
52crate::tidy_toml_test!(check_toml_manifest_schema_version, {
53    crate::example_tests!(EXAMPLES, check_toml_manifest_schema_version);
54});