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",
"test-case",
"textwrap",
"thiserror",
"titlecase",
"toml_edit",
"wasm-bindgen",

View File

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

View File

@ -4,7 +4,7 @@ use clap::{command, Parser};
use regex::Regex;
use ruff::fs;
use ruff::logging::LogLevel;
use ruff::registry::{RuleCode, RuleCodePrefix};
use ruff::registry::{Rule, RuleCodePrefix};
use ruff::resolver::ConfigProcessor;
use ruff::settings::types::{
FilePattern, PatternPrefixPair, PerFileIgnore, PythonVersion, SerializationFormat,
@ -169,6 +169,7 @@ pub struct Cli {
/// Explain a rule.
#[arg(
long,
value_parser=Rule::from_code,
// Fake subcommands.
conflicts_with = "add_noqa",
conflicts_with = "clean",
@ -180,7 +181,7 @@ pub struct Cli {
conflicts_with = "stdin_filename",
conflicts_with = "watch",
)]
pub explain: Option<RuleCode>,
pub explain: Option<Rule>,
/// Generate shell completion
#[arg(
long,
@ -302,7 +303,7 @@ pub struct Arguments {
pub config: Option<PathBuf>,
pub diff: bool,
pub exit_zero: bool,
pub explain: Option<RuleCode>,
pub explain: Option<Rule>,
pub files: Vec<PathBuf>,
pub generate_shell_completion: Option<clap_complete_command::Shell>,
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(),
};
if let Some(code) = cli.explain {
commands::explain(&code, format)?;
if let Some(rule) = cli.explain {
commands::explain(&rule, format)?;
return Ok(ExitCode::SUCCESS);
}
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_origin_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_body_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,});
let code_str = LitStr::new(&code.to_string(), Span::call_site());
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_body_match_arms.extend(quote! {Self::#name(x) => Violation::message(x), });
diagkind_fixable_match_arms
@ -49,7 +51,6 @@ pub fn define_rule_mapping(mapping: &Mapping) -> proc_macro2::TokenStream {
quote! {
#[derive(
EnumIter,
EnumString, // TODO(martin): Remove
Debug,
PartialEq,
Eq,
@ -67,6 +68,11 @@ pub fn define_rule_mapping(mapping: &Mapping) -> proc_macro2::TokenStream {
#[derive(AsRefStr, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum DiagnosticKind { #diagkind_variants }
#[derive(thiserror::Error, Debug)]
pub enum FromCodeError {
#[error("unknown rule code")]
Unknown,
}
impl Rule {
/// 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 {
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.
use std::str::FromStr;
use nohash_hasher::IntMap;
use rustpython_parser::ast::Location;
use crate::ast::types::Range;
use crate::fix::Fix;
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::violations::UnusedCodes;
use crate::{noqa, violations};
@ -134,8 +132,8 @@ pub fn check_noqa(
if matches.contains(&code) || settings.external.contains(code) {
valid_codes.push(code);
} else {
if let Ok(rule_code) = RuleCode::from_str(code) {
if settings.rules.enabled(&rule_code) {
if let Ok(rule) = Rule::from_code(code) {
if settings.rules.enabled(rule) {
unmatched_codes.push(code);
} else {
disabled_codes.push(code);

View File

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