Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 32 additions & 38 deletions gix-utils/src/btoi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub fn to_unsigned_with_radix<I: MinNumTraits>(bytes: &[u8], radix: u32) -> Resu
return Err(ParseIntegerError { kind: ErrorKind::Empty });
}

let mut result = I::zero();
let mut result = I::ZERO;

for &digit in bytes {
let x = match char::from(digit).to_digit(radix).and_then(I::from_u32) {
Expand Down Expand Up @@ -236,7 +236,7 @@ pub fn to_signed_with_radix<I: MinNumTraits>(bytes: &[u8], radix: u32) -> Result
return Err(ParseIntegerError { kind: ErrorKind::Empty });
}

let mut result = I::zero();
let mut result = I::ZERO;

for &digit in digits {
let x = match char::from(digit).to_digit(radix).and_then(I::from_u32) {
Expand Down Expand Up @@ -269,48 +269,42 @@ pub fn to_signed_with_radix<I: MinNumTraits>(bytes: &[u8], radix: u32) -> Result
}

/// minimal subset of traits used by [`to_signed_with_radix`] and [`to_unsigned_with_radix`]
pub trait MinNumTraits: Sized + Copy {
///
fn from_u32(n: u32) -> Option<Self>;
///
fn zero() -> Self;
///
fn checked_mul(self, v: Self) -> Option<Self>;
///
fn checked_add(self, v: Self) -> Option<Self>;
///
pub trait MinNumTraits: Sized + Copy + TryFrom<u32> {
/// the 0 value for this type
const ZERO: Self;
/// convert from a unsinged 32-bit word
fn from_u32(n: u32) -> Option<Self> {
Self::try_from(n).ok()
}
/// the checked multiplication operation for this type
fn checked_mul(self, rhs: Self) -> Option<Self>;
/// the chekced addition operation for this type
fn checked_add(self, rhs: Self) -> Option<Self>;
/// the checked subtraction operation for this type
fn checked_sub(self, v: Self) -> Option<Self>;
}

macro_rules! impl_checked {
($f:ident) => {
fn $f(self, rhs: Self) -> Option<Self> {
Self::$f(self, rhs)
}
};
}

macro_rules! min_num_traits {
($t : ty, from_u32 => $from_u32 : expr) => {
($t:ty) => {
impl MinNumTraits for $t {
fn from_u32(n: u32) -> Option<$t> {
#[allow(clippy::redundant_closure_call)]
$from_u32(n)
}

fn zero() -> Self {
0
}

fn checked_mul(self, v: $t) -> Option<$t> {
<$t>::checked_mul(self, v)
}

fn checked_add(self, v: $t) -> Option<$t> {
<$t>::checked_add(self, v)
}

fn checked_sub(self, v: $t) -> Option<$t> {
<$t>::checked_sub(self, v)
}
const ZERO: Self = 0;
impl_checked!(checked_add);
impl_checked!(checked_mul);
impl_checked!(checked_sub);
}
};
}

min_num_traits!(i32, from_u32 => |n: u32| n.try_into().ok());
min_num_traits!(i64, from_u32 => |n: u32| Some(n.into()));
min_num_traits!(u64, from_u32 => |n: u32| Some(n.into()));
min_num_traits!(u8, from_u32 => |n: u32| n.try_into().ok());
min_num_traits!(usize, from_u32 => |n: u32| n.try_into().ok());
min_num_traits!(i32);
min_num_traits!(i64);
min_num_traits!(u64);
min_num_traits!(u8);
min_num_traits!(usize);