Skip to main content

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}