1mod ast;
2pub mod cli;
3mod config;
4mod context;
5mod dsl;
6mod effect;
7mod engine;
8mod fix;
9mod format;
10mod format_conversions;
11mod ignore;
12pub mod log;
13#[cfg(feature = "lsp")]
14mod lsp;
15mod rule;
16mod rules;
17mod span;
18mod violation;
19
20use std::{error::Error, fmt, io, path::PathBuf};
21
22pub use config::{Config, LintLevel};
23pub use engine::LintEngine;
24pub use fix::apply_fixes_iteratively;
25use toml::{de, ser};
26use violation::{Fix, Replacement};
27
28pub const NU_PARSER_VERSION: &str = env!("NU_PARSER_VERSION");
29
30#[derive(Debug)]
31pub enum LintError {
32 Io {
33 path: PathBuf,
34 source: io::Error,
35 },
36 Config {
37 source: de::Error,
38 },
39 ConfigSerialize {
40 source: ser::Error,
41 },
42 RuleDoesNotExist {
43 non_existing_id: String,
44 },
45 RuleConflict {
46 rule_a: &'static str,
47 rule_b: &'static str,
48 },
49 NoConfigLocation,
50}
51
52impl fmt::Display for LintError {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 match self {
55 Self::Io { path, source } => {
56 write!(f, "failed to read '{}': {source}", path.display())
57 }
58 Self::RuleDoesNotExist { non_existing_id } => write!(
59 f,
60 "Rule declared in config with id `{non_existing_id}` does not exist in this \
61 version."
62 ),
63 Self::Config { source } => write!(f, "invalid configuration: {source}"),
64 Self::ConfigSerialize { source } => {
65 write!(f, "failed to serialize configuration: {source}")
66 }
67 Self::RuleConflict { rule_a, rule_b } => {
68 write!(
69 f,
70 "Based on the defaults merged with any configuration file (if present), the \
71 following two rules are both enabled and conclicting: '{rule_a}' and \
72 '{rule_b}'. The linter will not be able to start until you make sure at most \
73 one of both is active. Use the configuration file to override the lint \
74 levels."
75 )
76 }
77 Self::NoConfigLocation => {
78 write!(f, "no workspace root or home directory available")
79 }
80 }
81 }
82}
83
84impl Error for LintError {
85 fn source(&self) -> Option<&(dyn Error + 'static)> {
86 match self {
87 Self::Io { source, .. } => Some(source),
88 Self::Config { source } => Some(source),
89 Self::ConfigSerialize { source } => Some(source),
90 Self::RuleConflict { .. } | Self::RuleDoesNotExist { .. } | Self::NoConfigLocation => {
91 None
92 }
93 }
94 }
95}