diff --git a/.github/workflows/TestingCI.yml b/.github/workflows/TestingCI.yml index 88aeee17..a13ce3fd 100644 --- a/.github/workflows/TestingCI.yml +++ b/.github/workflows/TestingCI.yml @@ -11,11 +11,12 @@ jobs: linux-ubuntu: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 - name: Fetch run: cargo fetch + - name: Clippy + run: cargo clippy - name: Build run: cargo build --release --verbose - name: Run tests @@ -42,8 +43,9 @@ jobs: key: registry-${{ runner.os }}-${{ steps.rust-version.outputs.version }}-${{ hashFiles('Cargo.lock') }} - name: Fetch run: cargo fetch + - name: Clippy + run: cargo clippy - name: Build run: cargo build --release --verbose - name: Run tests run: cargo test --release --verbose - diff --git a/Cargo.toml b/Cargo.toml index a9a3ab35..e4c75ef5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,4 +34,49 @@ chrono = { version = "0.4", default-features = false, features = ["clock"] } libc = "0.2" regex = "1.10" gettext-rs = { path = "./gettext-rs" } -errno = "0.3" \ No newline at end of file +errno = "0.3" + +[workspace.lints.clippy] +all = {level = "deny", priority = -1} + +assign_op_pattern = "warn" +bool_comparison = "warn" +clone_on_copy = "warn" +collapsible_else_if = "warn" +collapsible_if = "warn" +comparison_chain = "warn" +derivable_impls = "warn" +derived_hash_with_manual_eq = "warn" +enum_variant_names = "allow" +format_in_format_args = "warn" +if_same_then_else = "warn" +int_plus_one = "warn" +large_enum_variant = "warn" +len_zero = "warn" +let_and_return = "warn" +manual_find = "warn" +manual_flatten = "warn" +manual_map = "warn" +manual_unwrap_or = "warn" +manual_unwrap_or_default = "warn" +match_like_matches_macro = "warn" +needless_lifetimes = "warn" +needless_range_loop = "warn" +new_without_default = "warn" +nonminimal_bool = "warn" +not_unsafe_ptr_arg_deref = "warn" +precedence = "warn" +redundant_field_names = "warn" +redundant_pattern_matching = "allow" +redundant_static_lifetimes = "warn" +result_large_err = "warn" +single_match = "warn" +suspicious_open_options = "warn" +too_many_arguments = "warn" +type_complexity = "warn" +unnecessary_cast = "warn" +unnecessary_filter_map = "warn" +unwrap_or_default = "warn" +upper_case_acronyms = "warn" +while_let_loop = "allow" +wrong_self_convention = "warn" diff --git a/awk/Cargo.toml b/awk/Cargo.toml index b1c57fb7..589fafa2 100644 --- a/awk/Cargo.toml +++ b/awk/Cargo.toml @@ -17,3 +17,6 @@ rand = {version = "0.8", default-features = false, features = ["small_rng"] } [[bin]] name = "awk" path = "src/main.rs" + +[lints] +workspace = true diff --git a/awk/src/interpreter/mod.rs b/awk/src/interpreter/mod.rs index ea5bd2d6..e2da6b1a 100644 --- a/awk/src/interpreter/mod.rs +++ b/awk/src/interpreter/mod.rs @@ -107,7 +107,7 @@ fn maybe_numeric_string>(str: S) -> AwkString { let numeric_string = is_valid_number( str.as_str() .trim() - .trim_start_matches(|c| c == '+' || c == '-'), + .trim_start_matches(['+', '-']), ); str.is_numeric = numeric_string; str diff --git a/calc/Cargo.toml b/calc/Cargo.toml index 5b63d04b..cbf0b6bd 100644 --- a/calc/Cargo.toml +++ b/calc/Cargo.toml @@ -21,3 +21,6 @@ path = "./expr.rs" [[bin]] name = "bc" path = "./bc.rs" + +[lints] +workspace = true diff --git a/calc/expr.rs b/calc/expr.rs index e358eaaf..88499447 100644 --- a/calc/expr.rs +++ b/calc/expr.rs @@ -187,19 +187,21 @@ fn cmpop(lhs: &Token, rhs: &Token, op: CmpOp) -> Result { let lhs_int = token_to_int(lhs); let rhs_int = token_to_int(rhs); - // if both are integers, perform int comparison - if lhs_int.is_some() && rhs_int.is_some() { - Ok(cmpint(lhs_int.unwrap(), rhs_int.unwrap(), op)) - - // otherwise, convert int to string, and perform string compare - } else if let Some(val) = lhs_int { - let tmp = Token::Str(val.to_string()); - cmpstr(&tmp, rhs, op) - } else if let Some(val) = rhs_int { - let tmp = Token::Str(val.to_string()); - cmpstr(lhs, &tmp, op) - } else { - cmpstr(lhs, rhs, op) + match (lhs_int, rhs_int) { + (Some(lhs), Some(rhs)) => { + // if both are integers, perform int comparison + Ok(cmpint(lhs, rhs, op)) + } + // otherwise, convert int to string, and perform string compare + (Some(lh), _) => { + let tmp = Token::Str(lh.to_string()); + cmpstr(&tmp, rhs, op) + } + (_, Some(rh)) => { + let tmp = Token::Str(rh.to_string()); + cmpstr(lhs, &tmp, op) + } + _ => cmpstr(lhs, rhs, op), } } diff --git a/datetime/Cargo.toml b/datetime/Cargo.toml index 4174253d..d3f7ff99 100644 --- a/datetime/Cargo.toml +++ b/datetime/Cargo.toml @@ -28,3 +28,6 @@ path = "./sleep.rs" [[bin]] name = "time" path = "./time.rs" + +[lints] +workspace = true diff --git a/datetime/cal.rs b/datetime/cal.rs index 1d621be8..15962209 100644 --- a/datetime/cal.rs +++ b/datetime/cal.rs @@ -105,7 +105,7 @@ fn main() -> Result<(), Box> { // If only one argument is provided, assume it is the entire year } else if args.month.is_some() && args.year.is_none() { - args.year = args.month.clone(); + args.year = args.month; args.month = None; } diff --git a/datetime/date.rs b/datetime/date.rs index 77287d4f..50be6db6 100644 --- a/datetime/date.rs +++ b/datetime/date.rs @@ -152,10 +152,10 @@ fn main() -> Result<(), Box> { match &args.timestr { None => show_time(args.utc, DEF_TIMESTR), Some(timestr) => { - if timestr.starts_with("+") { - show_time(args.utc, ×tr[1..]); + if let Some(st) = timestr.strip_prefix("+") { + show_time(args.utc, st); } else { - set_time(args.utc, ×tr)?; + set_time(args.utc, timestr)?; } } } diff --git a/dev/Cargo.toml b/dev/Cargo.toml index 0574d5b4..c3ed80c4 100644 --- a/dev/Cargo.toml +++ b/dev/Cargo.toml @@ -30,3 +30,6 @@ path = "./strip.rs" [[bin]] name = "strings" path = "./strings.rs" + +[lints] +workspace = true diff --git a/dev/ar.rs b/dev/ar.rs index ee280aaf..c96eb7a5 100644 --- a/dev/ar.rs +++ b/dev/ar.rs @@ -236,7 +236,7 @@ impl ArchiveMember { writer.write_all(&object::archive::TERMINATOR)?; writer.write_all(&self.data)?; if self.data.len() % 2 != 0 { - writer.write_all(&[b'\n'])?; + writer.write_all(b"\n")?; } Ok(()) diff --git a/display/Cargo.toml b/display/Cargo.toml index 07346ad6..cbc9b0cd 100644 --- a/display/Cargo.toml +++ b/display/Cargo.toml @@ -19,3 +19,5 @@ path = "./echo.rs" name = "printf" path = "./printf.rs" +[lints] +workspace = true diff --git a/display/echo.rs b/display/echo.rs index c458dd0c..24c96176 100644 --- a/display/echo.rs +++ b/display/echo.rs @@ -57,7 +57,7 @@ fn translate_str(skip_nl: bool, s: &str) -> String { output.push('\x11'); } '\\' => { - output.push_str("\\"); + output.push('\\'); } _ => {} } @@ -67,7 +67,7 @@ fn translate_str(skip_nl: bool, s: &str) -> String { } if nl && !skip_nl { - output.push_str("\n"); + output.push('\n'); } output diff --git a/display/printf.rs b/display/printf.rs index 691c9a73..b3c333a2 100644 --- a/display/printf.rs +++ b/display/printf.rs @@ -128,7 +128,7 @@ fn tokenize_format_str(format: &str) -> Vec { } ParseState::Width => { - if c.is_digit(10) { + if c.is_ascii_digit() { width.push(c); done_with_char = true; } else { @@ -150,7 +150,7 @@ fn tokenize_format_str(format: &str) -> Vec { } ParseState::PrecisionValue => { - if c.is_digit(10) { + if c.is_ascii_digit() { precision.push(c); done_with_char = true; } else { diff --git a/file/Cargo.toml b/file/Cargo.toml index 4064439a..349372f7 100644 --- a/file/Cargo.toml +++ b/file/Cargo.toml @@ -47,3 +47,6 @@ path = "./file.rs" [[bin]] name = "find" path = "./find.rs" + +[lints] +workspace = true diff --git a/file/dd.rs b/file/dd.rs index 97a7b70e..39a21a2c 100644 --- a/file/dd.rs +++ b/file/dd.rs @@ -227,18 +227,16 @@ fn apply_conversions(data: &mut Vec, config: &Config) { } fn copy_convert_file(config: &Config) -> Result<(), Box> { - let mut ifile: Box; - if config.ifile == "" { - ifile = Box::new(io::stdin().lock()); + let mut ifile: Box = if config.ifile.is_empty() { + Box::new(io::stdin().lock()) } else { - ifile = Box::new(fs::File::open(&config.ifile)?); - } - let mut ofile: Box; - if config.ofile == "" { - ofile = Box::new(io::stdout().lock()) + Box::new(fs::File::open(&config.ifile)?) + }; + let mut ofile: Box = if config.ofile.is_empty() { + Box::new(io::stdout().lock()) } else { - ofile = Box::new(fs::File::create(&config.ofile)?) - } + Box::new(fs::File::create(&config.ofile)?) + }; let mut ibuf = vec![0u8; config.ibs]; let obuf = vec![0u8; config.obs]; diff --git a/file/file.rs b/file/file.rs index add5c5ab..99f9f649 100644 --- a/file/file.rs +++ b/file/file.rs @@ -156,7 +156,7 @@ impl Value { let re = Regex::new(r"\\([0-7]{1,3})").map_err(|_| RawMagicLineParseError::InvalidRegex)?; let result = re - .replace_all(&input, |capture: ®ex::Captures| { + .replace_all(input, |capture: ®ex::Captures| { let mat = capture.get(1).unwrap().as_str(); let v = u32::from_str_radix(mat, 8).unwrap(); @@ -169,7 +169,7 @@ impl Value { fn parse_number(input: &mut String) -> Option<(ComparisonOperator, u64)> { let regex = Regex::new(r"^[=<>&^x]").unwrap(); - let comparision_op = match regex.find(&input) { + let comparision_op = match regex.find(input) { Some(mat) => { let comp = mat.as_str().chars().next().unwrap(); input.replace_range(..1, ""); // Remove the matched operator @@ -192,6 +192,8 @@ impl Value { } /// Parses Hexadecimal, Octal and Unsigned Decimal +// TODO +#[allow(clippy::needless_match)] fn parse_number(input: &mut String) -> Option { if let Some(hex_num) = parse_hexadecimal(input) { Some(hex_num) @@ -510,6 +512,7 @@ fn parse_magic_file_and_test( } } } else { + // TODO: Empty branch } } diff --git a/file/find.rs b/file/find.rs index b96b190a..973c3158 100644 --- a/file/find.rs +++ b/file/find.rs @@ -149,8 +149,8 @@ fn parse_expression(tokens: &mut Vec<&str>) -> Vec { "-size" => { tokens.pop(); if let Some(size) = tokens.pop() { - let (size, in_bytes) = if size.ends_with('c') { - (size[..size.len() - 1].parse::().unwrap_or(0), true) + let (size, in_bytes) = if let Some(st) = size.strip_suffix('c') { + (st.parse::().unwrap_or(0), true) } else { (size.parse::().unwrap_or(0), false) }; @@ -250,15 +250,15 @@ fn evaluate_expression( match expression { Expr::Not(inner) => { let i: Vec = vec![f_path.clone(), *inner.clone()]; - not_res = evaluate_expression(&i.as_slice(), files.clone(), root_dev)?; + not_res = evaluate_expression(i.as_slice(), files.clone(), root_dev)?; } Expr::Or(inner) => { let i: Vec = vec![f_path.clone(), *inner.clone()]; - or_res = evaluate_expression(&i.as_slice(), files.clone(), root_dev)?; + or_res = evaluate_expression(i.as_slice(), files.clone(), root_dev)?; } Expr::And(inner) => { let i: Vec = vec![f_path.clone(), *inner.clone()]; - and_res = evaluate_expression(&i.as_slice(), files.clone(), root_dev)?; + and_res = evaluate_expression(i.as_slice(), files.clone(), root_dev)?; } _ => {} } @@ -307,7 +307,7 @@ fn evaluate_expression( FileType::Fifo => file_type.is_fifo(), FileType::File => file_type.is_file(), FileType::Socket => file_type.is_socket(), - FileType::Unknown => return Err(format!("Unknown argument to -type")), + FileType::Unknown => return Err("Unknown argument to -type".to_string()), }; if !r { c_files.remove(file.path()); @@ -316,7 +316,7 @@ fn evaluate_expression( Expr::NoUser => { if let Ok(metadata) = file.metadata() { let uid = metadata.uid(); - if !users::get_user_by_uid(uid).is_none() { + if users::get_user_by_uid(uid).is_some() { c_files.remove(file.path()); } } @@ -324,7 +324,7 @@ fn evaluate_expression( Expr::NoGroup => { if let Ok(metadata) = file.metadata() { let gid = metadata.gid(); - if !users::get_group_by_gid(gid).is_none() { + if users::get_group_by_gid(gid).is_some() { c_files.remove(file.path()); } } diff --git a/file/od.rs b/file/od.rs index 9143dbb4..ea0aaae5 100644 --- a/file/od.rs +++ b/file/od.rs @@ -177,14 +177,15 @@ fn parse_skip(offset: &str) -> Result> { let (number, multiplier) = if offset.starts_with("0x") || offset.starts_with("0X") { // For hexadecimal, 'b' should be part of the number if it is the last character (offset, 1) - } else if offset.ends_with('b') { - (&offset[..offset.len() - 1], 512) - } else if offset.ends_with('k') { - (&offset[..offset.len() - 1], 1024) - } else if offset.ends_with('m') { - (&offset[..offset.len() - 1], 1048576) } else { - (offset, 1) + let mut chars = offset.chars(); + + match chars.next_back() { + Some('b') => (chars.as_str(), 512), + Some('k') => (chars.as_str(), 1024), + Some('m') => (chars.as_str(), 1048576), + _ => (offset, 1), + } }; let base_value = parse_count::(number)?; @@ -257,18 +258,24 @@ fn parse_offset(offset: &str) -> Result> { let mut base = 8; let mut multiplier = 1; + let mut chars = offset.chars(); + // Handle special suffixes - let offset = if offset.ends_with('b') { - multiplier = 512; - &offset[..offset.len() - 1] - } else if offset.ends_with('.') { - base = 10; - &offset[..offset.len() - 1] - } else { - offset + let offset_to_use = match chars.next_back() { + Some('b') => { + multiplier = 512; + + chars.as_str() + } + Some('.') => { + base = 10; + + chars.as_str() + } + _ => offset, }; - let parsed_offset = u64::from_str_radix(offset, base)?; + let parsed_offset = u64::from_str_radix(offset_to_use, base)?; Ok(parsed_offset * multiplier) } diff --git a/file/split.rs b/file/split.rs index ab42249c..5be0dad4 100644 --- a/file/split.rs +++ b/file/split.rs @@ -73,7 +73,7 @@ impl OutputState { assert!(self.suffix_len > 1); if self.suffix.is_empty() { - self.suffix = String::from("a".repeat(self.suffix_len as usize)); + self.suffix = "a".repeat(self.suffix_len as usize); return Ok(()); } @@ -140,7 +140,11 @@ impl OutputState { fn write(&mut self, buf: &[u8]) -> io::Result<()> { match &mut self.outf { None => { - assert!(false); + // TODO + #[allow(clippy::assertions_on_constants)] + { + assert!(false); + } Ok(()) } Some(ref mut f) => f.write_all(buf), diff --git a/fs/Cargo.toml b/fs/Cargo.toml index 1a14ad30..6179c43c 100644 --- a/fs/Cargo.toml +++ b/fs/Cargo.toml @@ -16,3 +16,5 @@ libc.workspace = true name = "df" path = "./df.rs" +[lints] +workspace = true diff --git a/fs/df.rs b/fs/df.rs index c280846c..77091e44 100644 --- a/fs/df.rs +++ b/fs/df.rs @@ -132,7 +132,7 @@ fn read_mount_info() -> io::Result { for mount in mounts { let devname = to_cstr(&mount.f_mntfromname); let dirname = to_cstr(&mount.f_mntonname); - info.push(&mount, devname, dirname); + info.push(mount, devname, dirname); } } @@ -244,7 +244,7 @@ fn show_info(args: &Args, info: &MountList) { for mount in &info.mounts { if mount.masked { - show_mount(args, block_size, &mount); + show_mount(args, block_size, mount); } } } diff --git a/ftw/Cargo.toml b/ftw/Cargo.toml index 194c7ee8..f7a16075 100644 --- a/ftw/Cargo.toml +++ b/ftw/Cargo.toml @@ -15,3 +15,6 @@ rand = "0.8.5" [lib] doctest = false + +[lints] +workspace = true diff --git a/ftw/src/lib.rs b/ftw/src/lib.rs index e7871b73..76e2cd39 100644 --- a/ftw/src/lib.rs +++ b/ftw/src/lib.rs @@ -422,7 +422,7 @@ enum ProcessFileResult { } fn process_file( - path_stack: &Vec>, + path_stack: &[Rc<[libc::c_char]>], dir_fd: &FileDescriptor, entry_filename: Rc<[libc::c_char]>, follow_symlinks: bool, @@ -439,7 +439,7 @@ where Ok(md) => md, Err(e) => { err_reporter( - Entry::new(dir_fd, &path_stack, &entry_filename, None), + Entry::new(dir_fd, path_stack, &entry_filename, None), Error::new(e, ErrorKind::Stat), ); return ProcessFileResult::NotProcessed; @@ -490,23 +490,23 @@ where // Is the directory searchable? if entry_metadata.is_executable() { if conserve_fds { - return ProcessFileResult::ProcessedDirectory(NodeOrMetadata::Metadata( + ProcessFileResult::ProcessedDirectory(NodeOrMetadata::Metadata( entry_metadata, - )); + )) } else { match OwnedDir::open_at(dir_fd, entry_filename.as_ptr()) { Ok(new_dir) => { - return ProcessFileResult::ProcessedDirectory( + ProcessFileResult::ProcessedDirectory( NodeOrMetadata::TreeNode(TreeNode { dir: HybridDir::Owned(new_dir), filename: entry_filename, metadata: entry_metadata, - }), - ); + }) + ) } Err(error) => { err_reporter(entry, error); - return ProcessFileResult::NotProcessed; + ProcessFileResult::NotProcessed } } } @@ -515,18 +515,18 @@ where // lowercase for "permission" in the error message so don't use that here. let e = io::Error::from_raw_os_error(libc::EACCES); err_reporter(entry, Error::new(e, ErrorKind::DirNotSearchable)); - return ProcessFileResult::NotProcessed; + ProcessFileResult::NotProcessed } } else { - return ProcessFileResult::ProcessedFile; + ProcessFileResult::ProcessedFile } } Ok(false) => { // `false` means skip the directory - return ProcessFileResult::Skipped; + ProcessFileResult::Skipped } Err(_) => { - return ProcessFileResult::NotProcessed; + ProcessFileResult::NotProcessed } } } @@ -583,7 +583,7 @@ where Err(e) => { if let Some(path_stack) = &path_stack { err_reporter( - Entry::new(&starting_dir, &path_stack, &filename, None), + Entry::new(&starting_dir, path_stack, &filename, None), Error::new(e, ErrorKind::Open), ); } @@ -607,12 +607,12 @@ where /// /// # Arguments /// * `path` - Pathname of the directory. Passing a file to this argument will cause the function to -/// return `false` but will otherwise allow processing the file inside `file_handler` like a normal -/// entry. +/// return `false` but will otherwise allow processing the file inside `file_handler` like a normal +/// entry. /// /// * `file_handler` - Called for each entry in the tree. If the current entry is a directory, its -/// contents will be skipped if `file_handler` returns `false`. The return value of `file_handler` -/// is ignored when the entry is a file. +/// contents will be skipped if `file_handler` returns `false`. The return value of `file_handler` +/// is ignored when the entry is a file. /// /// * `postprocess_dir` - Called when `traverse_directory` is exiting a directory. /// @@ -881,7 +881,7 @@ fn read_link_at( let num_bytes = ret as usize; buf.shrink_to(num_bytes); - return Ok(Rc::from(buf.into_boxed_slice())); + Ok(Rc::from(buf.into_boxed_slice())) } // Build the full path of an entry diff --git a/gettext-rs/Cargo.toml b/gettext-rs/Cargo.toml index a6471994..697ee436 100644 --- a/gettext-rs/Cargo.toml +++ b/gettext-rs/Cargo.toml @@ -4,4 +4,7 @@ version = "0.1.0" edition = "2021" [lib] -name = "gettextrs" \ No newline at end of file +name = "gettextrs" + +[lints] +workspace = true diff --git a/gettext-rs/src/lib.rs b/gettext-rs/src/lib.rs index 78f4fd31..7e7138d3 100644 --- a/gettext-rs/src/lib.rs +++ b/gettext-rs/src/lib.rs @@ -18,7 +18,7 @@ pub fn textdomain>>(domainname: T) -> Result, std::io::E } pub fn gettext>(msgid: T) -> String { - return msgid.into(); + msgid.into() } #[macro_export] diff --git a/i18n/Cargo.toml b/i18n/Cargo.toml index 585e2865..ac1e5ca6 100644 --- a/i18n/Cargo.toml +++ b/i18n/Cargo.toml @@ -16,3 +16,6 @@ byteorder = "1.5.0" [[bin]] name = "gencat" path = "./gencat.rs" + +[lints] +workspace = true diff --git a/i18n/gencat.rs b/i18n/gencat.rs index 4120a072..2151e092 100644 --- a/i18n/gencat.rs +++ b/i18n/gencat.rs @@ -261,25 +261,34 @@ impl MessageCatalog { pub fn new( #[cfg_attr(target_os = "macos", allow(unused_variables))] build_default: bool, ) -> Self { - #[cfg(target_os = "macos")] - let catalog; - - #[cfg(not(target_os = "macos"))] - let mut catalog; - - catalog = MessageCatalog { + let message_catalog = MessageCatalog { cat: Cat { first_set: None, last_set: None, }, }; - #[cfg(not(target_os = "macos"))] - if build_default { - catalog.add_set(NL_SETD, String::from("Default Set")); - } + let message_catalog_to_use: MessageCatalog = { + #[cfg(target_os = "macos")] + { + message_catalog + } + + #[cfg(not(target_os = "macos"))] + { + if build_default { + let mut message_catalog_mut = message_catalog; + + message_catalog_mut.add_set(NL_SETD, String::from("Default Set")); + + message_catalog_mut + } else { + message_catalog + } + } + }; - catalog + message_catalog_to_use } /// Parse the message file and override the catalog file(if it already exists) @@ -411,7 +420,7 @@ impl MessageCatalog { msg }; - catalog.add_msg(¤t_set.as_ref().unwrap(), msg_id, msg); + catalog.add_msg(current_set.as_ref().unwrap(), msg_id, msg); } } @@ -792,10 +801,10 @@ fn main() -> Result<(), Box> { catalog.write_catfile(&mut buffer)?; if catfile_path_str == "-" { - io::stdout().write_all(&buffer.get_ref())?; + io::stdout().write_all(buffer.get_ref())?; } else { let mut file = File::create(&args.catfile)?; - file.write_all(&buffer.get_ref())?; + file.write_all(buffer.get_ref())?; } } Err(err) => { diff --git a/m4/Cargo.toml b/m4/Cargo.toml index 948af33b..8342b5c9 100644 --- a/m4/Cargo.toml +++ b/m4/Cargo.toml @@ -33,3 +33,5 @@ test-log = { version = "0.2", default-features=false, features=["log"]} [build-dependencies] m4-test-manager = { path = "./test-manager" } +[lints] +workspace = true diff --git a/m4/src/lexer.rs b/m4/src/lexer.rs index ea4d7104..ed7768b7 100644 --- a/m4/src/lexer.rs +++ b/m4/src/lexer.rs @@ -1,11 +1,11 @@ -//! REQUIEREMENTS: +//! REQUIREMENTS: //! //! * Because m4 supports streaming input and output, it seems like we should probably support -//! streaming lexing/parsing so that we don't run out of RAM. +//! streaming lexing/parsing so that we don't run out of RAM. //! * For good performance it seems like the lexer should probably take into account the current state of the macro -//! definitions, otherwise potentially any input word not matching builtin macros could be a macro and we will need to re-analyze it in a second phase. Also I think there is the possibility to undefine builtin macros? in which case this is absolutely necessary. This seems relevant for nom https://github.com/rust-bakery/nom/issues/1419 -//! So it seems like a good optimization that once we know a word is not a current macro name, to -//! forget trying to parse the rest of it as a macro. +//! definitions, otherwise potentially any input word not matching builtin macros could be a macro and we will need to re-analyze it in a second phase. Also I think there is the possibility to undefine builtin macros? in which case this is absolutely necessary. This seems relevant for nom https://github.com/rust-bakery/nom/issues/1419 +//! So it seems like a good optimization that once we know a word is not a current macro name, to +//! forget trying to parse the rest of it as a macro. //! * Perhaps this might be useful https://github.com/fflorent/nom_locate/blob/master/README.md //! //! Taking a look at this BSD licensed code diff --git a/m4/src/precedence.rs b/m4/src/precedence.rs index 9e1e03e7..45248fcf 100644 --- a/m4/src/precedence.rs +++ b/m4/src/precedence.rs @@ -151,8 +151,8 @@ where /// * It reads, left-to-right, the first two operators `-a++`. /// * Because the minus takes precedence over the increment it is evaluated immediately `(-a)++`. /// * It then reads the remaining input and evaluates the increment next in order to preserve its -/// position in the expression \ -/// `((-a)++)**b`. +/// position in the expression \ +/// `((-a)++)**b`. pub fn precedence( mut prefix: H1, mut postfix: H2, diff --git a/m4/test-manager/Cargo.toml b/m4/test-manager/Cargo.toml index 73370261..9c081e70 100644 --- a/m4/test-manager/Cargo.toml +++ b/m4/test-manager/Cargo.toml @@ -5,3 +5,6 @@ edition = "2021" [dependencies] clap.workspace = true + +[lints] +workspace = true diff --git a/m4/test-manager/src/main.rs b/m4/test-manager/src/main.rs index 46668371..67a96c51 100644 --- a/m4/test-manager/src/main.rs +++ b/m4/test-manager/src/main.rs @@ -68,7 +68,7 @@ fn update_snapshots(args: &Args, update: &UpdateSnapshots) { return false; } - if let Some(name) = update.test_case_name.as_ref().map(|s| s.as_str()) { + if let Some(name) = update.test_case_name.as_deref() { if name != entry.path().file_stem().unwrap().to_str().unwrap() { return false; } diff --git a/misc/Cargo.toml b/misc/Cargo.toml index e1798d00..ae9c6581 100644 --- a/misc/Cargo.toml +++ b/misc/Cargo.toml @@ -24,3 +24,6 @@ path = "./false.rs" [[bin]] name = "test" path = "./test.rs" + +[lints] +workspace = true diff --git a/pathnames/Cargo.toml b/pathnames/Cargo.toml index 2c42307a..55391bf0 100644 --- a/pathnames/Cargo.toml +++ b/pathnames/Cargo.toml @@ -27,3 +27,6 @@ path = "./pathchk.rs" [[bin]] name = "realpath" path = "./realpath.rs" + +[lints] +workspace = true diff --git a/plib/Cargo.toml b/plib/Cargo.toml index 427c657b..dd7bae01 100644 --- a/plib/Cargo.toml +++ b/plib/Cargo.toml @@ -11,3 +11,6 @@ libc.workspace = true [lib] doctest = false + +[lints] +workspace = true diff --git a/plib/src/io.rs b/plib/src/io.rs index 17199a0b..be7272d8 100644 --- a/plib/src/io.rs +++ b/plib/src/io.rs @@ -13,22 +13,19 @@ use std::path::PathBuf; pub fn input_stream(pathname: &PathBuf, dashed_stdin: bool) -> io::Result> { // open file, or stdin - let file: Box; let path_str = pathname.as_os_str(); - if dashed_stdin && path_str == "-" { - file = Box::new(io::stdin().lock()); - } else if !dashed_stdin && path_str == "" { - file = Box::new(io::stdin().lock()); + let file: Box = if (dashed_stdin && path_str == "-") || (!dashed_stdin && path_str.is_empty()) { + Box::new(io::stdin().lock()) } else { - file = Box::new(fs::File::open(pathname)?); - } + Box::new(fs::File::open(pathname)?) + }; Ok(file) } pub fn input_stream_opt(pathname: &Option) -> io::Result> { match pathname { - Some(path) => input_stream(&path, false), + Some(path) => input_stream(path, false), None => input_stream(&PathBuf::new(), false), } } diff --git a/plib/src/modestr.rs b/plib/src/modestr.rs index 306fd424..11e13dae 100644 --- a/plib/src/modestr.rs +++ b/plib/src/modestr.rs @@ -110,11 +110,8 @@ enum ParseState { } pub fn parse(mode: &str) -> Result { - match u32::from_str_radix(mode, 8) { - Ok(m) => { - return Ok(ChmodMode::Absolute(m)); - } - Err(_) => {} + if let Ok(m) = u32::from_str_radix(mode, 8) { + return Ok(ChmodMode::Absolute(m)); } let mut state = ParseState::Wholist; diff --git a/plib/src/sccsfile.rs b/plib/src/sccsfile.rs index c521da55..d5c916b2 100644 --- a/plib/src/sccsfile.rs +++ b/plib/src/sccsfile.rs @@ -167,8 +167,8 @@ fn parse_deltas(lines: &[&str]) -> Result, &'static str> { comments: String::new(), }); } else if in_delta_section { - if line.starts_with("c ") { - current_comments.push_str(&line[2..]); + if let Some(st) = line.strip_prefix("c ") { + current_comments.push_str(st); current_comments.push('\n'); } else if line.starts_with("e") { if let Some(last_delta) = deltas.last_mut() { diff --git a/process/Cargo.toml b/process/Cargo.toml index b76a93c9..5070ecc0 100644 --- a/process/Cargo.toml +++ b/process/Cargo.toml @@ -39,3 +39,5 @@ path = "./renice.rs" name = "xargs" path = "./xargs.rs" +[lints] +workspace = true diff --git a/process/env.rs b/process/env.rs index 74e3eb88..7cbe24f0 100644 --- a/process/env.rs +++ b/process/env.rs @@ -59,7 +59,7 @@ fn merge_env(new_env: &Vec, clear: bool) -> HashMap { if !clear { for (key, value) in env::vars() { - map.insert(String::from(key), String::from(value)); + map.insert(key, value); } } diff --git a/process/kill.rs b/process/kill.rs index 544fd75c..50e6b825 100644 --- a/process/kill.rs +++ b/process/kill.rs @@ -133,11 +133,10 @@ fn parse_cmdline() -> Result { mode = ConfigMode::List; } else if arg == "--" { in_args = false; - } else if arg.starts_with("-") { - let argstr = &arg[1..]; - let sig_no = match argstr.parse::() { + } else if let Some(st) = arg.strip_prefix("-") { + let sig_no = match st.parse::() { Ok(signo) => signo, - Err(_) => lookup_signum(argstr)?, + Err(_) => lookup_signum(st)?, }; mode = ConfigMode::Signal(sig_no); } else { diff --git a/sccs/Cargo.toml b/sccs/Cargo.toml index 580f090d..2571a48a 100644 --- a/sccs/Cargo.toml +++ b/sccs/Cargo.toml @@ -15,3 +15,5 @@ gettext-rs.workspace = true name = "what" path = "./what.rs" +[lints] +workspace = true diff --git a/sccs/what.rs b/sccs/what.rs index 8586a823..1e9953d7 100644 --- a/sccs/what.rs +++ b/sccs/what.rs @@ -40,7 +40,7 @@ fn process_file(reader: R, single: bool) -> io::Result<()> { } let rest = &line[start + pos + 4..]; if let Some(end) = - rest.find(|c| c == '"' || c == '>' || c == '\n' || c == '\\' || c == '\0') + rest.find(['"', '>', '\n', '\\', '\0']) { println!("@(#){}", &rest[..end]); } else { @@ -62,7 +62,7 @@ fn main() -> io::Result<()> { for file in &args.files { let path = Path::new(file); - if let Ok(file) = File::open(&path) { + if let Ok(file) = File::open(path) { let reader = BufReader::new(file); process_file(reader, args.single)?; } else { diff --git a/screen/Cargo.toml b/screen/Cargo.toml index 0ea765f0..7bedef37 100644 --- a/screen/Cargo.toml +++ b/screen/Cargo.toml @@ -26,3 +26,5 @@ path = "./tabs.rs" name = "tput" path = "./tput.rs" +[lints] +workspace = true diff --git a/screen/stty.rs b/screen/stty.rs index 283f3d88..cb4fef96 100644 --- a/screen/stty.rs +++ b/screen/stty.rs @@ -53,9 +53,9 @@ fn speed_to_str(revspeed: &HashMap, speed: speed_t) -> St } fn ti_baud_str(revspeed: &HashMap, ti: &Termios) -> String { - let ispeed = cfgetispeed(&ti); + let ispeed = cfgetispeed(ti); let ispeed_str = speed_to_str(revspeed, ispeed); - let ospeed = cfgetospeed(&ti); + let ospeed = cfgetospeed(ti); let ospeed_str = speed_to_str(revspeed, ospeed); if ispeed == ospeed { @@ -72,7 +72,7 @@ fn stty_show_short(ti: Termios) -> io::Result<()> { fn build_flagstr(name: &str, flag: tcflag_t, pflg: u32, vset: tcflag_t, mask: tcflag_t) -> String { if (flag & mask) == vset { - format!("{}", name) + name.to_string() } else if (pflg & PNEG) != 0 { format!("-{}", name) } else { @@ -123,7 +123,7 @@ fn flagmap_push( }; } -fn show_flags(name: &str, flags: &Vec) { +fn show_flags(name: &str, flags: &[String]) { println!("{}: {}", name, flags.join(" ")); } @@ -173,7 +173,7 @@ fn stty_show_long(ti: Termios) -> io::Result<()> { } for (name, param) in &tty_params { - flagmap_push(&ti, &mut flagmap, name, ¶m); + flagmap_push(&ti, &mut flagmap, name, param); } for flagname in &flagnames { @@ -187,15 +187,15 @@ fn stty_show_long(ti: Termios) -> io::Result<()> { // display compact, parse-able form stty values fn stty_show_compact(ti: Termios) -> io::Result<()> { - let mut tiv = Vec::new(); - // encode settings as pairs of (String,u64) - tiv.push((String::from("ifl"), ti.c_iflag as u64)); - tiv.push((String::from("ofl"), ti.c_oflag as u64)); - tiv.push((String::from("cfl"), ti.c_cflag as u64)); - tiv.push((String::from("lfl"), ti.c_lflag as u64)); - tiv.push((String::from("isp"), cfgetispeed(&ti) as u64)); - tiv.push((String::from("osp"), cfgetospeed(&ti) as u64)); + let mut tiv = vec![ + (String::from("ifl"), ti.c_iflag as u64), + (String::from("ofl"), ti.c_oflag as u64), + (String::from("cfl"), ti.c_cflag as u64), + (String::from("lfl"), ti.c_lflag as u64), + (String::from("isp"), cfgetispeed(&ti) as u64), + (String::from("osp"), cfgetospeed(&ti) as u64), + ]; // encode control chars as pairs of (String,u64) for (i, cc) in ti.c_cc.iter().enumerate() { @@ -350,9 +350,9 @@ fn set_ti_speed( let speed = speed_res.unwrap(); if is_input { - let _ = cfsetispeed(ti, *speed)?; + cfsetispeed(ti, *speed)?; } else { - let _ = cfsetospeed(ti, *speed)?; + cfsetospeed(ti, *speed)?; } Ok(()) @@ -370,7 +370,7 @@ fn merge_map(ti: &mut Termios, pairmap: &HashMap) -> Result io::Result<()> { // if operand begins with "-", it is a negation let mut negate = false; let operand = { - if operand_raw.starts_with("-") { + if let Some(st) = operand_raw.strip_prefix("-") { negate = true; - &operand_raw[1..] + st } else { - &operand_raw[..] + operand_raw.as_str() } }; diff --git a/screen/tabs.rs b/screen/tabs.rs index 4c81f6fb..d19192f3 100644 --- a/screen/tabs.rs +++ b/screen/tabs.rs @@ -151,7 +151,7 @@ fn parse_cmd_line(args: &Args) -> Result, &'static str> { for stop in tabstops_str.split(',') { tabstops.push( stop.parse() - .expect(gettext("Invalid tabstop value.").as_str()), + .unwrap_or_else(|_| { panic!("{}", gettext("Invalid tabstop value.")) }), ); } } diff --git a/sys/Cargo.toml b/sys/Cargo.toml index 2603b4d3..f2c41bf1 100644 --- a/sys/Cargo.toml +++ b/sys/Cargo.toml @@ -38,3 +38,6 @@ path = "./uname.rs" name = "who" path = "./who.rs" + +[lints] +workspace = true diff --git a/sys/ipcs.rs b/sys/ipcs.rs index de0645f3..6d51283d 100644 --- a/sys/ipcs.rs +++ b/sys/ipcs.rs @@ -245,7 +245,11 @@ fn get_current_date() -> String { } fn display_ipc_status(args: &Args) { - println!("IPC status from {} as of {}", "source", get_current_date()); + // TODO: Add "source" + #[allow(clippy::print_literal)] + { + println!("IPC status from {} as of {}", "source", get_current_date()); + } if args.message_queues { display_message_queues(args); diff --git a/sys/ps.rs b/sys/ps.rs index 6f8b1d7e..bbfa144e 100644 --- a/sys/ps.rs +++ b/sys/ps.rs @@ -31,10 +31,13 @@ fn main() { if args.all { match platform::list_processes() { Ok(processes) => { - println!( - "{:<5} {:<5} {:<5} {:<5} {}", - "PID", "PPID", "UID", "GID", "COMMAND" - ); + #[allow(clippy::print_literal)] + { + println!( + "{:<5} {:<5} {:<5} {:<5} {}", + "PID", "PPID", "UID", "GID", "COMMAND" + ); + } for proc in processes { println!( "{:<5} {:<5} {:<5} {:<5} {}", diff --git a/sys/pslinux.rs b/sys/pslinux.rs index eddbcfbd..6f2b8c03 100644 --- a/sys/pslinux.rs +++ b/sys/pslinux.rs @@ -1,7 +1,7 @@ use std::fs; use std::fs::read_to_string; use std::io::Error; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; pub struct ProcessInfo { pub pid: i32, @@ -27,7 +27,7 @@ pub fn list_processes() -> Result, Error> { Ok(processes) } -fn get_process_info(pid: i32, proc_path: &PathBuf) -> Option { +fn get_process_info(pid: i32, proc_path: &Path) -> Option { let status_path = proc_path.join("status"); let cmdline_path = proc_path.join("cmdline"); let stat_path = proc_path.join("stat"); diff --git a/sys/who.rs b/sys/who.rs index ed69d6c9..faa42337 100644 --- a/sys/who.rs +++ b/sys/who.rs @@ -112,8 +112,8 @@ fn print_fmt_term(entry: &plib::utmpx::Utmpx, line: &str) { fn current_terminal() -> String { let s = plib::curuser::tty(); - if s.starts_with("/dev/") { - s[5..].to_string() + if let Some(st) = s.strip_prefix("/dev/") { + st.to_owned() } else { s } @@ -167,7 +167,7 @@ fn show_utmpx_entries(args: &Args) { let entries = plib::utmpx::load(); for entry in &entries { - print_entry(&args, entry); + print_entry(args, entry); } } @@ -192,7 +192,7 @@ fn main() -> Result<(), Box> { // parse command line arguments; if "who am i", use special args let mut args = { if am_i { - Args::parse_from(&["who", "-m"]) + Args::parse_from(["who", "-m"]) } else { Args::parse() } diff --git a/text/Cargo.toml b/text/Cargo.toml index eb5eb28a..9946d7c6 100644 --- a/text/Cargo.toml +++ b/text/Cargo.toml @@ -102,3 +102,5 @@ path = "./tsort.rs" name = "wc" path = "./wc.rs" +[lints] +workspace = true diff --git a/text/csplit.rs b/text/csplit.rs index bd8ee865..bd77b56f 100644 --- a/text/csplit.rs +++ b/text/csplit.rs @@ -334,18 +334,22 @@ fn csplit_file(args: &Args, ctx: SplitOps, new_files: &mut Vec) -> io::R } } - if split_options.len() == 1 { - split_options.remove(0); - } else if split_options.len() > 1 { - if let Operand::Repeat(repeat) = &mut split_options[1] { - *repeat -= 1; - if *repeat == 0 { - split_options.remove(0); + match split_options.len() { + 1 => { + split_options.remove(0); + } + us if us > 1 => { + if let Operand::Repeat(repeat) = &mut split_options[1] { + *repeat -= 1; + if *repeat == 0 { + split_options.remove(0); + split_options.remove(0); + } + } else { split_options.remove(0); } - } else { - split_options.remove(0); } + _ => {} } } else { if line.is_empty() { diff --git a/text/cut.rs b/text/cut.rs index d28273dd..db20edaa 100644 --- a/text/cut.rs +++ b/text/cut.rs @@ -382,7 +382,7 @@ fn read_range(line: &str) -> Result, String> { let end = if range.len() == 1 { start } else if nums[1].is_empty() { - std::i32::MAX - 1 + i32::MAX - 1 } else { match nums[1].parse::() { Err(err) => return Err(err.to_string()), diff --git a/text/diff.rs b/text/diff.rs index 235e8f58..8ce94d2e 100644 --- a/text/diff.rs +++ b/text/diff.rs @@ -139,16 +139,11 @@ fn check_difference(args: Args) -> io::Result { }; if path1_is_file && path2_is_file { - return FileDiff::file_diff(path1, path2, &format_options, None); + FileDiff::file_diff(path1, path2, &format_options, None) } else if !path1_is_file && !path2_is_file { - return DirDiff::dir_diff( - PathBuf::from(path1), - PathBuf::from(path2), - &format_options, - args.recurse, - ); + DirDiff::dir_diff(path1, path2, &format_options, args.recurse) } else { - return FileDiff::file_dir_diff(path1, path2, &format_options); + FileDiff::file_dir_diff(path1, path2, &format_options) } } @@ -164,5 +159,5 @@ fn main() -> Result> { eprintln!("diff: {}", error); } - return Ok(DiffExitStatus::NotDifferent); + Ok(DiffExitStatus::NotDifferent) } diff --git a/text/diff_util/dir_data.rs b/text/diff_util/dir_data.rs index 6e916293..658d99a1 100755 --- a/text/diff_util/dir_data.rs +++ b/text/diff_util/dir_data.rs @@ -39,6 +39,6 @@ impl DirData { } pub fn path_str(&self) -> &str { - &self.path.to_str().unwrap_or(COULD_NOT_UNWRAP_FILENAME) + self.path.to_str().unwrap_or(COULD_NOT_UNWRAP_FILENAME) } } diff --git a/text/diff_util/dir_diff.rs b/text/diff_util/dir_diff.rs index 4e26b3e0..74ab84f4 100755 --- a/text/diff_util/dir_diff.rs +++ b/text/diff_util/dir_diff.rs @@ -34,11 +34,11 @@ impl<'a> DirDiff<'a> { format_options: &FormatOptions, recursive: bool, ) -> io::Result { - let mut dir1: DirData = DirData::load(PathBuf::from(path1))?; - let mut dir2: DirData = DirData::load(PathBuf::from(path2))?; + let mut dir1: DirData = DirData::load(path1)?; + let mut dir2: DirData = DirData::load(path2)?; - let mut dir_diff = DirDiff::new(&mut dir1, &mut dir2, &format_options, recursive); - return dir_diff.analyze(); + let mut dir_diff = DirDiff::new(&mut dir1, &mut dir2, format_options, recursive); + dir_diff.analyze() } fn analyze(&mut self) -> io::Result { @@ -48,16 +48,15 @@ impl<'a> DirDiff<'a> { let is_file = dir_data .files() .get_key_value(file_name) - .expect( - format!( + .unwrap_or_else(|| { + panic!( "Could not find file in {}", dir_data .path() .to_str() .unwrap_or(COULD_NOT_UNWRAP_FILENAME) ) - .as_str(), - ) + }) .1 .file_type()? .is_file(); @@ -177,13 +176,13 @@ impl<'a> DirDiff<'a> { } else { let (file, dir) = if in_dir1_is_file && !in_dir2_is_file { ( - path1.to_str().unwrap_or(&COULD_NOT_UNWRAP_FILENAME), - path2.to_str().unwrap_or(&COULD_NOT_UNWRAP_FILENAME), + path1.to_str().unwrap_or(COULD_NOT_UNWRAP_FILENAME), + path2.to_str().unwrap_or(COULD_NOT_UNWRAP_FILENAME), ) } else { ( - path2.to_str().unwrap_or(&COULD_NOT_UNWRAP_FILENAME), - path1.to_str().unwrap_or(&COULD_NOT_UNWRAP_FILENAME), + path2.to_str().unwrap_or(COULD_NOT_UNWRAP_FILENAME), + path1.to_str().unwrap_or(COULD_NOT_UNWRAP_FILENAME), ) }; @@ -217,6 +216,6 @@ impl<'a> DirDiff<'a> { } } - return Ok(exit_status); + Ok(exit_status) } } diff --git a/text/diff_util/file_data.rs b/text/diff_util/file_data.rs index 5554b59f..6c2584a9 100755 --- a/text/diff_util/file_data.rs +++ b/text/diff_util/file_data.rs @@ -81,7 +81,7 @@ impl FileData { } } - return COULD_NOT_UNWRAP_FILENAME; + COULD_NOT_UNWRAP_FILENAME } pub fn set_change(&mut self, change: Change, index: usize) { @@ -102,7 +102,7 @@ impl FileData { } } - return false; + false } pub fn change(&self, index: usize) -> &Change { @@ -110,6 +110,6 @@ impl FileData { } pub fn path(&self) -> &str { - self.path.to_str().unwrap_or(&COULD_NOT_UNWRAP_FILENAME) + self.path.to_str().unwrap_or(COULD_NOT_UNWRAP_FILENAME) } } diff --git a/text/diff_util/file_diff.rs b/text/diff_util/file_diff.rs index 3e6e1613..a48bd860 100755 --- a/text/diff_util/file_diff.rs +++ b/text/diff_util/file_diff.rs @@ -61,7 +61,7 @@ impl<'a> FileDiff<'a> { show_if_different: Option, ) -> io::Result { if is_binary(&path1)? || is_binary(&path2)? { - return Self::binary_file_diff(&path1, &path2); + Self::binary_file_diff(&path1, &path2) } else { let mut file1 = FileData::get_file(path1)?; let mut file2 = FileData::get_file(path2)?; @@ -76,7 +76,7 @@ impl<'a> FileDiff<'a> { } } - return diff.print(); + diff.print() } } @@ -89,24 +89,24 @@ impl<'a> FileDiff<'a> { if path1_file_type.is_file() { let path1_file = path1.clone(); - let path1_file = path1_file.file_name().expect(&COULD_NOT_UNWRAP_FILENAME); + let path1_file = path1_file.file_name().expect(COULD_NOT_UNWRAP_FILENAME); let path2 = path2.join(path1_file); if !check_existance(&path2)? { return Ok(DiffExitStatus::Trouble); } - return FileDiff::file_diff(path1, path2, format_options, None); + FileDiff::file_diff(path1, path2, format_options, None) } else { let path2_file = path2.clone(); - let path2_file = path2_file.file_name().expect(&COULD_NOT_UNWRAP_FILENAME); + let path2_file = path2_file.file_name().expect(COULD_NOT_UNWRAP_FILENAME); let path1 = path1.join(path2_file); if !check_existance(&path1)? { return Ok(DiffExitStatus::Trouble); } - return FileDiff::file_diff(path1, path2, format_options, None); + FileDiff::file_diff(path1, path2, format_options, None) } } @@ -152,13 +152,13 @@ impl<'a> FileDiff<'a> { for hunk_index in 0..hunks_count { let hunk = self.hunks.hunk_at_mut(hunk_index); match self.format_options.output_format { - OutputFormat::Debug => hunk.print_debug(&self.file1, &self.file2), + OutputFormat::Debug => hunk.print_debug(self.file1, self.file2), OutputFormat::Default => { - hunk.print_default(&self.file1, &self.file2, hunk_index == hunks_count - 1) + hunk.print_default(self.file1, self.file2, hunk_index == hunks_count - 1) } OutputFormat::EditScript => hunk.print_edit_script( - &self.file1, - &self.file2, + self.file1, + self.file2, hunk_index == hunks_count - 1, ), OutputFormat::Context(_) => { @@ -166,8 +166,8 @@ impl<'a> FileDiff<'a> { return Ok(DiffExitStatus::Trouble); } OutputFormat::ForwardEditScript => hunk.print_forward_edit_script( - &self.file1, - &self.file2, + self.file1, + self.file2, hunk_index == hunks_count - 1, ), OutputFormat::Unified(_) => { @@ -179,9 +179,9 @@ impl<'a> FileDiff<'a> { } if self.are_different() { - return Ok(DiffExitStatus::Different); + Ok(DiffExitStatus::Different) } else { - return Ok(DiffExitStatus::NotDifferent); + Ok(DiffExitStatus::NotDifferent) } } @@ -197,8 +197,8 @@ impl<'a> FileDiff<'a> { let n = self.file1.lines().len(); let m = self.file2.lines().len(); let mut distances = vec![vec![0; m + 1]; n + 1]; - let mut file1_considered_lines = vec![0; 0]; - let mut file2_considered_lines = vec![0; 0]; + let mut file1_considered_lines = Vec::::new(); + let mut file2_considered_lines = Vec::::new(); for i in 0..=n { distances[i][0] = i; @@ -210,7 +210,7 @@ impl<'a> FileDiff<'a> { for i in 1..=n { for j in 1..=m { - let cost = if self.compare_lines(&self.file1.line(i - 1), &self.file2.line(j - 1)) { + let cost = if self.compare_lines(self.file1.line(i - 1), self.file2.line(j - 1)) { if !file1_considered_lines.contains(&i) && !file2_considered_lines.contains(&j) { file1_considered_lines.push(i); @@ -243,7 +243,7 @@ impl<'a> FileDiff<'a> { i -= 1 } else { - if !self.compare_lines(&self.file1.line(i - 1), &self.file2.line(j - 1)) { + if !self.compare_lines(self.file1.line(i - 1), self.file2.line(j - 1)) { self.add_change(Change::Substitute(ChangeData::new(i, j))); } @@ -288,7 +288,7 @@ impl<'a> FileDiff<'a> { .hunks .hunks() .iter() - .filter(|hunk| !Change::is_none(&hunk.kind()) && !Change::is_unchanged(&hunk.kind())) + .filter(|hunk| !Change::is_none(hunk.kind()) && !Change::is_unchanged(hunk.kind())) .map(|hunk| { ( hunk.ln1_start() as i64, @@ -301,7 +301,7 @@ impl<'a> FileDiff<'a> { change_ranges.sort_by_key(|change| (change.1, change.3)); - let mut context_ranges = vec![(usize::MIN, usize::MIN, usize::MIN, usize::MIN); 0]; + let mut context_ranges = Vec::<(usize, usize, usize, usize)>::new(); let f1_max = if self.file1.ends_with_newline() && f1_lines - 1 >= 1 { f1_lines - 1 @@ -335,7 +335,7 @@ impl<'a> FileDiff<'a> { context_ranges.push((ln1s as usize, ln1e as usize, ln2s as usize, ln2e as usize)); } - return context_ranges; + context_ranges } fn order_hunks_by_output_format(&mut self) { @@ -507,7 +507,7 @@ impl<'a> FileDiff<'a> { increase_by_one_if(change.is_substitute(), &mut printed_substitute); let printables = match change { - Change::None => vec![String::new(); 0], + Change::None => Vec::::new(), Change::Unchanged(data) => { vec![format!(" {}", self.file1.line(data.ln1() - 1))] } @@ -563,13 +563,13 @@ impl<'a> FileDiff<'a> { pub fn get_header(file: &FileData, label: &Option) -> String { if let Some(label) = label { - return format!("{}", label); + label.to_string() } else { - return format!( + format!( "{}\t{}", file.path(), system_time_to_rfc2822(file.modified()) - ); + ) } } } diff --git a/text/diff_util/functions.rs b/text/diff_util/functions.rs index 4c6bb708..b7bd2167 100755 --- a/text/diff_util/functions.rs +++ b/text/diff_util/functions.rs @@ -3,7 +3,7 @@ use std::{ fs::File, hash::{DefaultHasher, Hash, Hasher}, io::{self, Read}, - path::PathBuf, + path::{Path, PathBuf}, time::SystemTime, }; @@ -35,7 +35,7 @@ pub fn vec_min(nums: &[usize]) -> usize { } } - return result; + result } pub fn is_binary(file_path: &PathBuf) -> io::Result { @@ -53,11 +53,11 @@ pub fn is_binary(file_path: &PathBuf) -> io::Result { Ok(false) } -pub fn check_existance(path_buf: &PathBuf) -> io::Result { - if path_buf.exists() == false { +pub fn check_existance(path: &Path) -> io::Result { + if path.exists() == false { println!( "diff: {}: No such file or directory", - path_buf.to_str().unwrap_or(COULD_NOT_UNWRAP_FILENAME) + path.to_str().unwrap_or(COULD_NOT_UNWRAP_FILENAME) ); return Ok(false); diff --git a/text/diff_util/hunks.rs b/text/diff_util/hunks.rs index 659a5c53..b81790f4 100755 --- a/text/diff_util/hunks.rs +++ b/text/diff_util/hunks.rs @@ -34,7 +34,7 @@ impl Hunk { let (ln1, ln2) = change.get_lns(); Self { - kind: change.clone(), + kind: change, changes: vec![change; 1], ln1_start: ln1, ln1_end: ln1, @@ -148,7 +148,7 @@ impl Hunk { println!("{}c{}", self.f1_range(), self.f2_range()); - let mut replaced_lines = vec![""; 0]; + let mut replaced_lines = Vec::<&str>::new(); for change in &self.changes { let (new, old) = ( @@ -326,7 +326,7 @@ pub struct Hunks { impl Hunks { pub fn new() -> Self { Self { - hunks: vec![Hunk::new(); 0], + hunks: Vec::::new(), } } diff --git a/text/expand.rs b/text/expand.rs index 36a5fdee..9ae8c901 100644 --- a/text/expand.rs +++ b/text/expand.rs @@ -94,10 +94,10 @@ fn expand_file(tablist: &TabList, pathname: &PathBuf) -> io::Result<()> { if column > 1 { column = column - 1; } - } else if byte == '\r' as u8 || byte == '\n' as u8 { + } else if byte == b'\r' || byte == b'\n' { writer.write_all(&[byte])?; column = 1; - } else if byte != '\t' as u8 { + } else if byte != b'\t' { writer.write_all(&[byte])?; column = column + 1; } else { @@ -142,7 +142,7 @@ fn main() -> Result<(), Box> { let tablist = { if let Some(ref tablist) = args.tablist { - match parse_tablist(&tablist) { + match parse_tablist(tablist) { Ok(tl) => tl, Err(e) => { eprintln!("{}", e); diff --git a/text/fold.rs b/text/fold.rs index fbdb6bf1..a9bcefd3 100644 --- a/text/fold.rs +++ b/text/fold.rs @@ -90,15 +90,15 @@ impl OutputState { } } -fn find_last_blank(v: &Vec) -> Option { +fn find_last_blank(v: &[u8]) -> Option { for (pos, chv) in v.iter().rev().enumerate() { let ch = *chv as char; if ch.is_whitespace() { - return Some(pos as usize); + return Some(pos); } } - return None; + None } fn fold_file(args: &Args, pathname: &PathBuf) -> io::Result<()> { @@ -142,7 +142,7 @@ fn fold_file(args: &Args, pathname: &PathBuf) -> io::Result<()> { let rhs = &state.data[blankpos + 1..]; spill.extend_from_slice(rhs); state.data.truncate(blankpos + 1); - state.push('\n' as u8); + state.push(b'\n'); state.write_line()?; for dchv in &spill { let dch = *dchv as char; @@ -158,7 +158,7 @@ fn fold_file(args: &Args, pathname: &PathBuf) -> io::Result<()> { break; } - state.push('\n' as u8); + state.push(b'\n'); state.write_line()?; } } diff --git a/text/grep.rs b/text/grep.rs index 10c564b7..1ea74812 100644 --- a/text/grep.rs +++ b/text/grep.rs @@ -265,7 +265,7 @@ impl Patterns { // Therefore, an empty pattern is replaced with ".*". #[cfg(target_os = "macos")] { - pattern = if pattern == "" { + pattern = if pattern.is_empty() { String::from(".*") } else { pattern diff --git a/text/nl.rs b/text/nl.rs index 25442122..6da67309 100644 --- a/text/nl.rs +++ b/text/nl.rs @@ -33,7 +33,7 @@ struct Args { /// - n - No line numbering. /// /// - pREGEX - Number only lines that contain the basic regular expression - /// specified in *REGEX*. + /// specified in *REGEX*. #[arg(short = 'b', long, default_value_t = LineNumberingStyle::NonEmpty)] body_numbering: LineNumberingStyle, @@ -112,9 +112,9 @@ impl FromStr for LineNumberingStyle { s => { if let Some(re) = s.strip_prefix('p') { if let Ok(regexp) = Regex::new(re) { - return Ok(LineNumberingStyle::Regex(regexp)); + Ok(LineNumberingStyle::Regex(regexp)) } else { - return Err(format!("invalid regular expression: {re}")); + Err(format!("invalid regular expression: {re}")) } } else { Err(format!("invalid variant: {s}")) @@ -299,7 +299,7 @@ fn nl_main(args: &Args) -> io::Result<()> { line_number = args.starting_line_number; line_number_overflowed = false; } - println!(""); + println!(); } } else { break; diff --git a/text/paste.rs b/text/paste.rs index 44969b77..cf72cbfd 100644 --- a/text/paste.rs +++ b/text/paste.rs @@ -156,7 +156,7 @@ fn paste_files_serial(mut info: PasteInfo, mut dinfo: DelimInfo) -> io::Result<( // if EOF, output line terminator and end inner loop if n_read == 0 { - println!(""); + println!(); break; // output line segment diff --git a/text/pr.rs b/text/pr.rs index a1e009a7..b5378fd6 100644 --- a/text/pr.rs +++ b/text/pr.rs @@ -20,10 +20,10 @@ use std::process::ExitCode; use self::pr_util::{line_transform, Args, PageIterator, Parameters}; -const FORM_FEED: char = 12 as char; +const FORM_FEED: char = 12_u8 as char; const TAB: char = '\t'; -const BACKSPACE: char = 8 as char; -const ALERT: char = 7 as char; +const BACKSPACE: char = 8_u8 as char; +const ALERT: char = 7_u8 as char; const CARRIAGE_RETURN: char = '\r'; const DATE_TIME_FORMAT: &str = "%b %d %H:%M %Y"; @@ -110,7 +110,7 @@ fn print_footer(form_feed_as_page_separator: bool) { if form_feed_as_page_separator { print!("{FORM_FEED}"); } else { - println!(""); + println!(); } } @@ -254,7 +254,7 @@ fn pr_serial(path: &PathBuf, params: &Parameters) -> io::Result<()> { if !params.omit_header { print_header( &dt, - &*path.to_string_lossy(), + &path.to_string_lossy(), page_number, params.header.as_deref(), params.page_width, @@ -343,7 +343,7 @@ fn pr_serial(path: &PathBuf, params: &Parameters) -> io::Result<()> { if !params.omit_header { print_header( &dt, - &*path.to_string_lossy(), + &path.to_string_lossy(), page_number, params.header.as_deref(), params.page_width, diff --git a/text/pr_util/line_iterator.rs b/text/pr_util/line_iterator.rs index 3bdf0eba..f9ef4584 100644 --- a/text/pr_util/line_iterator.rs +++ b/text/pr_util/line_iterator.rs @@ -36,15 +36,15 @@ impl LineBreakIterator { self.buf.clear(); let num_bytes_read = self.reader.read_until(b'\n', &mut self.buf)?; - if self.buf.ends_with(&[b'\n']) { + if self.buf.ends_with(b"\n") { self.buf.pop(); - if self.buf.ends_with(&[b'\r']) { + if self.buf.ends_with(b"\r") { self.buf.pop(); } } - if self.buf.len() == 0 && num_bytes_read > 0 { + if self.buf.is_empty() && num_bytes_read > 0 { self.lines.push_back(Line { line: String::new(), ends_on_form_feed: false, diff --git a/text/uniq.rs b/text/uniq.rs index 68497001..a37a9d89 100644 --- a/text/uniq.rs +++ b/text/uniq.rs @@ -172,6 +172,8 @@ fn process_line(line: &str, fields: Option, chars: Option) -> Stri /// # Errors /// /// Returns an error if there is an issue writing to the output. +// TODO +#[allow(clippy::if_same_then_else)] fn output_result( output: &mut W, line: &str, diff --git a/text/wc.rs b/text/wc.rs index ce023751..d12f4676 100644 --- a/text/wc.rs +++ b/text/wc.rs @@ -102,7 +102,7 @@ fn build_display_str(args: &Args, count: &CountInfo, filename: &OsStr) -> String if multi_file { output.push(' '); - if filename == "" { + if filename.is_empty() { output.push_str("(stdin)"); } else { output.push_str(filename.to_string_lossy().as_ref()); @@ -206,7 +206,7 @@ fn wc_file( wc_file_bytes(count, pathname)?; } - let output = build_display_str(&args, count, pathname.as_os_str()); + let output = build_display_str(args, count, pathname.as_os_str()); println!("{}", output); @@ -260,7 +260,7 @@ fn main() -> Result<(), Box> { } if args.files.len() > 1 { - let output = build_display_str(&args, &totals, &OsStr::new("total")); + let output = build_display_str(&args, &totals, OsStr::new("total")); println!("{}", output); } diff --git a/tree/Cargo.toml b/tree/Cargo.toml index 6b982b2a..56f01dd1 100644 --- a/tree/Cargo.toml +++ b/tree/Cargo.toml @@ -88,3 +88,5 @@ path = "./touch.rs" name = "unlink" path = "./unlink.rs" +[lints] +workspace = true diff --git a/tree/common/mod.rs b/tree/common/mod.rs index 9d4ad7c8..201d3f4d 100644 --- a/tree/common/mod.rs +++ b/tree/common/mod.rs @@ -724,7 +724,7 @@ fn copy_special_file( }; if ret == 0 { created_files.insert(target.to_path_buf()); - return Ok(()); + Ok(()) } else { let e = io::Error::last_os_error(); let err_str = gettext!( @@ -732,7 +732,7 @@ fn copy_special_file( target.display(), error_string(&e) ); - return Err(io::Error::other(err_str)); + Err(io::Error::other(err_str)) } } diff --git a/tree/ls.rs b/tree/ls.rs index f09ec41b..942bbb01 100644 --- a/tree/ls.rs +++ b/tree/ls.rs @@ -752,7 +752,7 @@ fn get_file_names_in_directory_order(directory: &str) -> io::Result io::Result { @@ -924,7 +922,7 @@ fn display_entries(entries: &mut [Entry], config: &Config, dir_path: Option<&str { if col_idx == last_col_idx { entry.print_multi_column(padding); - println!(""); + println!(); } else { entry.print_multi_column(padding); print!("{:COLUMN_SPACING$}", ""); @@ -934,7 +932,7 @@ fn display_entries(entries: &mut [Entry], config: &Config, dir_path: Option<&str // If the last entry does not end up on the bottom right of // the grid if entries.len() % num_columns != 0 { - println!(""); + println!(); } } OutputFormat::StreamOutputFormat => { @@ -1006,7 +1004,7 @@ fn display_entries(entries: &mut [Entry], config: &Config, dir_path: Option<&str for entry in entries.iter() { entry.print_multi_column(padding); - println!(""); + println!(); } } } diff --git a/tree/ls_util/entry.rs b/tree/ls_util/entry.rs index ceab7e2c..8619c333 100644 --- a/tree/ls_util/entry.rs +++ b/tree/ls_util/entry.rs @@ -421,7 +421,7 @@ impl Entry { match self_sorting_key.0.cmp(&other_sorting_key.0) { Ordering::Equal => { match self_sorting_key.1.cmp(&other_sorting_key.1) { - Ordering::Equal => self_sorting_key.2.cmp(&other_sorting_key.2), + Ordering::Equal => self_sorting_key.2.cmp(other_sorting_key.2), r => r.reverse(), // Default is from largest file size to smallest } } diff --git a/tree/mv.rs b/tree/mv.rs index 7eee4642..d571dd8d 100644 --- a/tree/mv.rs +++ b/tree/mv.rs @@ -106,7 +106,7 @@ fn move_file( source: &Path, target: &Path, inode_map: &mut HashMap<(u64, u64), (ftw::FileDescriptor, CString)>, - mut created_files: Option<&mut HashSet>, + created_files: Option<&mut HashSet>, ) -> io::Result { let source_filename = CString::new(source.as_os_str().as_bytes()).unwrap(); let target_filename = CString::new(target.as_os_str().as_bytes()).unwrap(); @@ -292,7 +292,7 @@ fn move_file( .map_err(err_inter_device)?; } - let created_files = match created_files.as_deref_mut() { + let created_files = match created_files { Some(set) => set, None => &mut HashSet::new(), }; diff --git a/tree/rm.rs b/tree/rm.rs index b3c8dfb5..5c7b6934 100644 --- a/tree/rm.rs +++ b/tree/rm.rs @@ -255,7 +255,7 @@ fn rm_directory(cfg: &RmConfig, filepath: &Path) -> io::Result { } // Also forbidden to `rm` the root directory - if let Ok(abspath) = fs::canonicalize(&filepath) { + if let Ok(abspath) = fs::canonicalize(filepath) { if abspath.as_os_str() == "/" { // If the arg is verbatim "/" let err_str = if filepath.as_os_str() == "/" { @@ -276,7 +276,7 @@ fn rm_directory(cfg: &RmConfig, filepath: &Path) -> io::Result { let md = entry.metadata().unwrap(); if md.file_type() == ftw::FileType::Directory { - match process_directory(cfg, &entry, &md) { + match process_directory(cfg, &entry, md) { Ok(dir_action) => match dir_action { DirAction::Entered => Ok(true), DirAction::Removed | DirAction::Skipped => Ok(false), @@ -287,7 +287,7 @@ fn rm_directory(cfg: &RmConfig, filepath: &Path) -> io::Result { } } } else { - if should_remove_file(cfg, &md, || entry.path().clean_trailing_slashes()) { + if should_remove_file(cfg, md, || entry.path().clean_trailing_slashes()) { // Remove the file let ret = unsafe { libc::unlinkat(entry.dir_fd(), entry.file_name().as_ptr(), 0) }; @@ -412,7 +412,7 @@ fn rm_file(cfg: &RmConfig, filepath: &Path) -> io::Result { } fn rm_path(cfg: &RmConfig, filepath: &Path) -> io::Result { - let metadata = match fs::symlink_metadata(&filepath) { + let metadata = match fs::symlink_metadata(filepath) { Ok(md) => md, Err(e) => { // Not an error with -f in the case of operands that do not exist diff --git a/tree/touch.rs b/tree/touch.rs index 2ee366c9..e5e6a797 100644 --- a/tree/touch.rs +++ b/tree/touch.rs @@ -87,7 +87,7 @@ fn parse_tm_posix(time: &str) -> Result, Box { - let mut yearling = *&time[0..2].parse::()?; + let mut yearling = time[0..2].parse::()?; if yearling <= 68 { yearling += 2000; } else { diff --git a/users/Cargo.toml b/users/Cargo.toml index 9979e21e..6c53929d 100644 --- a/users/Cargo.toml +++ b/users/Cargo.toml @@ -43,3 +43,5 @@ path = "./tty.rs" name = "write" path = "./write.rs" +[lints] +workspace = true diff --git a/xform/Cargo.toml b/xform/Cargo.toml index 90470baa..0ddb30fc 100644 --- a/xform/Cargo.toml +++ b/xform/Cargo.toml @@ -32,3 +32,6 @@ path = "./uudecode.rs" [[bin]] name = "uuencode" path = "./uuencode.rs" + +[lints] +workspace = true diff --git a/xform/compress.rs b/xform/compress.rs index 65bd6bf7..5c1aa07c 100644 --- a/xform/compress.rs +++ b/xform/compress.rs @@ -89,10 +89,10 @@ fn compress_file(args: &Args, pathname: &PathBuf) -> io::Result { } let mut new_file = pathname.clone(); - new_file.set_file_name(format!("{fname}")); + new_file.set_file_name(&fname); let mut f = File::create(&new_file)?; - fs::remove_file(&pathname)?; + fs::remove_file(pathname)?; f.write_all(&out_buf)?; if args.verbose { diff --git a/xform/uudecode.rs b/xform/uudecode.rs index 694afede..f2bcebcc 100644 --- a/xform/uudecode.rs +++ b/xform/uudecode.rs @@ -96,7 +96,7 @@ fn decode_historical_line(line: &str) -> Vec { fn decode_base64_line(line: &str) -> io::Result> { BASE64_STANDARD - .decode(&line) + .decode(line) .map_err(|_| Error::from(io::ErrorKind::InvalidInput)) } @@ -142,7 +142,7 @@ fn decode_file(args: &Args) -> io::Result<()> { } DecodingType::Base64 => { - while let Some(line) = lines.next() { + for line in lines { if line == "====" || line == "====\n" { break; } @@ -157,10 +157,10 @@ fn decode_file(args: &Args) -> io::Result<()> { io::stdout().write_all(&out)?; } else { if out_path.exists() { - remove_file(&out_path)?; + remove_file(out_path)?; } - let mut o_file = File::create(&out_path)?; + let mut o_file = File::create(out_path)?; let mut o_file_perm = o_file.metadata()?.permissions(); let o_file_perm_mode = o_file_perm.mode(); let new_o_file_perm_mode = ((o_file_perm_mode >> 9) << 9) | header.lower_perm_bits; diff --git a/xform/uuencode.rs b/xform/uuencode.rs index de97e6fa..c960215b 100644 --- a/xform/uuencode.rs +++ b/xform/uuencode.rs @@ -65,7 +65,7 @@ fn get_permission_values(perm: Permissions) -> String { } fn encode_base64_line(line: &[u8]) -> Vec { - let mut out = BASE64_STANDARD.encode(&line).as_bytes().to_vec(); + let mut out = BASE64_STANDARD.encode(line).as_bytes().to_vec(); out.push(b'\n'); out }