Skip to content

Commit d3dc47f

Browse files
committed
chore(deps): upgrade perfectionist and enable non_exhaustive_error
Bump `perfectionist` past `0.0.0-rc.7` to its current `master` HEAD, which introduces the `non_exhaustive_error` rule and a suite of `single_letter_*` rules. Wire `non_exhaustive_error` in as a deny-level lint at the crate root and address the violations it surfaces: - Add `#[non_exhaustive]` to `args::fraction::ConversionError` and `args::fraction::FromStrError`. - Drop the unused `derive_more::Error` derive from `bytes_format::parsed_value::ParsedValue`. The enum is a formatter return value rather than an error type, so it no longer participates in the rule. The new `single_letter_*` rules also surface unrelated violations, addressed as follows: - Rename trait-method parameters `a` / `b` to `path` / `prefix` in `app::overlapping_arguments::Api::starts_with`, and rename the closure parameter `r` to `range` in `usage_md`. - Configure the rule's `comparison_methods` allowlist in `dylint.toml` to include the project-specific helper `sort_reflection_by` and the `into-sorted` crate's `into_sorted_by`, both of which take comparison closures whose `|a, b|` parameters CLAUDE.md explicitly permits. - Allow `single_letter_let_binding` at the `args` module level because `clap_derive`'s `default_value_t` expansion produces a `let s = ...` binding that is outside our control. Register the `perfectionist` tool and gate the deny directive on `cfg(dylint_lib = "perfectionist")` so non-dylint builds do not see an unknown lint tool. Declare the matching `check-cfg` entry in `Cargo.toml` to keep `unexpected_cfgs` quiet on ordinary builds. https://claude.ai/code/session_01CoRidYHvni9nKNgxMPXmfQ
1 parent 145bb5b commit d3dc47f

10 files changed

Lines changed: 56 additions & 10 deletions

File tree

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ terminal_size = "0.4.4"
8888
text-block-macros = "0.2.0"
8989
zero-copy-pads = "0.2.0"
9090

91+
[lints.rust]
92+
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(dylint_lib, values("perfectionist"))'] }
93+
9194
[dev-dependencies]
9295
build-fs-tree = "0.8.1"
9396
command-extra = "1.0.0"

dylint.toml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,31 @@
11
[workspace.metadata.dylint]
22
libraries = [
3-
{ git = "https://github.com/KSXGitHub/perfectionist", tag = "0.0.0-rc.7" },
3+
{ git = "https://github.com/KSXGitHub/perfectionist", rev = "3acd734c12fbd56d2c760f3c7bc9a19e45e62541" },
4+
]
5+
6+
["perfectionist::single_letter_names"]
7+
# Treat project-specific and third-party comparison-style helpers as if
8+
# they were standard `sort_by`-shaped methods, so the idiomatic
9+
# `|a, b| a.field.cmp(&b.field)` closure does not trip the rule. The
10+
# defaults are included explicitly because setting this list replaces
11+
# the built-in allowlist rather than extending it.
12+
comparison_methods = [
13+
"sort_by",
14+
"sort_unstable_by",
15+
"sort_by_key",
16+
"sort_unstable_by_key",
17+
"min_by",
18+
"max_by",
19+
"min_by_key",
20+
"max_by_key",
21+
"binary_search_by",
22+
"binary_search_by_key",
23+
"cmp_by",
24+
"partial_cmp_by",
25+
"eq_by",
26+
"fold",
27+
# Project-specific helper used in integration tests.
28+
"sort_reflection_by",
29+
# `into-sorted` crate's consuming sort.
30+
"into_sorted_by",
431
]

src/app/overlapping_arguments.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub trait Api {
1414
type RealPathError;
1515
fn canonicalize(path: &Self::Argument) -> Result<Self::RealPath, Self::RealPathError>;
1616
fn is_real_dir(path: &Self::Argument) -> bool;
17-
fn starts_with(a: &Self::RealPath, b: &Self::RealPath) -> bool;
17+
fn starts_with(path: &Self::RealPath, prefix: &Self::RealPath) -> bool;
1818
}
1919

2020
/// Implementation of [`Api`] that interacts with the real system.
@@ -36,8 +36,8 @@ impl Api for RealApi {
3636
}
3737

3838
#[inline]
39-
fn starts_with(a: &Self::RealPath, b: &Self::RealPath) -> bool {
40-
a.starts_with(b)
39+
fn starts_with(path: &Self::RealPath, prefix: &Self::RealPath) -> bool {
40+
path.starts_with(prefix)
4141
}
4242
}
4343

src/app/overlapping_arguments/test_remove_overlapping_paths.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ impl Api for MockedApi {
6464
.all(|(link, _)| PathBuf::from(link).normalize() != path)
6565
}
6666

67-
fn starts_with(a: &Self::RealPath, b: &Self::RealPath) -> bool {
68-
a.starts_with(b)
67+
fn starts_with(path: &Self::RealPath, prefix: &Self::RealPath) -> bool {
68+
path.starts_with(prefix)
6969
}
7070
}
7171

src/args.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
#![cfg_attr(
2+
dylint_lib = "perfectionist",
3+
allow(
4+
perfectionist::single_letter_let_binding,
5+
reason = "the `let s` bindings flagged by this lint originate in `clap_derive` macro expansion of `default_value_t` and are outside our control",
6+
)
7+
)]
8+
19
pub mod depth;
210
pub mod fraction;
311
pub mod quantity;

src/args/fraction.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub struct Fraction(f32);
1111

1212
/// Error that occurs when calling [`Fraction::new`].
1313
#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, Error)]
14+
#[non_exhaustive]
1415
pub enum ConversionError {
1516
/// Provided value is greater than or equal to 1.
1617
#[display("greater than or equal to 1")]
@@ -43,6 +44,7 @@ impl TryFrom<f32> for Fraction {
4344

4445
/// Error that occurs when parsing a string as [`Fraction`].
4546
#[derive(Debug, Display, Clone, PartialEq, Eq, Error)]
47+
#[non_exhaustive]
4648
pub enum FromStrError {
4749
ParseFloatError(ParseFloatError),
4850
Conversion(ConversionError),

src/bytes_format/parsed_value.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use derive_more::{Display, Error};
1+
use derive_more::Display;
22

33
/// Return value of [`Formatter::parse_value`](super::Formatter::parse_value).
4-
#[derive(Debug, Display, Clone, Copy, Error)]
4+
#[derive(Debug, Display, Clone, Copy)]
55
pub enum ParsedValue {
66
/// When input value is less than `scale_base`.
77
#[display("{value} ")]

src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
//! [`tree_builder::TreeBuilder`], [`data_tree::DataTree`], or [`visualizer::Visualizer`].
55
66
#![deny(warnings)]
7+
#![cfg_attr(dylint_lib = "perfectionist", feature(register_tool))]
8+
#![cfg_attr(dylint_lib = "perfectionist", register_tool(perfectionist))]
9+
#![cfg_attr(
10+
dylint_lib = "perfectionist",
11+
deny(perfectionist::non_exhaustive_error)
12+
)]
713

814
#[cfg(feature = "json")]
915
pub use serde;

src/usage_md.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ fn render_argument(out: &mut String, arg: &Arg) {
8585
.unwrap_or_else(|| arg.get_id().as_str());
8686
let is_multiple = arg
8787
.get_num_args()
88-
.map(|r| r.max_values() > 1)
88+
.map(|range| range.max_values() > 1)
8989
.unwrap_or(false);
9090
let display_name = if arg.is_required_set() {
9191
if is_multiple {

tests/_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ impl<'a> Default for CommandList<'a> {
466466
/// Initialize a list with one `pdu` command.
467467
fn default() -> Self {
468468
CommandRepresentation::default()
469-
.pipe(|x| vec![x])
469+
.pipe(|command| vec![command])
470470
.pipe(CommandList)
471471
}
472472
}

0 commit comments

Comments
 (0)