22name = " patchy-bin"
33version = " 1.3.0"
44edition = " 2024"
5- license = " MIT"
5+ license = " MIT OR Apache-2.0 "
66readme = " ./docs/README.md"
77keywords = [" git" , " github" , " fork" , " patchy" ]
88categories = [" development-tools" , " command-line-utilities" ]
@@ -58,12 +58,24 @@ inherits = "release"
5858codegen-units = 1
5959lto = " fat"
6060
61+ # ### lints ####
62+
63+ [lints .rustdoc ]
64+ # it is usually sufficient to include the README
65+ missing_crate_level_docs = " warn"
66+ unescaped_backticks = " warn"
67+
6168[lints .clippy ]
62- # enable all lints (other than restriction: https://rust-lang.github.io/rust-clippy/master/index.html?groups=restriction#blanket_clippy_restriction_lints), then selectively disable
69+ # enable all lints but:
70+ # - selectively *enable* rules from `restriction`
71+ # - selectively *disable* other rules that are annoying
72+
6373pedantic = { priority = -1 , level = " warn" }
6474nursery = { priority = -1 , level = " warn" }
6575cargo = { priority = -1 , level = " warn" }
6676
77+ # # ENABLED
78+
6779# Rust Analyzer's "fill match arms" code action is bugged and will not use "Self",
6880# so temporarily turn it off until that issue gets resolved
6981use_self = " allow"
@@ -78,84 +90,111 @@ missing_const_for_fn = "allow"
7890# we're not a crate: documenting all errors is not necessary
7991missing_errors_doc = " allow"
8092# placing an arbitrary limit on how many lines we can have is unnecessary
93+ # if we have a function that's 300 lines long we should probably split it, right?
94+ # but what if there's not really a good place to split it. Placing a piece of code
95+ # into a function creates an extra abstraction. Each abstraction has a mental cost.
8196too_many_lines = " allow"
8297# it can't detect if the code has a condition to stop the iterator
8398maybe_infinite_iter = " allow"
8499
100+ # # DISABLED
101+
85102# === Restrictions ===
86103# == safety ==
87104
88- # Each ' unsafe' block should always contain exactly 1 unsafe operation
89- # with clear documentation why the invariants are upheld.
90- undocumented_unsafe_blocks = " deny "
91- unnecessary_safety_comment = " deny "
92- unnecessary_safety_doc = " deny "
93- multiple_unsafe_ops_per_block = " deny "
94- # not specifying representation may cause undefined behaviour
95- default_union_representation = " deny "
105+ # unsafe blocks need to have their invariants upheld
106+ undocumented_unsafe_blocks = " warn "
107+ unnecessary_safety_comment = " warn "
108+ unnecessary_safety_doc = " warn "
109+ # each `unsafe` block must just have 1 unsafe operation
110+ multiple_unsafe_ops_per_block = " warn "
111+ # not specifying representation may cause UB
112+ default_union_representation = " warn "
96113
97114# == correctness ==
98115# Program may behave unexpectedly
99116
100- create_dir = " deny"
101- filetype_is_file = " deny"
117+ # usually creating a directory including all of its parents is the desired behaviour
118+ create_dir = " warn"
119+ # is_file doesn't cover special file types nor symlinks
120+ filetype_is_file = " warn"
102121# may cause memory leaks
103- mem_forget = " deny"
104- assertions_on_result_states = " deny"
122+ mem_forget = " warn"
123+ # removes valuable information
124+ assertions_on_result_states = " warn"
105125# The conversion might include a dangerous cast that might go undetected due to the type being inferred.
106- as_pointer_underscore = " deny"
107- as_underscore = " deny"
126+ as_pointer_underscore = " warn"
127+ # its better to be specific
128+ as_underscore = " warn"
108129# bloats the binary size with unneeded files
109- doc_include_without_cfg = " deny "
130+ doc_include_without_cfg = " warn "
110131# casting a function to a pointer is likely a mistake
111- fn_to_numeric_cast_any = " deny "
112- # integer division discards the remainder and is likely a mistake
113- integer_division = " deny "
114- lossy_float_literal = " deny "
115- wildcard_enum_match_arm = " deny "
132+ fn_to_numeric_cast_any = " warn "
133+ # "exact" float value that cannot be represented
134+ lossy_float_literal = " warn "
135+ # new enum variants added by the library updates can be missed
136+ wildcard_enum_match_arm = " warn "
116137
117138# == performance ==
118139
119- # .to_string() is problematic because it does through the whole Display pipeline
120- str_to_string = " warn"
140+ # type information is valuable, lets not lose it
121141non_zero_suggestions = " warn"
122142mutex_atomic = " warn"
123143rc_mutex = " warn"
124144rc_buffer = " warn"
125145# prefer using pattern matching
126146string_lit_chars_any = " warn"
127- missing_asserts_for_indexing = " warn"
128- pathbuf_init_then_push = " warn"
129147
130- # == readabilty ==
148+ # == readability ==
131149
150+ # functional path composition is nice
151+ pathbuf_init_then_push = " warn"
152+ # must use e.g. 123_i32 instead of 123i32
132153unseparated_literal_suffix = " warn"
154+ # Foo { a: _, b, c: _ } => Foo { b, .. }
133155unneeded_field_pattern = " warn"
156+ # use std::io::{self} => use std::io
134157unnecessary_self_imports = " warn"
158+ # Err(x)? => return Err(x)
135159try_err = " warn"
160+ # (0..3).map(|_| x) => iter::repeat(x).take(3)
136161map_with_unused_argument_over_ranges = " warn"
137162# better be explicit with .clone()
138163string_to_string = " warn"
139164# no need to be extra verbose, and makes code easier to modify as well
140165redundant_type_annotations = " warn"
141166# having multiple layout styles can be confusing
167+ # I prefer mod.rs because the whole module is encapsulated in 1 directory
168+ # instead of a my_module/ and a my_module.rs, which is 1 file + 1 directory
169+ # always use: mod.rs
142170self_named_module_files = " warn"
143171# having an explicit, even if just containing a comment,
144172# "else" branch improves readability
145173else_if_without_else = " warn"
146174# explicit annotation of ! for functions that never return
147175# due to having infinite loops
148176infinite_loop = " warn"
149- semicolon_outside_block = " warn"
177+ # for consistency: { x }; => { x; }
178+ semicolon_inside_block = " warn"
179+ # idiomatic to put tests into #[cfg(test)]
150180tests_outside_test_module = " warn"
181+ # #[allow] => #[expect]
151182allow_attributes = " warn"
183+ # always must specify a reason why we're opting out of a lint
152184allow_attributes_without_reason = " warn"
185+ # do not use raw strings if we don't have to
153186needless_raw_strings = " warn"
187+ # makes for confusing code
154188mixed_read_write_in_expression = " warn"
189+ # when panicking its important to know what happened and why,
190+ # and a helpful message helps a LOT with that.
155191missing_assert_message = " warn"
192+ # using index [] is more clear and concise
156193get_unwrap = " warn"
157194if_then_some_else_none = " warn"
195+ # turbofish ::<> can't be used to specify the type of an impl Trait parameter
158196impl_trait_in_params = " warn"
197+ # throws away the error
159198map_err_ignore = " warn"
160199# explicit imports
161200alloc_instead_of_core = " warn"
@@ -165,18 +204,34 @@ cfg_not_test = "warn"
165204# we instantly might think "expensive". But cloning a pointer isn't. It's
166205# good to be explicit
167206clone_on_ref_ptr = " warn"
207+ # more readable to use hex literals sometimes
168208decimal_literal_representation = " warn"
209+ # instead use: Infallible {} => !
210+ empty_enum = " warn"
211+ # enum A { B(), C } => enum A { B, C }
169212empty_enum_variants_with_brackets = " warn"
213+ # struct A() => struct A
170214empty_structs_with_brackets = " warn"
215+ # having error types named Error can be confusing
171216error_impl_error = " warn"
217+ # use x86_intel instead
172218inline_asm_x86_att_syntax = " warn"
219+ # splitting the implementation for a type makes code harder to navigate
173220multiple_inherent_impl = " warn"
221+ # pub(in super) => pub(super)
174222pub_without_shorthand = " warn"
223+ # use the same name as the trait method's default names when implement the trait
175224renamed_function_params = " warn"
225+ # unnecessary pattern binding can be confusing
226+ # example: A { a, .. } => A { a } where A = struct A { a: usize }
176227rest_pat_in_fully_bound_structs = " warn"
177228# same name from a trait and one not from a trait can be confusing
178229same_name_method = " warn"
179230# more explicit and avoids polluting the scope
231+ # example: use std::io::Write => use std::io::Write as _ if Write only used for its methods
180232unused_trait_names = " warn"
233+ # simpler and more obvious deref:
234+ # example: &vec[..] => &*vec
181235deref_by_slicing = " warn"
236+ # use fs::read instead of intermediate values
182237verbose_file_reads = " warn"
0 commit comments