diff --git a/.bumpversion.toml b/.bumpversion.toml index 0f10dc5..49de31e 100644 --- a/.bumpversion.toml +++ b/.bumpversion.toml @@ -4,7 +4,7 @@ # SPDX-License-Identifier: Apache-2.0 OR MIT [tool.bumpversion] -current_version = "0.8.2" +current_version = "0.8.3" [[tool.bumpversion.files]] filename = "CITATION.cff" diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0395e08..7e14ee1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,10 +7,10 @@ updates: - package-ecosystem: "cargo" directory: "/" schedule: - interval: "daily" + interval: "weekly" - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "daily" + interval: "weekly" open-pull-requests-limit: 10 diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 71867ae..81d8dce 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -42,6 +42,10 @@ jobs: with: toolchain: ${{ matrix.toolchain }} targets: ${{ matrix.target }} + - name: Cache build artifacts + uses: Swatinem/rust-cache@v2.7.5 + with: + key: ${{ matrix.target }} - name: Run tests run: cargo test --target ${{ matrix.target }} - name: Run tests (no default features) @@ -64,6 +68,8 @@ jobs: with: toolchain: stable components: rustfmt + - name: Cache build artifacts + uses: Swatinem/rust-cache@v2.7.5 - name: Check code formatted run: cargo fmt -- --check @@ -78,6 +84,8 @@ jobs: with: toolchain: stable components: clippy + - name: Cache build artifacts + uses: Swatinem/rust-cache@v2.7.5 - name: Check no lint warnings run: cargo clippy -- -D warnings - name: Check no lint warnings (no default features) @@ -93,5 +101,22 @@ jobs: uses: dtolnay/rust-toolchain@v1 with: toolchain: stable + - name: Cache build artifacts + uses: Swatinem/rust-cache@v2.7.5 - name: Check no `rustdoc` lint warnings run: RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --document-private-items + + benchmark: + name: Benchmark + runs-on: ubuntu-22.04 + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@v1 + with: + toolchain: nightly + - name: Cache build artifacts + uses: Swatinem/rust-cache@v2.7.5 + - name: Run benchmarks + run: cargo bench diff --git a/.github/workflows/SemverChecks.yaml b/.github/workflows/SemverChecks.yaml index 8fb2f0b..741c587 100644 --- a/.github/workflows/SemverChecks.yaml +++ b/.github/workflows/SemverChecks.yaml @@ -10,6 +10,7 @@ on: - "release/*" tags: - "v[0-9]+.[0-9]+.[0-9]+" + workflow_dispatch: jobs: semver: diff --git a/.github/workflows/dependabot_auto_merge.yaml b/.github/workflows/dependabot_auto_merge.yaml new file mode 100644 index 0000000..a18ca56 --- /dev/null +++ b/.github/workflows/dependabot_auto_merge.yaml @@ -0,0 +1,34 @@ +# SPDX-FileCopyrightText: 2024 Shun Sakai +# +# SPDX-License-Identifier: Apache-2.0 OR MIT + +name: Dependabot auto-merge + +on: pull_request_target + +permissions: + contents: write + pull-requests: write + +jobs: + dependabot: + name: Dependabot auto-merge + if: github.actor == 'dependabot[bot]' && github.repository_owner == 'sorairolake' + runs-on: ubuntu-22.04 + steps: + - name: Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v2.2.0 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Approve a PR + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Enable auto-merge for Dependabot PRs + if: ${{ steps.metadata.outputs.update-type == 'version-update:semver-patch' || steps.metadata.outputs.update-type == 'version-update:semver-minor' }} + run: gh pr merge --auto --squash "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/mirror.yaml b/.github/workflows/mirror.yaml index ec4075d..fcec755 100644 --- a/.github/workflows/mirror.yaml +++ b/.github/workflows/mirror.yaml @@ -9,12 +9,14 @@ on: branches: - "develop" - "master" + schedule: + - cron: "0 0 * * FRI" workflow_dispatch: jobs: gitlab: name: Mirror to GitLab - if: github.actor == 'sorairolake' && github.repository_owner == 'sorairolake' + if: (github.actor == 'sorairolake' || github.event_name == 'schedule') && github.repository_owner == 'sorairolake' runs-on: ubuntu-22.04 steps: - name: Checkout code @@ -31,7 +33,7 @@ jobs: codeberg: name: Mirror to Codeberg - if: github.actor == 'sorairolake' && github.repository_owner == 'sorairolake' + if: (github.actor == 'sorairolake' || github.event_name == 'schedule') && github.repository_owner == 'sorairolake' runs-on: ubuntu-22.04 steps: - name: Checkout code diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 8da64c7..70bfa86 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -14,6 +14,13 @@ All notable changes to this project will be documented in this file. The format is based on https://keepachangelog.com/[Keep a Changelog], and this project adheres to https://semver.org/[Semantic Versioning]. +== {compare-url}/v0.8.2\...v0.8.3[0.8.3] - 2024-10-30 + +=== Added + +* Add benchmarks ({pull-request-url}/121[#121]) +* Implement `Default` for `ExitCode` ({pull-request-url}/126[#126]) + == {compare-url}/v0.8.1\...v0.8.2[0.8.2] - 2024-09-22 === Added diff --git a/CITATION.cff b/CITATION.cff index ecdcf49..d093dde 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -8,8 +8,8 @@ cff-version: 1.2.0 message: Please cite this software using these meta data. # Version information. -date-released: 2024-09-22 -version: 0.8.2 +date-released: 2024-10-30 +version: 0.8.3 # Project information. abstract: The system exit codes as defined by for Rust diff --git a/Cargo.lock b/Cargo.lock index 92a24dd..d345802 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", @@ -19,43 +19,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "bit-set" @@ -92,9 +92,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.18" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" dependencies = [ "clap_builder", "clap_derive", @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.18" +version = "4.5.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" dependencies = [ "anstream", "anstyle", @@ -132,9 +132,9 @@ checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "errno" @@ -189,15 +189,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libm" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "linux-raw-sys" @@ -217,9 +217,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "ppv-lite86" @@ -232,9 +232,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -315,15 +315,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rustix" -version = "0.38.37" +version = "0.38.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" dependencies = [ "bitflags", "errno", @@ -375,9 +375,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -386,7 +386,7 @@ dependencies = [ [[package]] name = "sysexits" -version = "0.8.2" +version = "0.8.3" dependencies = [ "clap", "proptest", @@ -395,9 +395,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", "fastrand", diff --git a/Cargo.toml b/Cargo.toml index 05e8a9e..2b9f3da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ [package] name = "sysexits" -version = "0.8.2" +version = "0.8.3" authors = ["Shun Sakai "] edition = "2021" rust-version = "1.74.0" @@ -26,22 +26,22 @@ all-features = true [[example]] name = "cat" path = "examples/cat.rs" -required-features = ["default"] +required-features = ["std"] [[example]] name = "cmp" path = "examples/cmp.rs" -required-features = ["default"] +required-features = ["std"] [[example]] name = "isutf8" path = "examples/isutf8.rs" -required-features = ["default"] +required-features = ["std"] [dependencies] [dev-dependencies] -clap = { version = "4.5.18", features = ["derive"] } +clap = { version = "4.5.20", features = ["derive"] } proptest = "1.5.0" test-strategy = "0.4.0" @@ -50,3 +50,13 @@ default = ["std"] std = [] nightly = ["extended_io_error"] extended_io_error = ["std"] + +[lints.clippy] +cargo = "warn" +nursery = "warn" +pedantic = "warn" + +[lints.rust] +missing_debug_implementations = "deny" +rust_2018_idioms = { level = "warn", priority = -1 } +unsafe_code = "forbid" diff --git a/README.md b/README.md index 56abf3c..4bcee7f 100644 --- a/README.md +++ b/README.md @@ -24,29 +24,7 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -sysexits = "0.8.2" -``` - -### Example - -```rust -use std::str; - -use sysexits::ExitCode; - -fn main() -> ExitCode { - let bytes = [0xf0, 0x9f, 0x92, 0x96]; - match str::from_utf8(&bytes) { - Ok(string) => { - println!("{string}"); - ExitCode::Ok - } - Err(err) => { - eprintln!("{err}"); - ExitCode::DataErr - } - } -} +sysexits = "0.8.3" ``` ### Crate features @@ -95,6 +73,14 @@ Please see [CHANGELOG.adoc]. Please see [CONTRIBUTING.adoc]. +## Similar projects + +- (Julia) +- (Zig) + +You can discover more projects at +. + ## License Copyright © 2022–2024 Shun Sakai and other contributors (see diff --git a/benches/convert.rs b/benches/convert.rs new file mode 100644 index 0000000..566f234 --- /dev/null +++ b/benches/convert.rs @@ -0,0 +1,74 @@ +// SPDX-FileCopyrightText: 2024 Shun Sakai +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +#![feature(test)] + +extern crate test; + +use sysexits::ExitCode; +use test::Bencher; + +macro_rules! bench_from_exit_code_to_integer { + ($T:ty, $name:ident) => { + #[bench] + fn $name(b: &mut Bencher) { + b.iter(|| <$T>::from(ExitCode::Ok)); + } + }; +} +bench_from_exit_code_to_integer!(i8, from_exit_code_to_i8); +bench_from_exit_code_to_integer!(i16, from_exit_code_to_i16); +bench_from_exit_code_to_integer!(i32, from_exit_code_to_i32); +bench_from_exit_code_to_integer!(i64, from_exit_code_to_i64); +bench_from_exit_code_to_integer!(i128, from_exit_code_to_i128); +bench_from_exit_code_to_integer!(isize, from_exit_code_to_isize); +bench_from_exit_code_to_integer!(u8, from_exit_code_to_u8); +bench_from_exit_code_to_integer!(u16, from_exit_code_to_u16); +bench_from_exit_code_to_integer!(u32, from_exit_code_to_u32); +bench_from_exit_code_to_integer!(u64, from_exit_code_to_u64); +bench_from_exit_code_to_integer!(u128, from_exit_code_to_u128); +bench_from_exit_code_to_integer!(usize, from_exit_code_to_usize); + +#[cfg(feature = "std")] +#[bench] +fn from_exit_code_to_process_exit_code(b: &mut Bencher) { + b.iter(|| std::process::ExitCode::from(ExitCode::Ok)); +} + +macro_rules! bench_try_from_integer_to_exit_code { + ($T:ty, $name:ident) => { + #[bench] + fn $name(b: &mut Bencher) { + b.iter(|| ExitCode::try_from(0 as $T).unwrap()); + } + }; +} +bench_try_from_integer_to_exit_code!(i8, try_from_i8_to_exit_code); +bench_try_from_integer_to_exit_code!(i16, try_from_i16_to_exit_code); +bench_try_from_integer_to_exit_code!(i32, try_from_i32_to_exit_code); +bench_try_from_integer_to_exit_code!(i64, try_from_i64_to_exit_code); +bench_try_from_integer_to_exit_code!(i128, try_from_i128_to_exit_code); +bench_try_from_integer_to_exit_code!(isize, try_from_isize_to_exit_code); +bench_try_from_integer_to_exit_code!(u8, try_from_u8_to_exit_code); +bench_try_from_integer_to_exit_code!(u16, try_from_u16_to_exit_code); +bench_try_from_integer_to_exit_code!(u32, try_from_u32_to_exit_code); +bench_try_from_integer_to_exit_code!(u64, try_from_u64_to_exit_code); +bench_try_from_integer_to_exit_code!(u128, try_from_u128_to_exit_code); +bench_try_from_integer_to_exit_code!(usize, try_from_usize_to_exit_code); + +#[cfg(feature = "std")] +#[bench] +fn from_io_error_to_exit_code(b: &mut Bencher) { + use std::io::{Error, ErrorKind}; + + b.iter(|| ExitCode::from(Error::from(ErrorKind::NotFound))); +} + +#[cfg(feature = "std")] +#[bench] +fn from_io_error_kind_to_exit_code(b: &mut Bencher) { + use std::io; + + b.iter(|| ExitCode::from(io::ErrorKind::NotFound)); +} diff --git a/benches/exit_code.rs b/benches/exit_code.rs new file mode 100644 index 0000000..a3d8064 --- /dev/null +++ b/benches/exit_code.rs @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: 2024 Shun Sakai +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +#![feature(test)] + +extern crate test; + +use sysexits::ExitCode; +use test::Bencher; + +#[bench] +fn default(b: &mut Bencher) { + b.iter(ExitCode::default); +} + +#[bench] +fn equality(b: &mut Bencher) { + b.iter(|| ExitCode::Ok == ExitCode::Ok); +} + +#[bench] +fn is_success_for_successful_termination(b: &mut Bencher) { + b.iter(|| ExitCode::Ok.is_success()); +} + +#[bench] +fn is_success_for_unsuccessful_termination(b: &mut Bencher) { + b.iter(|| ExitCode::Usage.is_success()); +} + +#[bench] +fn is_failure_for_successful_termination(b: &mut Bencher) { + b.iter(|| ExitCode::Ok.is_failure()); +} + +#[bench] +fn is_failure_for_unsuccessful_termination(b: &mut Bencher) { + b.iter(|| ExitCode::Usage.is_failure()); +} + +#[cfg(feature = "std")] +#[bench] +fn source(b: &mut Bencher) { + use std::error::Error; + + b.iter(|| ExitCode::Ok.source()); +} + +#[cfg(feature = "std")] +#[bench] +fn report(b: &mut Bencher) { + use std::process::Termination; + + b.iter(|| ExitCode::Ok.report()); +} diff --git a/benches/result.rs b/benches/result.rs new file mode 100644 index 0000000..dd24422 --- /dev/null +++ b/benches/result.rs @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: 2024 Shun Sakai +// +// SPDX-License-Identifier: Apache-2.0 OR MIT + +#![feature(test)] + +extern crate test; + +use sysexits::ExitCode; +use test::Bencher; + +#[bench] +fn from_result_type_to_exit_code(b: &mut Bencher) { + b.iter(|| ExitCode::from(Ok::<(), ExitCode>(()))); +} diff --git a/examples/cat.rs b/examples/cat.rs index 6f01841..606def8 100644 --- a/examples/cat.rs +++ b/examples/cat.rs @@ -6,13 +6,6 @@ //! An example of concatenating files and print on the standard output. The //! contents of the file must be valid UTF-8. -// Lint levels of rustc. -#![forbid(unsafe_code)] -#![deny(missing_debug_implementations)] -#![warn(rust_2018_idioms)] -// Lint levels of Clippy. -#![warn(clippy::cargo, clippy::nursery, clippy::pedantic)] - use std::{ fs, io::{self, Read}, diff --git a/examples/cmp.rs b/examples/cmp.rs index 956dae9..e733b5e 100644 --- a/examples/cmp.rs +++ b/examples/cmp.rs @@ -4,13 +4,6 @@ //! An example of comparing two files byte by byte. -// Lint levels of rustc. -#![forbid(unsafe_code)] -#![deny(missing_debug_implementations)] -#![warn(rust_2018_idioms)] -// Lint levels of Clippy. -#![warn(clippy::cargo, clippy::nursery, clippy::pedantic)] - use std::{ fs, io, path::PathBuf, diff --git a/examples/isutf8.rs b/examples/isutf8.rs index 9feca67..797fb65 100644 --- a/examples/isutf8.rs +++ b/examples/isutf8.rs @@ -5,13 +5,6 @@ //! An example of checking whether the input is valid UTF-8. The input is a file //! or the standard input. -// Lint levels of rustc. -#![forbid(unsafe_code)] -#![deny(missing_debug_implementations)] -#![warn(rust_2018_idioms)] -// Lint levels of Clippy. -#![warn(clippy::cargo, clippy::nursery, clippy::pedantic)] - use std::{ fs, io::{self, Read}, diff --git a/justfile b/justfile index 2208424..d289d69 100644 --- a/justfile +++ b/justfile @@ -31,7 +31,7 @@ default: build # Run the formatter with options @fmt-with-options: - cargo fmt -- --config "format_code_in_doc_comments=true,wrap_comments=true" + cargo +nightly fmt # Run the linter @clippy: @@ -39,7 +39,7 @@ default: build # Apply lint suggestions @clippy-fix: - cargo clippy --fix --allow-dirty --allow-staged -- -D warnings + cargo +nightly clippy --fix --allow-dirty --allow-staged -- -D warnings # Run the linter for GitHub Actions workflow files @lint-github-actions: diff --git a/rustfmt.toml b/rustfmt.toml index 68f4c7f..ba5100f 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -3,3 +3,8 @@ # SPDX-License-Identifier: Apache-2.0 OR MIT edition = "2021" +format_code_in_doc_comments = true +format_macro_matchers = true +group_imports = "StdExternalCrate" +imports_granularity = "Crate" +wrap_comments = true diff --git a/src/error.rs b/src/error.rs index f3f6cc1..9acc177 100644 --- a/src/error.rs +++ b/src/error.rs @@ -14,6 +14,7 @@ use core::fmt; pub struct ExitCodeRangeError; impl fmt::Display for ExitCodeRangeError { + #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "value is out of range for `ExitCode`") } @@ -49,6 +50,7 @@ impl TryFromExitStatusError { #[cfg(feature = "std")] impl fmt::Display for TryFromExitStatusError { + #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(code) = self.code() { write!(f, "invalid exit code `{code}`") diff --git a/src/exit_code.rs b/src/exit_code.rs index 04da0ee..b46d19a 100644 --- a/src/exit_code.rs +++ b/src/exit_code.rs @@ -17,7 +17,7 @@ use core::fmt; /// defined by [``]. /// /// [``]: https://man.openbsd.org/sysexits -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)] pub enum ExitCode { /// The successful exit. /// @@ -28,6 +28,7 @@ pub enum ExitCode { /// # /// assert_eq!(ExitCode::Ok as u8, 0); /// ``` + #[default] Ok, /// The command was used incorrectly, e.g., with the wrong number of @@ -266,6 +267,7 @@ impl ExitCode { /// } /// ``` #[cfg(feature = "std")] + #[inline] pub fn exit(self) -> ! { std::process::exit(self.into()) } @@ -304,19 +306,19 @@ mod tests { use super::*; #[test] - fn clone_exit_code() { + fn clone() { assert_eq!(ExitCode::Ok.clone(), ExitCode::Ok); } #[test] - fn copy_exit_code() { + fn copy() { let a = ExitCode::Ok; let b = a; assert_eq!(a, b); } #[test] - fn debug_exit_code() { + fn debug() { assert_eq!(format!("{:?}", ExitCode::Ok), "Ok"); assert_eq!(format!("{:?}", ExitCode::Usage), "Usage"); assert_eq!(format!("{:?}", ExitCode::DataErr), "DataErr"); @@ -335,9 +337,14 @@ mod tests { assert_eq!(format!("{:?}", ExitCode::Config), "Config"); } + #[test] + fn default() { + assert_eq!(ExitCode::default(), ExitCode::Ok); + } + #[test] #[allow(clippy::cognitive_complexity, clippy::too_many_lines)] - fn exit_code_equality() { + fn equality() { assert_eq!(ExitCode::Ok, ExitCode::Ok); assert_ne!(ExitCode::Ok, ExitCode::Usage); assert_ne!(ExitCode::Ok, ExitCode::DataErr); @@ -597,7 +604,7 @@ mod tests { } #[test] - fn display_exit_code() { + fn display() { assert_eq!(format!("{}", ExitCode::Ok), format!("{}", 0)); assert_eq!(format!("{}", ExitCode::Usage), format!("{}", 64)); assert_eq!(format!("{}", ExitCode::DataErr), format!("{}", 65)); @@ -666,7 +673,7 @@ mod tests { #[cfg(feature = "std")] #[test] - fn source_exit_code() { + fn source() { use std::error::Error; assert!(ExitCode::Ok.source().is_none()); @@ -689,7 +696,7 @@ mod tests { #[cfg(feature = "std")] #[test] - fn report_exit_code() { + fn report() { use std::process::Termination; assert_eq!( diff --git a/src/exit_code/convert.rs b/src/exit_code/convert.rs index 1a31a83..9c872fc 100644 --- a/src/exit_code/convert.rs +++ b/src/exit_code/convert.rs @@ -6,9 +6,8 @@ //! Implementations of conversions between [`ExitCode`] and other types. -use crate::error::ExitCodeRangeError; - use super::ExitCode; +use crate::error::ExitCodeRangeError; macro_rules! impl_from_exit_code_to_integer { ($T:ty, $ok:expr, $usage:expr) => { @@ -162,6 +161,7 @@ impl From for ExitCode { /// ExitCode::NoInput /// ); /// ``` + #[inline] fn from(error: std::io::Error) -> Self { error.kind().into() } @@ -180,6 +180,7 @@ impl From for ExitCode { /// # /// assert_eq!(ExitCode::from(io::ErrorKind::NotFound), ExitCode::NoInput); /// ``` + #[inline] fn from(kind: std::io::ErrorKind) -> Self { use std::io::ErrorKind; @@ -222,6 +223,7 @@ impl TryFrom for ExitCode { /// - The exit code is not `0` or `64..=78`. /// - The exit code is unknown (e.g., the process was terminated by a /// signal). + #[inline] fn try_from(status: std::process::ExitStatus) -> std::result::Result { match status.code() { Some(0) => Ok(Self::Ok), diff --git a/src/exit_code/result.rs b/src/exit_code/result.rs index 6339b2f..4036408 100644 --- a/src/exit_code/result.rs +++ b/src/exit_code/result.rs @@ -37,6 +37,7 @@ impl From> for ExitCode { /// ExitCode::Usage /// ); /// ``` + #[inline] fn from(result: Result) -> Self { result.map_or_else(|code| code, |_| Self::Ok) } diff --git a/src/lib.rs b/src/lib.rs index 6a03b0f..10e448b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,15 +42,11 @@ //! [``]: https://man.openbsd.org/sysexits #![cfg_attr(feature = "extended_io_error", feature(io_error_more))] -#![doc(html_root_url = "https://docs.rs/sysexits/0.8.2/")] +#![doc(html_root_url = "https://docs.rs/sysexits/0.8.3/")] #![no_std] #![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))] // Lint levels of rustc. -#![forbid(unsafe_code)] -#![deny(missing_debug_implementations, missing_docs)] -#![warn(rust_2018_idioms)] -// Lint levels of Clippy. -#![warn(clippy::cargo, clippy::nursery, clippy::pedantic)] +#![deny(missing_docs)] #[cfg(test)] #[macro_use]