diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 87aac20..9809b24 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,8 +40,10 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: "1.53.0" + toolchain: "1.60.0" override: true + - name: Use Cargo.lock.msrv + run: cp Cargo.lock.msrv Cargo.lock - name: Test run: | cargo test diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f38ab6..e2f60af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ Changelog ========= +## [0.5.3] — 2024-12-12 + +- Bump MSRV to 1.60.0 and use Edition 2021 (#30) + ## [0.5.2] — 2022-12-22 - Support cast to self, useful in generics (#28) diff --git a/Cargo.lock.msrv b/Cargo.lock.msrv new file mode 100644 index 0000000..58b02aa --- /dev/null +++ b/Cargo.lock.msrv @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "easy-cast" +version = "0.5.3" +dependencies = [ + "libm", +] + +[[package]] +name = "libm" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bda4c6077b0b08da2c48b172195795498381a7c8988c9e6212a6c55c5b9bd70" diff --git a/Cargo.toml b/Cargo.toml index 32538fd..233eb10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,14 +1,20 @@ [package] name = "easy-cast" -version = "0.5.2" +version = "0.5.3" authors = ["Diggory Hardy "] -edition = "2018" +edition = "2021" license = "Apache-2.0" description = "Type conversions which are expected to succeed" readme = "README.md" documentation = "https://docs.rs/easy-cast/" keywords = ["cast", "into", "from", "conversion"] repository = "https://github.com/kas-gui/easy-cast" +rust-version = "1.60.0" + +[package.metadata.docs.rs] +features = [] +# To build locally: +# RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --open [features] default = ["std"] @@ -16,6 +22,9 @@ default = ["std"] # Without std, float conversions are disabled (unless libm is used) std = [] +# libm may be used instead of std to provide float conversions +libm = ["dep:libm"] + # Note: assertions are always used in debug builds; these only affect release builds: # Always use all assertions @@ -31,6 +40,5 @@ assert_int = [] assert_digits = [] [dependencies.libm] -# libm may be used instead of std to provide float conversions version = "0.2.1" optional = true diff --git a/src/impl_basic.rs b/src/impl_basic.rs index 5a121fb..a9ef626 100644 --- a/src/impl_basic.rs +++ b/src/impl_basic.rs @@ -133,9 +133,7 @@ impl Conv<()> for () { Ok(()) } #[inline] - fn conv(_: ()) -> Self { - () - } + fn conv(_: ()) -> Self {} } impl> Conv<(S0,)> for (T0,) { #[inline] diff --git a/src/impl_float.rs b/src/impl_float.rs index d86e851..f841389 100644 --- a/src/impl_float.rs +++ b/src/impl_float.rs @@ -7,6 +7,7 @@ use super::*; +#[allow(clippy::manual_range_contains)] impl ConvApprox for f32 { fn try_conv_approx(x: f64) -> Result { use core::num::FpCategory; @@ -80,7 +81,6 @@ impl FloatRound for f64 { } #[cfg(any(feature = "std", feature = "libm"))] -#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "libm"))))] macro_rules! impl_float { ($x:ty: $y:tt) => { impl ConvFloat<$x> for $y { @@ -140,8 +140,8 @@ macro_rules! impl_float { #[inline] fn try_conv_trunc(x: $x) -> Result { // Tested: these limits work for $x=f32 and all $y except u128 - const LBOUND: $x = core::$y::MIN as $x - 1.0; - const UBOUND: $x = core::$y::MAX as $x + 1.0; + const LBOUND: $x = $y::MIN as $x - 1.0; + const UBOUND: $x = $y::MAX as $x + 1.0; if x > LBOUND && x < UBOUND { Ok(x as $y) } else { @@ -151,10 +151,10 @@ macro_rules! impl_float { #[inline] fn try_conv_nearest(x: $x) -> Result { // Tested: these limits work for $x=f32 and all $y except u128 - const LBOUND: $x = core::$y::MIN as $x; - const UBOUND: $x = core::$y::MAX as $x + 1.0; + const LBOUND: $x = $y::MIN as $x; + const UBOUND: $x = $y::MAX as $x + 1.0; let x = x.round(); - if x >= LBOUND && x < UBOUND { + if (LBOUND..UBOUND).contains(&x) { Ok(x as $y) } else { Err(Error::Range) @@ -163,10 +163,10 @@ macro_rules! impl_float { #[inline] fn try_conv_floor(x: $x) -> Result { // Tested: these limits work for $x=f32 and all $y except u128 - const LBOUND: $x = core::$y::MIN as $x; - const UBOUND: $x = core::$y::MAX as $x + 1.0; + const LBOUND: $x = $y::MIN as $x; + const UBOUND: $x = $y::MAX as $x + 1.0; let x = x.floor(); - if x >= LBOUND && x < UBOUND { + if (LBOUND..UBOUND).contains(&x) { Ok(x as $y) } else { Err(Error::Range) @@ -175,10 +175,10 @@ macro_rules! impl_float { #[inline] fn try_conv_ceil(x: $x) -> Result { // Tested: these limits work for $x=f32 and all $y except u128 - const LBOUND: $x = core::$y::MIN as $x; - const UBOUND: $x = core::$y::MAX as $x + 1.0; + const LBOUND: $x = $y::MIN as $x; + const UBOUND: $x = $y::MAX as $x + 1.0; let x = x.ceil(); - if x >= LBOUND && x < UBOUND { + if (LBOUND..UBOUND).contains(&x) { Ok(x as $y) } else { Err(Error::Range) diff --git a/src/impl_int.rs b/src/impl_int.rs index 79616ac..1ae3847 100644 --- a/src/impl_int.rs +++ b/src/impl_int.rs @@ -53,15 +53,15 @@ macro_rules! impl_via_as_max_check { fn conv(x: $x) -> $y { #[cfg(any(debug_assertions, feature = "assert_int"))] assert!( - x <= core::$y::MAX as $x, + x <= $y::MAX as $x, "cast x: {} to {}: expected x <= {}, found x = {}", - stringify!($x), stringify!($y), core::$y::MAX, x + stringify!($x), stringify!($y), $y::MAX, x ); x as $y } #[inline] fn try_conv(x: $x) -> Result { - if x <= core::$y::MAX as $x { + if x <= $y::MAX as $x { Ok(x as $y) } else { Err(Error::Range) @@ -90,15 +90,15 @@ macro_rules! impl_via_as_range_check { fn conv(x: $x) -> $y { #[cfg(any(debug_assertions, feature = "assert_int"))] assert!( - core::$y::MIN as $x <= x && x <= core::$y::MAX as $x, + $y::MIN as $x <= x && x <= $y::MAX as $x, "cast x: {} to {}: expected {} <= x <= {}, found x = {}", - stringify!($x), stringify!($y), core::$y::MIN, core::$y::MAX, x + stringify!($x), stringify!($y), $y::MIN, $y::MAX, x ); x as $y } #[inline] fn try_conv(x: $x) -> Result { - if core::$y::MIN as $x <= x && x <= core::$y::MAX as $x { + if $y::MIN as $x <= x && x <= $y::MAX as $x { Ok(x as $y) } else { Err(Error::Range) @@ -123,8 +123,8 @@ macro_rules! impl_int_generic { #[allow(unused_comparisons)] #[inline] fn conv(x: $x) -> $y { - let src_is_signed = core::$x::MIN != 0; - let dst_is_signed = core::$y::MIN != 0; + let src_is_signed = $x::MIN != 0; + let dst_is_signed = $y::MIN != 0; if size_of::<$x>() < size_of::<$y>() { if !dst_is_signed { #[cfg(any(debug_assertions, feature = "assert_int"))] @@ -138,9 +138,9 @@ macro_rules! impl_int_generic { if dst_is_signed { #[cfg(any(debug_assertions, feature = "assert_int"))] assert!( - x <= core::$y::MAX as $x, + x <= $y::MAX as $x, "cast x: {} to {}: expected x <= {}, found x = {}", - stringify!($x), stringify!($y), core::$y::MAX, x + stringify!($x), stringify!($y), $y::MAX, x ); } else if src_is_signed { #[cfg(any(debug_assertions, feature = "assert_int"))] @@ -155,16 +155,16 @@ macro_rules! impl_int_generic { if src_is_signed { #[cfg(any(debug_assertions, feature = "assert_int"))] assert!( - core::$y::MIN as $x <= x && x <= core::$y::MAX as $x, + $y::MIN as $x <= x && x <= $y::MAX as $x, "cast x: {} to {}: expected {} <= x <= {}, found x = {}", - stringify!($x), stringify!($y), core::$y::MIN, core::$y::MAX, x + stringify!($x), stringify!($y), $y::MIN, $y::MAX, x ); } else { #[cfg(any(debug_assertions, feature = "assert_int"))] assert!( - x <= core::$y::MAX as $x, + x <= $y::MAX as $x, "cast x: {} to {}: expected x <= {}, found x = {}", - stringify!($x), stringify!($y), core::$y::MAX, x + stringify!($x), stringify!($y), $y::MAX, x ); } } @@ -173,15 +173,15 @@ macro_rules! impl_int_generic { #[allow(unused_comparisons)] #[inline] fn try_conv(x: $x) -> Result { - let src_is_signed = core::$x::MIN != 0; - let dst_is_signed = core::$y::MIN != 0; + let src_is_signed = $x::MIN != 0; + let dst_is_signed = $y::MIN != 0; if size_of::<$x>() < size_of::<$y>() { if dst_is_signed || x >= 0 { return Ok(x as $y); } } else if size_of::<$x>() == size_of::<$y>() { if dst_is_signed { - if x <= core::$y::MAX as $x { + if x <= $y::MAX as $x { return Ok(x as $y); } } else if src_is_signed { @@ -195,11 +195,11 @@ macro_rules! impl_int_generic { } else { // src size > dst size if src_is_signed { - if core::$y::MIN as $x <= x && x <= core::$y::MAX as $x { + if $y::MIN as $x <= x && x <= $y::MAX as $x { return Ok(x as $y); } } else { - if x <= core::$y::MAX as $x { + if x <= $y::MAX as $x { return Ok(x as $y); } } @@ -249,7 +249,7 @@ macro_rules! impl_via_digits_check { fn try_conv(x: $x) -> Result { let src_ty_bits = (size_of::<$x>() * 8) as u32; let src_digits = src_ty_bits.saturating_sub(x.leading_zeros() + x.trailing_zeros()); - let dst_digits = core::$y::MANTISSA_DIGITS; + let dst_digits = $y::MANTISSA_DIGITS; if src_digits <= dst_digits { Ok(x as $y) } else { @@ -286,7 +286,7 @@ macro_rules! impl_via_digits_check_signed { let src_digits = x.checked_abs() .map(|y| src_ty_bits.saturating_sub(y.leading_zeros() + y.trailing_zeros())) .unwrap_or(1 /*MIN has one binary digit in float repr*/); - let dst_digits = core::$y::MANTISSA_DIGITS; + let dst_digits = $y::MANTISSA_DIGITS; if src_digits <= dst_digits { Ok(x as $y) } else { diff --git a/src/lib.rs b/src/lib.rs index aa7d539..b126e5b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,7 @@ #![deny(missing_docs)] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(doc_cfg, feature(doc_cfg))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] mod impl_basic; mod impl_float; diff --git a/src/traits.rs b/src/traits.rs index 55b2f1c..33a1ab8 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -216,7 +216,6 @@ impl> CastApprox for S { /// /// The sister-trait [`CastFloat`] supports "into" style usage. #[cfg(any(feature = "std", feature = "libm"))] -#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "libm"))))] pub trait ConvFloat: Sized { /// Try converting to integer with truncation /// @@ -280,7 +279,6 @@ pub trait ConvFloat: Sized { /// This trait is automatically implemented for every implementation of /// [`ConvFloat`]. #[cfg(any(feature = "std", feature = "libm"))] -#[cfg_attr(doc_cfg, doc(cfg(any(feature = "std", feature = "libm"))))] pub trait CastFloat { /// Cast to integer, truncating ///