From e8c955da4cbb042e6f9b89307d143f5bfa6779fa Mon Sep 17 00:00:00 2001 From: Akshay Date: Sun, 31 Oct 2021 14:35:26 +0530 Subject: add `explain` subcommand and explanations to all lints --- bin/src/config.rs | 24 ++++++++++++++++++++++++ bin/src/err.rs | 10 ++++++++++ bin/src/explain.rs | 15 +++++++++++++++ bin/src/main.rs | 5 +++++ 4 files changed, 54 insertions(+) create mode 100644 bin/src/explain.rs (limited to 'bin') diff --git a/bin/src/config.rs b/bin/src/config.rs index ef3a29d..1649017 100644 --- a/bin/src/config.rs +++ b/bin/src/config.rs @@ -26,6 +26,8 @@ pub enum SubCommand { Fix(Fix), /// Fix exactly one issue at provided position Single(Single), + /// Print detailed explanation for a lint warning + Explain(Explain), } #[derive(Clap, Debug)] @@ -88,6 +90,13 @@ pub struct Single { pub diff_only: bool, } +#[derive(Clap, Debug)] +pub struct Explain { + /// Warning code to explain + #[clap(parse(try_from_str = parse_warning_code))] + pub target: u32, +} + mod dirs { use std::{ fs, @@ -160,6 +169,21 @@ fn parse_line_col(src: &str) -> Result<(usize, usize), ConfigErr> { } } +fn parse_warning_code(src: &str) -> Result { + let mut char_stream = src.chars(); + let severity = char_stream + .next() + .ok_or(ConfigErr::InvalidWarningCode(src.to_owned()))? + .to_ascii_lowercase(); + match severity { + 'w' => char_stream + .collect::() + .parse::() + .map_err(|_| ConfigErr::InvalidWarningCode(src.to_owned())), + _ => Ok(0), + } +} + fn build_ignore_set(ignores: &[String]) -> Result { let mut set = GlobSetBuilder::new(); for pattern in ignores { diff --git a/bin/src/err.rs b/bin/src/err.rs index 4c16d69..1e52c2b 100644 --- a/bin/src/err.rs +++ b/bin/src/err.rs @@ -12,6 +12,8 @@ pub enum ConfigErr { InvalidPath(#[from] io::Error), #[error("unable to parse `{0}` as line and column")] InvalidPosition(String), + #[error("unable to parse `{0}` as warning code")] + InvalidWarningCode(String), } // #[derive(Error, Debug)] @@ -40,6 +42,12 @@ pub enum SingleFixErr { NoOp, } +#[derive(Error, Debug)] +pub enum ExplainErr { + #[error("lint with code `{0}` not found")] + LintNotFound(u32), +} + #[derive(Error, Debug)] pub enum StatixErr { // #[error("linter error: {0}")] @@ -50,4 +58,6 @@ pub enum StatixErr { Single(#[from] SingleFixErr), #[error("config error: {0}")] Config(#[from] ConfigErr), + #[error("explain error: {0}")] + Explain(#[from] ExplainErr), } diff --git a/bin/src/explain.rs b/bin/src/explain.rs new file mode 100644 index 0000000..6aefa7e --- /dev/null +++ b/bin/src/explain.rs @@ -0,0 +1,15 @@ +use crate::err::ExplainErr; + +use lib::LINTS; + +pub fn explain(code: u32) -> Result<&'static str, ExplainErr> { + match code { + 0 => Ok("syntax error"), + _ => LINTS + .values() + .flatten() + .find(|l| l.code() == code) + .map(|l| l.explanation()) + .ok_or(ExplainErr::LintNotFound(code)), + } +} diff --git a/bin/src/main.rs b/bin/src/main.rs index 90b79ce..31f6823 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -1,5 +1,6 @@ mod config; mod err; +mod explain; mod fix; mod lint; mod traits; @@ -86,6 +87,10 @@ fn _main() -> Result<(), StatixErr> { print!("{}", &*single_fix_result.src) } } + SubCommand::Explain(explain_config) => { + let explanation = explain::explain(explain_config.target)?; + println!("{}", explanation) + } } Ok(()) } -- cgit v1.2.3