rule 5/8: Remove FromStr impl for Rule

This commit is contained in:
Martin Fischer 2023-01-18 01:24:27 +01:00 committed by Charlie Marsh
parent 3534e370e1
commit 6cf770a692
7 changed files with 27 additions and 15 deletions

1
Cargo.lock generated
View File

@ -1951,6 +1951,7 @@ dependencies = [
"strum_macros", "strum_macros",
"test-case", "test-case",
"textwrap", "textwrap",
"thiserror",
"titlecase", "titlecase",
"toml_edit", "toml_edit",
"wasm-bindgen", "wasm-bindgen",

View File

@ -61,6 +61,7 @@ strum_macros = { version = "0.24.3" }
textwrap = { version = "0.16.0" } textwrap = { version = "0.16.0" }
titlecase = { version = "2.2.1" } titlecase = { version = "2.2.1" }
toml_edit = { version = "0.17.1", features = ["easy"] } toml_edit = { version = "0.17.1", features = ["easy"] }
thiserror = { version = "1.0" }
# https://docs.rs/getrandom/0.2.7/getrandom/#webassembly-support # https://docs.rs/getrandom/0.2.7/getrandom/#webassembly-support
# For (future) wasm-pack support # For (future) wasm-pack support

View File

@ -4,7 +4,7 @@ use clap::{command, Parser};
use regex::Regex; use regex::Regex;
use ruff::fs; use ruff::fs;
use ruff::logging::LogLevel; use ruff::logging::LogLevel;
use ruff::registry::{RuleCode, RuleCodePrefix}; use ruff::registry::{Rule, RuleCodePrefix};
use ruff::resolver::ConfigProcessor; use ruff::resolver::ConfigProcessor;
use ruff::settings::types::{ use ruff::settings::types::{
FilePattern, PatternPrefixPair, PerFileIgnore, PythonVersion, SerializationFormat, FilePattern, PatternPrefixPair, PerFileIgnore, PythonVersion, SerializationFormat,
@ -169,6 +169,7 @@ pub struct Cli {
/// Explain a rule. /// Explain a rule.
#[arg( #[arg(
long, long,
value_parser=Rule::from_code,
// Fake subcommands. // Fake subcommands.
conflicts_with = "add_noqa", conflicts_with = "add_noqa",
conflicts_with = "clean", conflicts_with = "clean",
@ -180,7 +181,7 @@ pub struct Cli {
conflicts_with = "stdin_filename", conflicts_with = "stdin_filename",
conflicts_with = "watch", conflicts_with = "watch",
)] )]
pub explain: Option<RuleCode>, pub explain: Option<Rule>,
/// Generate shell completion /// Generate shell completion
#[arg( #[arg(
long, long,
@ -302,7 +303,7 @@ pub struct Arguments {
pub config: Option<PathBuf>, pub config: Option<PathBuf>,
pub diff: bool, pub diff: bool,
pub exit_zero: bool, pub exit_zero: bool,
pub explain: Option<RuleCode>, pub explain: Option<Rule>,
pub files: Vec<PathBuf>, pub files: Vec<PathBuf>,
pub generate_shell_completion: Option<clap_complete_command::Shell>, pub generate_shell_completion: Option<clap_complete_command::Shell>,
pub isolated: bool, pub isolated: bool,

View File

@ -157,8 +157,8 @@ quoting the executed command, along with the relevant file contents and `pyproje
PyprojectDiscovery::Hierarchical(settings) => settings.cli.clone(), PyprojectDiscovery::Hierarchical(settings) => settings.cli.clone(),
}; };
if let Some(code) = cli.explain { if let Some(rule) = cli.explain {
commands::explain(&code, format)?; commands::explain(&rule, format)?;
return Ok(ExitCode::SUCCESS); return Ok(ExitCode::SUCCESS);
} }
if cli.show_settings { if cli.show_settings {

View File

@ -9,6 +9,7 @@ pub fn define_rule_mapping(mapping: &Mapping) -> proc_macro2::TokenStream {
let mut rule_kind_match_arms = quote!(); let mut rule_kind_match_arms = quote!();
let mut rule_origin_match_arms = quote!(); let mut rule_origin_match_arms = quote!();
let mut rule_code_match_arms = quote!(); let mut rule_code_match_arms = quote!();
let mut rule_from_code_match_arms = quote!();
let mut diagkind_code_match_arms = quote!(); let mut diagkind_code_match_arms = quote!();
let mut diagkind_body_match_arms = quote!(); let mut diagkind_body_match_arms = quote!();
let mut diagkind_fixable_match_arms = quote!(); let mut diagkind_fixable_match_arms = quote!();
@ -25,6 +26,7 @@ pub fn define_rule_mapping(mapping: &Mapping) -> proc_macro2::TokenStream {
rule_origin_match_arms.extend(quote! {Self::#code => RuleOrigin::#origin,}); rule_origin_match_arms.extend(quote! {Self::#code => RuleOrigin::#origin,});
let code_str = LitStr::new(&code.to_string(), Span::call_site()); let code_str = LitStr::new(&code.to_string(), Span::call_site());
rule_code_match_arms.extend(quote! {Self::#code => #code_str,}); rule_code_match_arms.extend(quote! {Self::#code => #code_str,});
rule_from_code_match_arms.extend(quote! {#code_str => Ok(&RuleCode::#code), });
diagkind_code_match_arms.extend(quote! {Self::#name(..) => &RuleCode::#code, }); diagkind_code_match_arms.extend(quote! {Self::#name(..) => &RuleCode::#code, });
diagkind_body_match_arms.extend(quote! {Self::#name(x) => Violation::message(x), }); diagkind_body_match_arms.extend(quote! {Self::#name(x) => Violation::message(x), });
diagkind_fixable_match_arms diagkind_fixable_match_arms
@ -49,7 +51,6 @@ pub fn define_rule_mapping(mapping: &Mapping) -> proc_macro2::TokenStream {
quote! { quote! {
#[derive( #[derive(
EnumIter, EnumIter,
EnumString, // TODO(martin): Remove
Debug, Debug,
PartialEq, PartialEq,
Eq, Eq,
@ -67,6 +68,11 @@ pub fn define_rule_mapping(mapping: &Mapping) -> proc_macro2::TokenStream {
#[derive(AsRefStr, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(AsRefStr, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum DiagnosticKind { #diagkind_variants } pub enum DiagnosticKind { #diagkind_variants }
#[derive(thiserror::Error, Debug)]
pub enum FromCodeError {
#[error("unknown rule code")]
Unknown,
}
impl Rule { impl Rule {
/// A placeholder representation of the `DiagnosticKind` for the diagnostic. /// A placeholder representation of the `DiagnosticKind` for the diagnostic.
@ -81,6 +87,13 @@ pub fn define_rule_mapping(mapping: &Mapping) -> proc_macro2::TokenStream {
pub fn code(&self) -> &'static str { pub fn code(&self) -> &'static str {
match self { #rule_code_match_arms } match self { #rule_code_match_arms }
} }
pub fn from_code(code: &str) -> Result<&'static Self, FromCodeError> {
match code {
#rule_from_code_match_arms
_ => Err(FromCodeError::Unknown),
}
}
} }

View File

@ -1,14 +1,12 @@
//! `NoQA` enforcement and validation. //! `NoQA` enforcement and validation.
use std::str::FromStr;
use nohash_hasher::IntMap; use nohash_hasher::IntMap;
use rustpython_parser::ast::Location; use rustpython_parser::ast::Location;
use crate::ast::types::Range; use crate::ast::types::Range;
use crate::fix::Fix; use crate::fix::Fix;
use crate::noqa::{is_file_exempt, Directive}; use crate::noqa::{is_file_exempt, Directive};
use crate::registry::{Diagnostic, DiagnosticKind, RuleCode, CODE_REDIRECTS}; use crate::registry::{Diagnostic, DiagnosticKind, Rule, RuleCode, CODE_REDIRECTS};
use crate::settings::{flags, Settings}; use crate::settings::{flags, Settings};
use crate::violations::UnusedCodes; use crate::violations::UnusedCodes;
use crate::{noqa, violations}; use crate::{noqa, violations};
@ -134,8 +132,8 @@ pub fn check_noqa(
if matches.contains(&code) || settings.external.contains(code) { if matches.contains(&code) || settings.external.contains(code) {
valid_codes.push(code); valid_codes.push(code);
} else { } else {
if let Ok(rule_code) = RuleCode::from_str(code) { if let Ok(rule) = Rule::from_code(code) {
if settings.rules.enabled(&rule_code) { if settings.rules.enabled(rule) {
unmatched_codes.push(code); unmatched_codes.push(code);
} else { } else {
disabled_codes.push(code); disabled_codes.push(code);

View File

@ -5,7 +5,7 @@ use once_cell::sync::Lazy;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use rustpython_parser::ast::Location; use rustpython_parser::ast::Location;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use strum_macros::{AsRefStr, EnumIter, EnumString}; use strum_macros::{AsRefStr, EnumIter};
use crate::ast::types::Range; use crate::ast::types::Range;
use crate::fix::Fix; use crate::fix::Fix;
@ -712,8 +712,6 @@ pub static CODE_REDIRECTS: Lazy<FxHashMap<&'static str, RuleCode>> = Lazy::new(|
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::str::FromStr;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::registry::Rule; use crate::registry::Rule;
@ -722,7 +720,7 @@ mod tests {
fn check_code_serialization() { fn check_code_serialization() {
for rule in Rule::iter() { for rule in Rule::iter() {
assert!( assert!(
Rule::from_str(rule.code()).is_ok(), Rule::from_code(rule.code()).is_ok(),
"{rule:?} could not be round-trip serialized." "{rule:?} could not be round-trip serialized."
); );
} }