diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e41e1e0d..80b8e4f96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## v0.4.0 (2024-02-08) + +**Major Changes** + +* Fixes an issue where primitive integer implementations were not properly panicking +for passing radix 0 and 1 to the `CountDigits::count_digits_radix()` function. + +**Minor Changes** + +* Update documentation clarifying the Radix type. + ## v0.3.1 (2024-02-07) **Minor Changes** diff --git a/Cargo.toml b/Cargo.toml index 445ef954d..695f4f6a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "count-digits" -version = "0.3.1" +version = "0.4.0" authors = ["Erik Nordin "] description = "A no-std trait to count the digits of integer types in various number bases." homepage = "https://github.com/nordzilla/count-digits" diff --git a/src/lib.rs b/src/lib.rs index d274db5f1..f5e47c600 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -201,8 +201,10 @@ pub trait CountDigits: Copy + Sized { /// The type of integer that should be passed in to the /// [count_digits_radix()](CountDigits::count_digits_radix) function. /// - /// This is equal to [Self](CountDigits) for primitive types, - /// and is equal to the corresponding primitive type for non-zero types. + /// This type is always the corresponding unsigned primitive type for an + /// integer of a given size. + /// + /// For example, [u8] is the [Radix](CountDigits::Radix) type for [i8], [u8], [NonZeroI8], and [NonZeroU8]. type Radix; /// Returns the count of bits in an integer. @@ -721,6 +723,7 @@ macro_rules! impl_count_digits { /// Returns the count of digits in an integer as interpreted with the given [radix](https://en.wikipedia.org/wiki/Radix). fn count_digits_radix(self, radix: Self::Radix) -> usize { match radix { + 0 | 1 => panic!("base of integer logarithm must be at least 2"), 02 => self.count_bits() as usize, 08 => self.count_octal_digits() as usize, 10 => self.count_digits(), @@ -779,6 +782,7 @@ macro_rules! impl_count_digits { /// Returns the count of digits in an integer as interpreted with the given [radix](https://en.wikipedia.org/wiki/Radix). fn count_digits_radix(self, radix: Self::Radix) -> usize { match radix { + 0 | 1 => panic!("base of integer logarithm must be at least 2"), 02 => self.count_bits() as usize, 08 => self.count_octal_digits() as usize, 10 => self.count_digits(), @@ -829,6 +833,7 @@ macro_rules! impl_count_digits { /// Returns the count of digits in an integer as interpreted with the given [radix](https://en.wikipedia.org/wiki/Radix). fn count_digits_radix(self, radix: Self::Radix) -> usize { match radix { + 0 | 1 => panic!("base of integer logarithm must be at least 2"), 02 => self.count_bits() as usize, 08 => self.count_octal_digits() as usize, 10 => self.count_digits(), @@ -869,6 +874,7 @@ macro_rules! impl_count_digits { /// Returns the count of digits in an integer as interpreted with the given [radix](https://en.wikipedia.org/wiki/Radix). fn count_digits_radix(self, radix: Self::Radix) -> usize { match radix { + 0 | 1 => panic!("base of integer logarithm must be at least 2"), 02 => self.count_bits() as usize, 08 => self.count_octal_digits() as usize, 10 => self.count_digits(), @@ -1427,6 +1433,28 @@ mod count_digits { }; } + macro_rules! invalid_radix { + ($type:ty, $non_zero_type:ty) => { + invalid_radix!(0, $type, $non_zero_type); + invalid_radix!(1, $type, $non_zero_type); + }; + ($radix:expr, $type:ty, $non_zero_type:ty) => { + paste! { + #[test] + #[should_panic(expected = "base of integer logarithm must be at least 2")] + fn [<$type _invalid_radix_ $radix>]() { + (1 as $type).count_digits_radix($radix); + } + #[test] + #[allow(non_snake_case)] + #[should_panic(expected = "base of integer logarithm must be at least 2")] + fn [<$non_zero_type _invalid_radix_ $radix>]() { + $non_zero_type::new(1).unwrap().count_digits_radix($radix); + } + } + }; + } + macro_rules! boundaries_for_radix { ($type:ty, $non_zero_type:ty) => { boundaries_for_radix!(02, $type, $non_zero_type); @@ -1498,6 +1526,18 @@ mod count_digits { add_test!(boundaries_for_radix, u128, NonZeroU128); add_test!(boundaries_for_radix, usize, NonZeroUsize); + add_test!(invalid_radix, i8, NonZeroI8); + add_test!(invalid_radix, i16, NonZeroI16); + add_test!(invalid_radix, i32, NonZeroI32); + add_test!(invalid_radix, i64, NonZeroI64); + add_test!(invalid_radix, isize, NonZeroIsize); + + add_test!(invalid_radix, u8, NonZeroU8); + add_test!(invalid_radix, u16, NonZeroU16); + add_test!(invalid_radix, u32, NonZeroU32); + add_test!(invalid_radix, u64, NonZeroU64); + add_test!(invalid_radix, usize, NonZeroUsize); + add_test!(iteration, signed, i8, NonZeroI8); add_test!(iteration, signed, i16, NonZeroI16); add_test!(iteration, signed, i32, NonZeroI32);