Skip to content

Commit

Permalink
Introduce pedantic lint config
Browse files Browse the repository at this point in the history
Configure `clippy` to do warn for pedantic lints and fix warnings.
  • Loading branch information
tcharding committed Mar 6, 2025
1 parent c1e12b6 commit a05406c
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 28 deletions.
126 changes: 125 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,130 @@ name = "wrap_array"
name = "serde"
required-features = ["std", "serde"]


[lints.clippy]
# Exclude lints we don't think are valuable.
needless_question_mark = "allow" # https://github.com/rust-bitcoin/rust-bitcoin/pull/2134
manual_range_contains = "allow" # More readable than clippy's format.
# Exhaustive list of pedantic clippy lints
assigning_clones = "warn"
bool_to_int_with_if = "warn"
borrow_as_ptr = "warn"
case_sensitive_file_extension_comparisons = "warn"
cast_lossless = "warn"
cast_possible_truncation = "allow" # All casts should include a code comment (except test code).
cast_possible_wrap = "allow" # Same as above re code comment.
cast_precision_loss = "warn"
cast_ptr_alignment = "warn"
cast_sign_loss = "allow" # All casts should include a code comment (except in test code).
checked_conversions = "warn"
cloned_instead_of_copied = "warn"
copy_iterator = "warn"
default_trait_access = "warn"
doc_link_with_quotes = "warn"
doc_markdown = "warn"
empty_enum = "warn"
enum_glob_use = "warn"
expl_impl_clone_on_copy = "warn"
explicit_deref_methods = "warn"
explicit_into_iter_loop = "warn"
explicit_iter_loop = "warn"
filter_map_next = "warn"
flat_map_option = "warn"
float_cmp = "allow" # Bitcoin floats are typically limited to 8 decimal places and we want them exact.
fn_params_excessive_bools = "warn"
from_iter_instead_of_collect = "warn"
if_not_else = "warn"
ignored_unit_patterns = "warn"
implicit_clone = "warn"
implicit_hasher = "warn"
inconsistent_struct_constructor = "warn"
index_refutable_slice = "warn"
inefficient_to_string = "warn"
inline_always = "warn"
into_iter_without_iter = "warn"
invalid_upcast_comparisons = "warn"
items_after_statements = "warn"
iter_filter_is_ok = "warn"
iter_filter_is_some = "warn"
iter_not_returning_iterator = "warn"
iter_without_into_iter = "warn"
large_digit_groups = "warn"
large_futures = "warn"
large_stack_arrays = "warn"
large_types_passed_by_value = "warn"
linkedlist = "warn"
macro_use_imports = "warn"
manual_assert = "warn"
manual_instant_elapsed = "warn"
manual_is_power_of_two = "warn"
manual_is_variant_and = "warn"
manual_let_else = "warn"
manual_ok_or = "warn"
manual_string_new = "warn"
many_single_char_names = "warn"
map_unwrap_or = "warn"
match_bool = "allow" # Adds extra indentation and LOC.
match_on_vec_items = "warn"
match_same_arms = "allow" # Collapses things that are conceptually unrelated to each other.
match_wild_err_arm = "warn"
match_wildcard_for_single_variants = "warn"
maybe_infinite_iter = "warn"
mismatching_type_param_order = "warn"
missing_errors_doc = "warn"
missing_fields_in_debug = "warn"
missing_panics_doc = "warn"
must_use_candidate = "allow" # Useful for audit but many false positives.
mut_mut = "warn"
naive_bytecount = "warn"
needless_bitwise_bool = "warn"
needless_continue = "warn"
needless_for_each = "warn"
needless_pass_by_value = "warn"
needless_raw_string_hashes = "warn"
no_effect_underscore_binding = "warn"
no_mangle_with_rust_abi = "warn"
option_as_ref_cloned = "warn"
option_option = "warn"
ptr_as_ptr = "warn"
ptr_cast_constness = "warn"
pub_underscore_fields = "warn"
range_minus_one = "warn"
range_plus_one = "warn"
redundant_closure_for_method_calls = "warn"
redundant_else = "warn"
ref_as_ptr = "warn"
ref_binding_to_reference = "warn"
ref_option = "warn"
ref_option_ref = "warn"
return_self_not_must_use = "warn"
same_functions_in_if_condition = "warn"
semicolon_if_nothing_returned = "warn"
should_panic_without_expect = "warn"
similar_names = "allow" # Too many (subjectively) false positives.
single_char_pattern = "warn"
single_match_else = "warn"
stable_sort_primitive = "warn"
str_split_at_newline = "warn"
string_add_assign = "warn"
struct_excessive_bools = "warn"
struct_field_names = "warn"
too_many_lines = "warn"
transmute_ptr_to_ptr = "warn"
trivially_copy_pass_by_ref = "warn"
unchecked_duration_subtraction = "warn"
unicode_not_nfc = "warn"
uninlined_format_args = "allow" # This is a subjective style choice.
unnecessary_box_returns = "warn"
unnecessary_join = "warn"
unnecessary_literal_bound = "warn"
unnecessary_wraps = "warn"
unnested_or_patterns = "warn"
unreadable_literal = "warn"
unsafe_derive_deserialize = "warn"
unused_async = "warn"
unused_self = "warn"
used_underscore_binding = "warn"
used_underscore_items = "warn"
verbose_bit_mask = "warn"
wildcard_imports = "warn"
zero_sized_map_values = "warn"
4 changes: 2 additions & 2 deletions src/buf_encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl<const CAP: usize> BufEncoder<CAP> {
#[inline]
#[allow(clippy::let_unit_value)] // Allow the unit value of the const check
pub fn new(case: Case) -> Self {
let _ = Self::_CHECK_EVEN_CAPACITY;
let () = Self::_CHECK_EVEN_CAPACITY;
BufEncoder { buf: ArrayString::new(), table: case.table() }
}

Expand Down Expand Up @@ -80,7 +80,7 @@ impl<const CAP: usize> BufEncoder<CAP> {
I: IntoIterator,
I::Item: Borrow<u8>,
{
self.put_bytes_inner(bytes.into_iter())
self.put_bytes_inner(bytes.into_iter());
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub trait DisplayHex: Copy + sealed::IsRef + sealed::Sealed {
// We don't expect `std` to ever be buggy, so the bug is most likely in the `Display`
// impl of `Self::Display`.
panic!("The implementation of Display for {} returned an error when it shouldn't", name)
})
});
}

/// Hints how many bytes to reserve when creating a `String`.
Expand Down
25 changes: 13 additions & 12 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,12 @@ impl From<Infallible> for ToBytesError {

impl fmt::Display for ToBytesError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use ToBytesError::*;
use ToBytesError as E;

match *self {
InvalidChar(ref e) => write_err!(f, "invalid char, failed to create bytes from hex"; e),
OddLengthString(ref e) =>
E::InvalidChar(ref e) =>
write_err!(f, "invalid char, failed to create bytes from hex"; e),
E::OddLengthString(ref e) =>
write_err!(f, "odd length, failed to create bytes from hex"; e),
}
}
Expand All @@ -92,11 +93,11 @@ impl fmt::Display for ToBytesError {
#[cfg(feature = "std")]
impl std::error::Error for ToBytesError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use ToBytesError::*;
use ToBytesError as E;

match *self {
InvalidChar(ref e) => Some(e),
OddLengthString(ref e) => Some(e),
E::InvalidChar(ref e) => Some(e),
E::OddLengthString(ref e) => Some(e),
}
}
}
Expand Down Expand Up @@ -222,23 +223,23 @@ impl From<Infallible> for ToArrayError {

impl fmt::Display for ToArrayError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use ToArrayError::*;
use ToArrayError as E;

match *self {
InvalidChar(ref e) => write_err!(f, "failed to parse hex digit"; e),
InvalidLength(ref e) => write_err!(f, "failed to parse hex"; e),
E::InvalidChar(ref e) => write_err!(f, "failed to parse hex digit"; e),
E::InvalidLength(ref e) => write_err!(f, "failed to parse hex"; e),
}
}
}

#[cfg(feature = "std")]
impl std::error::Error for ToArrayError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
use ToArrayError::*;
use ToArrayError as E;

match *self {
InvalidChar(ref e) => Some(e),
InvalidLength(ref e) => Some(e),
E::InvalidChar(ref e) => Some(e),
E::InvalidLength(ref e) => Some(e),
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,8 @@ mod tests {

#[test]
#[should_panic]
// Don't test panic message because it is from `debug_assert`.
#[allow(clippy::should_panic_without_expect)]
fn hex_to_bytes_slice_drain_panic_empty() {
let hex = "deadbeef";
let iter = HexToBytesIter::new_unchecked(hex);
Expand All @@ -451,6 +453,8 @@ mod tests {

#[test]
#[should_panic]
// Don't test panic message because it is from `debug_assert`.
#[allow(clippy::should_panic_without_expect)]
fn hex_to_bytes_slice_drain_panic_too_small() {
let hex = "deadbeef";
let iter = HexToBytesIter::new_unchecked(hex);
Expand All @@ -460,6 +464,8 @@ mod tests {

#[test]
#[should_panic]
// Don't test panic message because it is from `debug_assert`.
#[allow(clippy::should_panic_without_expect)]
fn hex_to_bytes_slice_drain_panic_too_big() {
let hex = "deadbeef";
let iter = HexToBytesIter::new_unchecked(hex);
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ extern crate alloc;

#[doc(hidden)]
pub mod _export {
/// A re-export of core::*
/// A re-export of `core::*`.
pub mod _core {
pub use core::*;
}
Expand Down Expand Up @@ -171,6 +171,6 @@ mod tests {
fn parse_hex_into_vector() {
let got = hex!("deadbeef");
let want = vec![0xde, 0xad, 0xbe, 0xef];
assert_eq!(got, want)
assert_eq!(got, want);
}
}
2 changes: 1 addition & 1 deletion src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ mod tests {
assert_eq!(
<[u8; 4]>::from_hex(len_sixteen).unwrap_err(),
InvalidLengthError { invalid: 16, expected: 8 }.into()
)
);
}

#[test]
Expand Down
18 changes: 9 additions & 9 deletions src/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ where
T: Serialize + DisplayHex,
{
// Don't do anything special when not human readable.
if !serializer.is_human_readable() {
serde::Serialize::serialize(&data, serializer)
} else {
if serializer.is_human_readable() {
serializer.collect_str(&format_args!("{:x}", data.as_hex()))
} else {
serde::Serialize::serialize(&data, serializer)
}
}

Expand All @@ -76,10 +76,10 @@ where
T: Serialize + DisplayHex,
{
// Don't do anything special when not human readable.
if !serializer.is_human_readable() {
serde::Serialize::serialize(&data, serializer)
} else {
if serializer.is_human_readable() {
serializer.collect_str(&format_args!("{:X}", data.as_hex()))
} else {
serde::Serialize::serialize(&data, serializer)
}
}

Expand Down Expand Up @@ -155,9 +155,9 @@ where
}

// Don't do anything special when not human readable.
if !d.is_human_readable() {
serde::Deserialize::deserialize(d)
} else {
if d.is_human_readable() {
d.deserialize_map(HexVisitor(PhantomData))
} else {
serde::Deserialize::deserialize(d)
}
}

0 comments on commit a05406c

Please sign in to comment.