Skip to main content

wowlab_tidy/infra/
ctx.rs

1use wowlab_fs::path::Path;
2
3use super::config::Config;
4
5/// Per-file context passed to line rules with path, raw contents, and pre-split lines.
6#[derive(Debug)]
7pub(crate) struct FileCtx<'a> {
8    pub(crate) rel: &'a str,
9    pub(crate) path: &'a Path,
10    pub(crate) lines: &'a [&'a str],
11    pub(crate) contents: &'a str,
12    pub(crate) config: &'a Config,
13}
14
15/// A single lint violation reported by a rule against a file location.
16#[derive(Debug)]
17pub(crate) struct Violation {
18    pub(crate) rel: String,
19    pub(crate) line: usize,
20    pub(crate) message: String,
21    pub(crate) rule: Option<&'static str>,
22}
23
24impl Violation {
25    pub(crate) fn with_rule(mut self, rule: &'static str) -> Self {
26        self.rule = Some(rule);
27
28        self
29    }
30
31    /// Return the rule name or `"unknown"` for untagged violations.
32    pub(crate) fn rule_name(&self) -> &str {
33        self.rule.unwrap_or("unknown")
34    }
35}
36
37/// Construct a `Violation` without a rule tag. Use `with_rule` to attach one.
38pub(crate) fn violation(rel: &str, line: usize, msg: impl Into<String>) -> Violation {
39    Violation {
40        rel: rel.to_string(),
41        line,
42        message: msg.into(),
43        rule: None,
44    }
45}
46
47impl FileCtx<'_> {
48    /// Get the source text of a specific line (1-based).
49    pub(crate) fn line(&self, lineno: usize) -> Option<&str> {
50        self.lines.get(lineno.checked_sub(1)?).copied()
51    }
52}