jsslint_core/catalogue.rs
1//! Rule metadata catalogue — compiled in from
2//! `specs/003-jss-rule-catalogue/catalogue.yaml` by `build.rs`.
3//!
4//! Mirrors `texlint.journals.jss._catalogue_data` (itself generated from
5//! the same YAML by `tools/generate_catalogue_data.py`). Both languages
6//! read the identical source of truth; neither hand-maintains a copy.
7
8use crate::report::Severity;
9use std::collections::HashMap;
10use std::sync::LazyLock;
11
12#[derive(Debug, Clone, Copy)]
13pub struct RuleMeta {
14 pub rule_id: &'static str,
15 pub category: &'static str,
16 pub severity: Severity,
17 pub message_template: &'static str,
18 pub authority: &'static str,
19 pub authority_ref: &'static str,
20 pub explanation: &'static str,
21 pub inspects: &'static [&'static str],
22 pub auto_fixable: bool,
23 /// Measured-precision confidence tier: "high" / "medium" / "low".
24 /// "high" is the catalogue default for rules without a narrowed tier.
25 pub confidence: &'static str,
26 /// JSS author-guide section label; "" for tool-side / un-backfilled rules.
27 pub guide_section: &'static str,
28 /// Absolute URL into the public JSS author guide; `None` for
29 /// tool-side / un-backfilled rules.
30 pub guide_url: Option<&'static str>,
31}
32
33include!(concat!(env!("OUT_DIR"), "/catalogue_data.rs"));
34
35static RULES_BY_ID: LazyLock<HashMap<&'static str, &'static RuleMeta>> =
36 LazyLock::new(|| RULES.iter().map(|r| (r.rule_id, r)).collect());
37
38/// Look up a rule's catalogue metadata by id. `None` for unknown ids
39/// (e.g. the synthetic `JSS-PARSE-000`, which has no catalogue entry —
40/// callers fall back to `RuleMeta`-shaped defaults, matching
41/// `output/json_output.py`'s `_catalogue().get(rule_id, {})`).
42pub fn lookup(rule_id: &str) -> Option<&'static RuleMeta> {
43 RULES_BY_ID.get(rule_id).copied()
44}
45
46/// Every catalogue rule's metadata, in the generated (alphabetical by
47/// id) order. Used by the SARIF renderer's `tool.driver.rules` array,
48/// which must list every rule regardless of whether it fired.
49pub fn all_rules() -> &'static [RuleMeta] {
50 RULES
51}
52
53/// Journal rollout order — mirrors `_catalogue_data.ROLLOUT_ORDER`
54/// (`journals/jss/__init__.py::JSSJournal.categories()` iterates this).
55pub fn categories() -> &'static [&'static str] {
56 CATEGORIES
57}