mdwright-lint 0.1.1

Lint diagnostics, rule execution, suppressions, and standard rules for mdwright
Documentation
//! The `LintRule` trait — `mdwright`'s open extension point.
//!
//! A rule is any `Send + Sync` value that names itself, describes
//! itself, and inspects a [`Document`] to produce [`Diagnostic`]s.
//! The standard library in [`crate::stdlib`] ships fifteen
//! implementors; user code adds more by implementing this trait on
//! a struct and dropping it into a [`RuleSet`](crate::RuleSet).
//!
//! ## Identity
//!
//! Each rule carries a stable kebab-case name. The name is the
//! identifier used in CLI flags (`--rules orphan-reference-link`),
//! configuration files, suppression comments, and diagnostic output.
//! Names must be unique within any `RuleSet` — duplicate insertion
//! fails (see [`RuleSet::add`](crate::RuleSet::add)).
//!
//! ## Emit pattern
//!
//! Rule implementations append [`Diagnostic`]s to the supplied
//! `Vec`. They should leave the diagnostic's `rule` field empty —
//! the dispatcher stamps it from `self.name()` after the call
//! returns, so rule code does not repeat its own name on every emit.

use crate::diagnostic::Diagnostic;
use mdwright_document::Document;

/// A lint check. Implementors may be unit structs (stdlib rules) or
/// carry configuration (regex patterns, allowlists, …).
pub trait LintRule: Send + Sync {
    /// Stable kebab-case identifier. Must be unique within any
    /// [`RuleSet`](crate::RuleSet).
    fn name(&self) -> &str;

    /// One-line summary for `mdwright list-rules`.
    fn description(&self) -> &str;

    /// Whether this rule is enabled in
    /// [`RuleSet::stdlib_defaults`](crate::RuleSet::stdlib_defaults).
    /// Most rules are on by default; the few opinionated or
    /// repair-focused checks return `false`.
    fn is_default(&self) -> bool {
        true
    }

    /// Advisory rules emit informational diagnostics that do not
    /// fail `mdwright check --check`. Their output still prints.
    fn is_advisory(&self) -> bool {
        false
    }

    /// Whether this rule can emit a [`crate::Fix`]. Used by
    /// `mdwright list-rules` and the generated rule docs. Defaults
    /// to `false`; stdlib rules that emit fixes override.
    fn produces_fix(&self) -> bool {
        false
    }

    /// Long-form explanation used by `mdwright explain <rule>` and
    /// the per-rule pages under `docs/rules/`. Returns an empty
    /// string by default so existing third-party rules continue to
    /// compile; stdlib rules override with a multi-paragraph
    /// markdown body (no frontmatter).
    fn explain(&self) -> &str {
        ""
    }

    /// Run the check against a parsed document. Append diagnostics
    /// to `out`. The dispatcher fills in each diagnostic's `rule`
    /// and `advisory` fields from `self.name()` and
    /// `self.is_advisory()` after the call returns.
    fn check(&self, doc: &Document, out: &mut Vec<Diagnostic>);
}