Compare commits

...

18 Commits

Author SHA1 Message Date
Lynne Megido a570b07672
release v0.7.1 🥳 2024-01-21 17:04:58 +10:00
Lynne Megido 10c6512231
REALLY update gitlab CI 2023-03-15 09:59:12 +10:00
Lynne Megido c048d21935
update gitlab CI MSRV 2023-03-15 09:17:51 +10:00
Lynne Megido 4565487149
release v0.7.0 🥳 2023-03-15 06:53:05 +10:00
Lynne Megido 5017854dd3
clippy, format 2023-03-15 06:51:29 +10:00
Lynne Megido 4469104ac1
update changelog 2023-03-15 06:46:09 +10:00
Lynne Megido 7e03dd7cf7
fix value parsing, bump MSRV 2023-03-15 06:42:44 +10:00
Lynne Megido 61196df626
update clap to 4.1 2023-03-15 06:23:59 +10:00
Lynne Megido 9e592863f1
update dependencies 2023-03-15 06:12:38 +10:00
Lynne Megido 62a630249c
update dependencies 2023-01-02 07:36:11 +10:00
Lynne Megido 57fbbc23be visual studio code 2022-09-19 01:59:48 +10:00
Lynne Megido 476209b82e
release v0.6.0 🥳 2022-09-04 13:52:37 +10:00
Lynne Megido acd33980e9
clippy cleanup 2022-09-04 13:48:54 +10:00
Lynne Megido 420bd0483c
update all dependencies, remove deprecated code 2022-09-04 13:41:41 +10:00
Lynne Megido 866a8d41d5
implement Eq where possible 2022-09-04 12:55:30 +10:00
Lynne Megido 74098ed281
update and fix dependencies 2022-09-04 12:47:17 +10:00
Lynne Megido c15d92eaa6
update deps 2022-05-20 07:18:57 +10:00
Lynne Megido b19a508020
fix changelog 2022-05-05 09:45:44 +10:00
15 changed files with 539 additions and 446 deletions

1
.gitignore vendored
View File

@ -21,3 +21,4 @@ cargo-timing*.html
*.sync-conflict*
.idea/sonarlint
.directory
*.tmp

View File

@ -105,7 +105,7 @@ build-base-stable:
build-base-msrv:
extends: build-base-stable
image: "rust:1.54.0"
image: "rust:1.64.0"
cache:
key: msrv
paths:
@ -131,7 +131,7 @@ build-stable:
build-msrv:
extends: build-stable
needs: ["build-base-msrv"]
image: "rust:1.54.0"
image: "rust:1.64.0"
cache:
key: msrv
paths:
@ -156,7 +156,7 @@ test-stable:
test-msrv:
extends: test-stable
image: "rust:1.54.0"
image: "rust:1.64.0"
needs: ["build-msrv"]
cache:
key: msrv

64
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,64 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in library 'fif'",
"cargo": {
"args": [
"test",
"--no-run",
"--lib",
"--package=fif"
],
"filter": {
"name": "fif",
"kind": "lib"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'fif'",
"cargo": {
"args": [
"build",
"--bin=fif",
"--package=fif"
],
"filter": {
"name": "fif",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'fif'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=fif",
"--package=fif"
],
"filter": {
"name": "fif",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}

View File

@ -4,7 +4,25 @@ Dates are given in YYYY-MM-DD format - for example, the 15th of October 2021 is
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
## v0.7.1 - 2024-01-24
### Changed
- Updated and pinned dependencies, using the latest MSRV-compatible versions available.
## v0.7.0 - 2023-03-15
### Changed
- The Minimum Supported Rust Version (MSRV) is now **1.64.0**.
- Update [`clap`] to v4.0
- Update [`infer`] to v0.13.0, bringing support for formats such as [CPIO](https://en.wikipedia.org/wiki/Cpio) and
[OpenRaster](https://www.openraster.org/index.html)
## v0.6.0 - 2022-09-04
### Changed
- The Minimum Supported Rust Version (MSRV) is now **1.57.0**.
- Update [`clap`] to v3.2.0
- Update [`smartstring`] to v1.0 - this should (slightly) improve performance on 32-bit big endian architectures
such as PowerPC
## v0.5.2 - 2022-05-02
### Added
- Output now contains a reminder to use `fif --fix`
### Changed
@ -26,7 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
## v0.5.0 - 2022-01-01
### Changed
- The Minimum Supported Rust Version (MSRV) is now **1.54.0**.
- The Minimum Supported Rust Version (MSRV) is now **1.57.0**.
- Updated [`new_mime_guess`] to 4.0.0
- `--version` output now handles missing Git commit hashes, and specifies the target operating system
### Fixed

721
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,11 @@
[package]
name = "fif"
description = "A command-line tool for detecting and optionally correcting files with incorrect extensions."
version = "0.5.2"
version = "0.7.1"
authors = ["Lynnesbian <lynne@bune.city>"]
edition = "2018"
edition = "2021"
license = "GPL-3.0-or-later"
rust-version = "1.54.0" # clap 3 requires >=1.54.0
rust-version = "1.64.0" # clap 4.1 requires >=1.64.0
repository = "https://gitlab.com/Lynnesbian/fif"
readme = "README.md"
keywords = ["mime", "mimetype", "utilities", "tools"]
@ -23,57 +23,46 @@ xdg-mime-backend = ["xdg-mime"]
json = ["serde", "serde_json"]
[dependencies]
walkdir = "~2.3.2"
walkdir = "2.4.0"
log = "0.4.14"
mime = "0.3.16"
mime_guess = { package = "new_mime_guess", features = ["phf-map"], version = "4.0.0" }
mime_guess = { package = "new_mime_guess", version = "4.0.0" }
snailquote = "0.3.0"
once_cell = "1.8.0"
rayon = { version = "1.5.0", optional = true }
exitcode = "1.1.2"
cfg-if = "1.0.0"
itertools = "0.10.0"
itertools = "0.12.0"
serde = { version = "1.0", features = ["derive"], optional = true }
serde_json = { version = "1.0", optional = true }
num_cpus = { version = "1.13.0", optional = true }
maplit = "1.0.2"
parking_lot = "0.12.0"
smartstring = "1"
maplit = "1.0.2"
[target.'cfg(not(unix))'.dependencies]
xdg-mime = { version = "0.3.3", optional = true }
infer = "0.7.0"
infer = "=0.13.0" # 0.14.0 uses `let else`, which requires rust 1.65
[target.'cfg(unix)'.dependencies]
xdg-mime = "0.3.3"
infer = { version = "0.7.0", optional = true }
[target.'cfg(not(all(target_endian = "big", target_pointer_width = "32")))'.dependencies]
# the seemingly weird target constraint here is due to this:
# https://github.com/bodil/smartstring/blob/v0.2.9/src/config.rs#L91-L93
# essentially, smartstring is intentionally blocked from compiling on 32-bit big endian archs, so our dependency on it
# needs to be too. otherwise, fif won't work on platforms like powerpc, even though this dependency is the only
# blocker -- fif runs just fine on powerpc (or on my powerbook G4, anyway) without smartstring.
# additionally, versions before 0.2.4 didn't impl Display, so we need at least that version for displaying Strings.
# version 1.0 of smartstring adds 32-bit BE compatibility (by rewriting the implementation), but requires rust 1.57.0,
# so we can't use it.
smartstring = ">= 0.2.4, <=0.2.9"
infer = { version = "=0.13.0", optional = true }
[dependencies.clap]
version = "3.1.0"
version = "~4.1"
default-features = false
features = ["wrap_help", "color", "derive", "std", "unicode"]
[dependencies.env_logger]
version = "0.9.0"
version = "0.10.0"
default-features = false
features = ["termcolor", "atty"]
features = ["color"]
[dev-dependencies]
tempfile = "3.2.0"
rand = "0.8.3"
assert_cmd = "2.0.2"
regex = { version = "1.5.4", default-features = false, features = ["std"] }
assert_cmd = "=2.0.5" # higher versions than this have dependencies that require later rust versions
regex = { version = "=1.9.5", default-features = false, features = ["std"] } # 1.9.6 requires rust 1.65
[profile.release]
lto = "thin"
@ -86,4 +75,4 @@ opt-level = 3
opt-level = 3
[package.metadata]
msrv = "1.54.0"
msrv = "1.64.0"

View File

@ -7,7 +7,7 @@
[![Version](https://img.shields.io/crates/v/fif.svg?logo=rust&style=flat-square)
](https://crates.io/crates/fif)
[![Minimum Supported Rust Version](https://img.shields.io/badge/msrv-1.54.0-orange?logo=rust&style=flat-square)
[![Minimum Supported Rust Version](https://img.shields.io/badge/msrv-1.57.0-orange?logo=rust&style=flat-square)
](https://gitlab.com/Lynnesbian/fif/-/blob/master/README.md#version-policy)
[![License](https://img.shields.io/crates/l/fif.svg?style=flat-square)
](https://gitlab.com/Lynnesbian/fif/-/blob/master/LICENSE)

View File

@ -14,9 +14,9 @@ fn main() -> Result<(), String> {
// a more robust way of doing this would be to use vergen (https://github.com/rustyhorde/vergen), but it pulls in a
// whole bunch of extra dependencies (including chrono and git2), and also blocks compilation on the current MSRV.
// this method is less clever and robust, but it works!
let git = Command::new("git").args(&["rev-parse", "--short", "HEAD"]).output();
let git = Command::new("git").args(["rev-parse", "--short", "HEAD"]).output();
let hash = match git {
Ok(output) => String::from_utf8_lossy(&*output.stdout).into(),
Ok(output) => String::from_utf8_lossy(&output.stdout).into(),
Err(_) => {
// git not being present (or failing) shouldn't block compilation
println!("cargo:warning=Failed to retrieve git commit hash");

View File

@ -1,3 +1,3 @@
# avoid-breaking-exported-api = false # only available on nightly for now
cognitive-complexity-threshold = 15
msrv = "1.54.0"
msrv = "1.64.0"

View File

@ -317,7 +317,7 @@ pub fn mime_type<T: MimeDb>(db: &T, path: &Path) -> io::Result<Option<Mime>> {
// attempt to read up to BUF_SIZE bytes of the file.
let mut buffer = [0; BUF_SIZE];
file.seek(SeekFrom::Start(0))?;
file.read(&mut buffer)?;
_ = file.read(&mut buffer)?;
Ok(db.get_type(&buffer))
}

View File

@ -31,7 +31,6 @@ use crate::String;
/// // ...just use:
/// smart_write(&mut f, writables!["hello", Newline]);
/// ```
#[macro_export]
macro_rules! writables {
[$($args:tt),+] => {
@ -55,7 +54,7 @@ macro_rules! writablesln {
};
}
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Eq)]
pub enum Writable<'a> {
String(&'a str),
Path(&'a Path),
@ -90,7 +89,7 @@ pub fn smart_write<W: Write>(f: &mut W, writeables: &[Writable]) -> io::Result<(
}
}
}
Writable::String(s) => write!(f, "{}", s)?,
Writable::String(s) => write!(f, "{s}")?,
Writable::Path(path) => {
if let Some(path_str) = path.to_str() {
let escaped = escape(path_str);
@ -98,9 +97,9 @@ pub fn smart_write<W: Write>(f: &mut W, writeables: &[Writable]) -> io::Result<(
// the escaped string is the same as the input - this will occur for inputs like "file.txt" which don't
// need to be escaped. however, it's Best Practice™ to escape such strings anyway, so we prefix/suffix the
// escaped string with single quotes.
write!(f, "'{}'", escaped)?;
write!(f, "'{escaped}'")?;
} else {
write!(f, "{}", escaped)?;
write!(f, "{escaped}")?;
}
} else {
write!(f, "'")?;
@ -111,7 +110,7 @@ pub fn smart_write<W: Write>(f: &mut W, writeables: &[Writable]) -> io::Result<(
// f.write_all(&*path.as_os_str().encode_wide().collect::<Vec<u16>>())?;
write!(f, "{}", path.as_os_str().to_string_lossy())?;
} else {
f.write_all(&*path.as_os_str().as_bytes())?;
f.write_all(path.as_os_str().as_bytes())?;
}
}
write!(f, "'")?;

View File

@ -132,7 +132,7 @@ fn main() {
if args.fix {
fn ask(message: &str) -> bool {
let mut buf = String::with_capacity(1);
print!("{} [y/N] ", message);
print!("{message} [y/N] ");
// flush stdout to ensure message is displayed
stdout().flush().expect("Failed to flush stdout");
@ -163,10 +163,10 @@ fn main() {
// handles: --prompt never --overwrite
// user specified --prompt never in conjunction with --overwrite, so always rename
true
} else if prompt == Prompt::Error || ask(&*format!("Rename {:#?} to {:#?}?", &f.file, &rename_to)) {
} else if prompt == Prompt::Error || ask(&format!("Rename {:#?} to {:#?}?", &f.file, &rename_to)) {
// handles: --prompt error --overwrite, --prompt always --overwrite [y]
// if the target exists, prompt before renaming; otherwise, just rename
!rename_to.exists() || ask(&*format!("Destination {:#?} already exists, overwrite?", rename_to))
!rename_to.exists() || ask(&format!("Destination {rename_to:#?} already exists, overwrite?"))
} else {
// handles: --prompt always --overwrite [n]
// user was prompted and replied "no"
@ -182,7 +182,7 @@ fn main() {
loop {
// until file is renamed successfully
match std::fs::rename(&f.file, &rename_to) {
Ok(_) => {
Ok(()) => {
info!("Renamed {:#?} -> {:#?}", f.file, rename_to);
renamed += 1;
break;
@ -191,7 +191,7 @@ fn main() {
warn!("Couldn't rename {:#?} to {:#?}: {:#?}", f.file, rename_to, e);
// if the user passed --prompt never, continue to the next file
// otherwise, prompt user to retry move, retrying until the rename succeeds or they respond "N"
if prompt == Prompt::Never || !ask(&*format!("Error while renaming file: {:#?}. Try again?", e)) {
if prompt == Prompt::Never || !ask(&format!("Error while renaming file: {e:#?}. Try again?")) {
failed += 1;
break;
}

View File

@ -32,7 +32,7 @@ cfg_if! {
}
fn open_document_check(buf: &[u8], kind: &str) -> bool {
let mime = format!("application/vnd.oasis.opendocument.{}", kind);
let mime = format!("application/vnd.oasis.opendocument.{kind}");
let mime = mime.as_bytes();
buf.len() > 38 + mime.len() && buf.starts_with(b"PK\x03\x04") && buf[38..mime.len() + 38] == mime[..]

View File

@ -7,7 +7,7 @@ use std::collections::BTreeSet;
use std::path::PathBuf;
use cfg_if::cfg_if;
use clap::{ArgEnum, Parser};
use clap::{ArgAction, Parser, ValueEnum};
use crate::utils::{CLAP_LONG_VERSION, CLAP_VERSION};
use crate::String as StringType;
@ -22,7 +22,7 @@ cfg_if! {
}
}
#[derive(ArgEnum, PartialEq, Debug, Copy, Clone)]
#[derive(ValueEnum, Eq, PartialEq, Debug, Copy, Clone)]
/// The format to use when running fif without the `--fix` flag. Specified at runtime with the `-o`/`--output-format`
/// flag.
pub enum OutputFormat {
@ -39,7 +39,7 @@ pub enum OutputFormat {
Json,
}
#[derive(ArgEnum, PartialEq, Debug, Copy, Clone)]
#[derive(ValueEnum, Eq, PartialEq, Debug, Copy, Clone)]
/// Specifies under what conditions the user should be prompted when running fif in `--fix` mode. Defaults to `Error`.
/// Specified at runtime with the `-p`/`--prompt` flag.
pub enum Prompt {
@ -63,8 +63,7 @@ pub enum Prompt {
This program is free software: you can redistribute it and/or modify \
it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 \
of the License, or (at your option) any later version.",
max_term_width = 120,
setting(clap::AppSettings::DeriveDisplayOrder)
max_term_width = 120
)]
/// [`Clap`]-derived struct used to parse command line arguments.
pub struct Parameters {
@ -73,7 +72,7 @@ pub struct Parameters {
pub fix: bool,
/// Requires --fix. Should fif prompt you `Never`, only on `Error`s and overwrites, or `Always`?
#[clap(short = 'p', long, arg_enum, requires = "fix", help_heading = "RENAMING")]
#[clap(short = 'p', long, value_enum, requires = "fix", help_heading = "RENAMING")]
pub prompt: Option<Prompt>,
/// Requires --fix. Allow overwriting files. Warning: When used in combination with `--prompt never`, fif will
@ -86,8 +85,8 @@ pub struct Parameters {
/// Only examine files with these extensions.
/// Multiple extensions can be specified by either using the flag multiple times (`-e jpg -e png -e gif`), or by
/// separating them with commas (`-e jpg,png,gif`).
#[clap(short, long, use_value_delimiter = true, require_value_delimiter = true, value_name = "ext", takes_value = true,
validator = validate_exts, help_heading = "FILTERING")]
#[clap(short, long, use_value_delimiter = true, value_delimiter = ',', value_name = "ext", num_args(1),
value_parser = validate_exts, help_heading = "FILTERING")]
pub exts: Option<Vec<StringType>>,
/// Use these preset lists of extensions as the search filter (comma-separated list).
@ -96,9 +95,9 @@ pub struct Parameters {
#[clap(
short = 'E',
long,
arg_enum,
value_enum,
use_value_delimiter = true,
require_value_delimiter = true,
value_delimiter = ',',
value_name = "set",
help_heading = "FILTERING"
)]
@ -106,7 +105,7 @@ pub struct Parameters {
/// Don't scan files with these extensions.
/// This option takes precedence over extensions specified with `-e` or `-E`.
#[clap(short = 'x', long, use_value_delimiter = true, require_value_delimiter = true, value_name = "ext", validator =
#[clap(short = 'x', long, use_value_delimiter = true, value_delimiter = ',', value_name = "ext", value_parser =
validate_exts, help_heading = "FILTERING")]
pub exclude: Option<Vec<StringType>>,
@ -115,9 +114,9 @@ pub struct Parameters {
#[clap(
short = 'X',
long,
arg_enum,
value_enum,
use_value_delimiter = true,
require_value_delimiter = true,
value_delimiter = ',',
value_name = "set",
help_heading = "FILTERING"
)]
@ -146,17 +145,17 @@ pub struct Parameters {
/// Output format to use.
/// By default, fif will output a PowerShell script on Windows, and a Bourne Shell script on other platforms.
#[clap(short, long, default_value = DEFAULT_FORMAT, arg_enum, value_name = "format", help_heading = "OUTPUT")]
#[clap(short, long, default_value = DEFAULT_FORMAT, value_enum, value_name = "format", help_heading = "OUTPUT")]
pub output_format: OutputFormat,
/// Output verbosity. Each additional `-v` increases verbosity.
/// Can be overridden by FIF_LOG or RUST_LOG.
#[clap(short, long, parse(from_occurrences), group = "verbosity", help_heading = "OUTPUT")]
#[clap(short, long, action = ArgAction::Count, group = "verbosity", help_heading = "OUTPUT")]
pub verbose: u8,
/// Output quietness. Each additional `-q` decreases verbosity.
/// Can be overridden by FIF_LOG or RUST_LOG.
#[clap(short, long, parse(from_occurrences), group = "verbosity", help_heading = "OUTPUT")]
#[clap(short, long, action = ArgAction::Count, group = "verbosity", help_heading = "OUTPUT")]
pub quiet: u8,
/// Use canonical (absolute) paths in output.
@ -167,7 +166,7 @@ pub struct Parameters {
pub canonical_paths: bool,
/// The directory to process.
#[clap(name = "DIR", default_value = ".", parse(from_os_str))]
#[clap(name = "DIR", default_value = ".", value_parser)]
pub dir: PathBuf,
#[cfg(feature = "multi-threaded")]
@ -181,7 +180,7 @@ pub struct Parameters {
/// Validation function for argument parsing that ensures passed-in extensions are lowercase, and that the user
/// didn't supply an empty list.
fn validate_exts(exts: &str) -> Result<(), String> {
fn validate_exts(exts: &str) -> Result<StringType, String> {
// TODO: i would much rather accept uppercase exts and convert them to lowercase than just rejecting lowercase exts...
if exts.is_empty() {
@ -191,11 +190,11 @@ fn validate_exts(exts: &str) -> Result<(), String> {
if exts.to_lowercase() != exts {
return Err(String::from("Supplied extensions must be lowercase"));
}
Ok(())
Ok(exts.into())
}
/// Further options relating to scanning.
#[derive(PartialEq, Debug, Copy, Clone)]
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
#[allow(clippy::struct_excessive_bools)]
pub struct ScanOpts {
/// Whether hidden files and directories should be scanned.
@ -298,7 +297,7 @@ impl Parameters {
}
/// Sets of extensions for use with [Parameter](crate::parameters::Parameters)'s `-E` flag.
#[derive(ArgEnum, PartialEq, Debug, Copy, Clone)]
#[derive(ValueEnum, Eq, PartialEq, Debug, Copy, Clone)]
pub enum ExtensionSet {
/// Extensions used for image file formats, such as `png`, `jpeg`, `webp`, etc.
Images,

View File

@ -102,11 +102,11 @@ fn simple_directory() {
set_current_dir(dir.path()).expect("Failed to change directory.");
for (name, bytes) in &files {
let mut file = File::create(dir.path().join(name)).expect(&*format!("Failed to create file: {}", name));
let mut file = File::create(dir.path().join(name)).unwrap_or_else(|_| panic!("Failed to create file: {name}"));
file
.write_all(bytes)
.expect(&*format!("Failed to write to file: {}", name));
.unwrap_or_else(|_| panic!("Failed to write to file: {name}"));
drop(file);
}
@ -225,7 +225,7 @@ fn argument_parsing() {
#[test]
/// Ensure that `fif -e jpg dir` is interpreted as "scan for jpg files in dir" and not "scan for jpg and dir files"
fn positional_args() {
for flag in &["-x", "-e", "-X", "-E"] {
for flag in ["-x", "-e", "-X", "-E"] {
assert_eq!(
Parameters::parse_from(vec!["fif", flag, "images", "directory"]).dir,
PathBuf::from("directory")
@ -279,12 +279,12 @@ fn exclude_set_overrides_include_set() {
.iter()
.chain(ExtensionSet::Video.extensions().iter())
{
assert!(extensions.contains(&ext), "Extensions should contain {}!", ext);
assert!(extensions.contains(&ext), "Extensions should contain {ext}!");
}
// ensure all of images' extensions are excluded
for ext in ExtensionSet::Images.extensions() {
assert!(!extensions.contains(&ext), "Extensions should not contain {}!", ext);
assert!(!extensions.contains(&ext), "Extensions should not contain {ext}!");
}
}
@ -315,7 +315,7 @@ fn rejects_bad_args() {
for test in &tests {
// first, try testing the flags against the Parameters struct...
assert!(Parameters::try_parse_from(test).is_err(), "Failed to reject {:?}", test);
assert!(Parameters::try_parse_from(test).is_err(), "Failed to reject {test:?}");
// ...then, make sure it actually works against the binary
let mut cmd = Command::cargo_bin("fif").unwrap();
cmd.args(test).assert().failure();
@ -357,9 +357,8 @@ fn check_version_output() {
let output = cmd.arg("-V").ok().unwrap().stdout;
let output = String::from_utf8(output).unwrap();
assert!(
Regex::new(r#"fif v([0-9]\.){2}[0-9]"#).unwrap().is_match(output.trim()),
"\"{}\" does not match the expected `-v` format!",
output
Regex::new(r"fif v([0-9]\.){2}[0-9]").unwrap().is_match(output.trim()),
"\"{output}\" does not match the expected `-v` format!"
);
// test `--version` matches the format of "fif x.y.z (OS, example backend, commit #1234abc)"
@ -367,7 +366,7 @@ fn check_version_output() {
let output = cmd.arg("--version").ok().unwrap().stdout;
let output = String::from_utf8(output).unwrap();
assert!(
Regex::new(r#"fif v([0-9]\.){2}[0-9] \(.+, .+ backend, (unknown commit|commit #[[:xdigit:]]{7})\)"#)
Regex::new(r"fif v([0-9]\.){2}[0-9] \(.+, .+ backend, (unknown commit|commit #[[:xdigit:]]{7})\)")
.unwrap()
.is_match(output.trim()),
"\"{}\" does not match the expected `--version` format!",
@ -392,7 +391,7 @@ fn identify_random_bytes() {
}
for (mime, count) in &results {
println!("{}:\t{} counts", mime, count);
println!("{mime}:\t{count} counts");
}
println!("No type found:\t{} counts", 1000 - results.values().sum::<i32>());
}
@ -429,9 +428,7 @@ fn outputs_move_commands() {
// the output should contain a command like "mv -i misnamed_file.png misnamed_file.jpg"
assert!(
contents.contains("misnamed_file.jpg") && contents.contains("misnamed_file.png"),
"{} output doesn't contain move command!\n===\n{}",
format,
contents
"{format} output doesn't contain move command!\n===\n{contents}"
);
}
}
@ -465,8 +462,7 @@ fn test_json() {
// the output should contain the file's MIME type
assert!(
contents.contains(IMAGE_JPEG.essence_str()),
"JSON output doesn't contain move command!\n===\n{}",
contents
"JSON output doesn't contain move command!\n===\n{contents}"
);
}
@ -483,8 +479,8 @@ fn media_contains_audio_video_images() {
.for_each(|ext| assert!(media_exts.contains(&ext)));
assert_eq!(
Parameters::parse_from(&["fif", "-E", "media"]).extensions(),
Parameters::parse_from(&["fif", "-E", "audio,video,images"]).extensions()
Parameters::parse_from(["fif", "-E", "media"]).extensions(),
Parameters::parse_from(["fif", "-E", "audio,video,images"]).extensions()
);
}
@ -510,7 +506,7 @@ fn writables_is_correct() {
fn verbosity() {
use log::LevelFilter;
assert!(
Parameters::try_parse_from(&["fif", "-q", "-v"]).is_err(),
Parameters::try_parse_from(["fif", "-q", "-v"]).is_err(),
"Failed to reject usage of both -q and -v!"
);
@ -527,7 +523,7 @@ fn verbosity() {
];
for (flags, level) in expected_results {
assert_eq!(Parameters::parse_from(&["fif", flags]).get_verbosity(), level);
assert_eq!(Parameters::parse_from(["fif", flags]).get_verbosity(), level);
}
}
@ -564,21 +560,3 @@ fn sort_findings() {
assert_eq!(findings.next().unwrap().file, Path::new("ccc"));
assert_eq!(findings.next(), None);
}
#[test]
#[cfg(not(all(target_endian = "big", target_pointer_width = "32")))]
/// Ensures that [`SmartString`]s don't deviate from std's Strings
// remove this when (if) updating to smartstring v1.0!
fn validate_string_type() {
use std::string::String as StdString;
use fif::String as SmartString;
assert_eq!(SmartString::new(), StdString::new());
assert_eq!(SmartString::from("smol"), StdString::from("smol"));
assert_eq!(
SmartString::from("A long and therefore heap-allocated string"),
StdString::from("A long and therefore heap-allocated string")
);
smartstring::validate();
}