alpm_lint/
rule.rs

1//! The trait definition and behavioral description of a lint rule.
2
3use std::collections::BTreeMap;
4
5use alpm_lint_config::{LintGroup, LintRuleConfigurationOptionName};
6
7use crate::{Error, Level, LintScope, ScopedName, issue::LintIssue, resources::Resources};
8
9/// The trait definition and behavioral description of a lint rule.
10///
11/// This trait must be implemented by every available lint.
12pub trait LintRule {
13    /// Returns the name of this lint rule.
14    ///
15    /// # Note
16    ///
17    /// This must be a static and unique identifier.
18    fn name(&self) -> &'static str;
19
20    /// Returns the full name of this lint by combining [`LintRule::scope`] and [`LintRule::name`]
21    /// as `{scope}::{name}`.
22    ///
23    /// # Warning
24    ///
25    /// Do not re-implement this. The default implementation should cover all cases.
26    fn scoped_name(&self) -> String {
27        ScopedName::new(self.scope(), self.name()).to_string()
28    }
29
30    /// Return the scope of this lint rule.
31    ///
32    /// This is used to select groups of lints based on the performed linting operation.
33    /// Linting scopes can also be fully dis-/enabled via configuration files.
34    fn scope(&self) -> LintScope;
35
36    /// The severity level of this lint rule.
37    ///
38    /// This is used to determine what lint messages should be shown to the user based on CLI flags
39    /// and configuration.
40    ///
41    /// # Note
42    ///
43    /// The default level is [`Level::Warn`].
44    fn level(&self) -> Level {
45        Level::Warn
46    }
47
48    /// Returns the static lint groups this lint rule belongs to.
49    ///
50    /// Lint rules can be in zero or more lint groups.
51    /// Each lint rule is considered "enabled" by default, unless it belongs to a [`LintGroup`].
52    /// Lint rules that are part of one or more lint groups need to be enabled explicitly.
53    fn groups(&self) -> &'static [LintGroup] {
54        &[]
55    }
56
57    /// Executes the linting logic and appends to list of accumulated issues.
58    ///
59    /// This method accepts the [`Resources`] enum, that contains all data required to run a
60    /// lint.
61    ///
62    /// The second argument (`issues`) is the list of accumulated issues across all lints.
63    /// If your lint rule encounters an issue, add it to that list.
64    fn run(&self, resources: &Resources, issues: &mut Vec<LintIssue>) -> Result<(), Error>;
65
66    /// Returns the full documentation for this lint rule.
67    ///
68    /// This includes:
69    ///
70    /// - a description of what the rule does,
71    /// - the reasoning behind its existence,
72    /// - and example usage.
73    ///
74    /// Typically, you should use the [`documented`] crate to forward the doc
75    /// comments from the struct that implements this trait.
76    ///
77    /// # Examples
78    /// ```rust,ignore
79    /// fn documentation(&self) -> String {
80    ///     DuplicateArchitecture::DOCS.into()
81    /// }
82    /// ```
83    fn documentation(&self) -> String;
84
85    /// Returns the help text for this lint rule.
86    ///
87    /// The help text explains why this lint is encountered and
88    /// how to potentially fix it.
89    ///
90    /// This information is shown to users when they encounter an issue with this lint.
91    fn help_text(&self) -> String;
92
93    /// Returns a map of configuration options used by this lint rule.
94    ///
95    /// The returned map of [`LintRuleConfigurationOptionName`] represents the options that this
96    /// lint rule uses to configure itself.
97    /// This is necessary to reference the correct options on the central `lint-config-website`.
98    fn configuration_options(&self) -> &[LintRuleConfigurationOptionName] {
99        &[]
100    }
101
102    /// Returns a map of additional associated links for this lint rule.
103    ///
104    /// The map provides the links as tuples of URL name and URL (i.e. `BTreeMap<URL-Name, URL>`).
105    ///
106    /// These links are displayed to users on the central `lint-config-website` as additional
107    /// information.
108    fn extra_links(&self) -> Option<BTreeMap<String, String>> {
109        None
110    }
111}