wowlab_tidy/languages/toml/rules/manifest/
schema.rs1use wowlab_fs::path::Path;
2use wowlab_manifest_schema::ManifestRepository;
3
4use super::{ITEMS_REL, MANIFEST_PREFIX, manifest_repository_root};
5use crate::{Example, TomlCtx, Violation, violation};
6
7const EXAMPLES: &[Example] = &[];
8
9crate::toml_rule!(
10 toml_manifest_schema,
11 "Require every root manifest to compose and deserialize through the canonical schema.",
12 "Taplo validates TOML syntax, while typed composition catches unknown fields, invalid fragments, duplicate definitions, and wrong value types.",
13 High,
14);
15
16fn check_toml_manifest_schema(ctx: &TomlCtx<'_>) -> Vec<Violation> {
17 if !ctx.file.rel.starts_with(MANIFEST_PREFIX) || !ctx.parse.errors.is_empty() {
18 return Vec::new();
19 }
20
21 let Some(root) = manifest_repository_root(ctx.file.path) else {
22 return Vec::new();
23 };
24 let repository = ManifestRepository::new(root);
25 let result = if Path::new(ctx.file.rel)
26 .file_name()
27 .is_some_and(|name| name == "manifest.toml")
28 {
29 repository.load_spec(ctx.file.path).map(|_| ())
30 } else if ctx.file.rel == ITEMS_REL {
31 repository.load_items().map(|_| ())
32 } else {
33 return Vec::new();
34 };
35
36 result.err().map_or_else(Vec::new, |error| {
37 vec![violation(ctx.file.rel, 1, error.to_string())]
38 })
39}