Refactor SignedInteger conversions to be more comprehensive and less repetitive

This commit is contained in:
Tony Garnock-Jones 2021-08-28 17:01:59 +02:00
parent 3cdf1f662e
commit 8550be0ba2
1 changed files with 65 additions and 60 deletions

View File

@ -81,29 +81,44 @@ impl SignedInteger {
}
}
impl From<i32> for SignedInteger {
fn from(v: i32) -> Self {
SignedInteger(SignedIntegerRepr::I128(v.into()))
//--
macro_rules! map_integral_type_to_signed_integer {
($iN:ident, $uN:ident) => {
impl From<$iN> for SignedInteger {
fn from(v: $iN) -> Self {
SignedInteger(SignedIntegerRepr::I128(v.into()))
}
}
impl From<$uN> for SignedInteger {
fn from(v: $uN) -> Self {
SignedInteger(SignedIntegerRepr::I128(v.into()))
}
}
impl TryFrom<&SignedInteger> for $iN {
type Error = ();
fn try_from(v: &SignedInteger) -> Result<Self, Self::Error> {
i128::try_from(v)?.try_into().map_err(|_| ())
}
}
impl TryFrom<&SignedInteger> for $uN {
type Error = ();
fn try_from(v: &SignedInteger) -> Result<Self, Self::Error> {
u128::try_from(v)?.try_into().map_err(|_| ())
}
}
}
}
impl From<u32> for SignedInteger {
fn from(v: u32) -> Self {
SignedInteger(SignedIntegerRepr::I128(v.into()))
}
}
map_integral_type_to_signed_integer!(i8, u8);
map_integral_type_to_signed_integer!(i16, u16);
map_integral_type_to_signed_integer!(i32, u32);
map_integral_type_to_signed_integer!(i64, u64);
impl From<i64> for SignedInteger {
fn from(v: i64) -> Self {
SignedInteger(SignedIntegerRepr::I128(v.into()))
}
}
impl From<u64> for SignedInteger {
fn from(v: u64) -> Self {
SignedInteger(SignedIntegerRepr::I128(v.into()))
}
}
//--
impl From<i128> for SignedInteger {
fn from(v: i128) -> Self {
@ -121,24 +136,6 @@ impl From<u128> for SignedInteger {
}
}
impl From<BigInt> for SignedInteger {
fn from(v: BigInt) -> Self {
Self::from(Cow::Owned(v))
}
}
impl<'a> From<Cow<'a, BigInt>> for SignedInteger {
fn from(v: Cow<'a, BigInt>) -> Self {
if let Some(w) = v.to_i128() {
SignedInteger(SignedIntegerRepr::I128(w))
} else if let Some(w) = v.to_u128() {
SignedInteger(SignedIntegerRepr::U128(w))
} else {
SignedInteger(SignedIntegerRepr::Big(Box::new(v.into_owned())))
}
}
}
impl TryFrom<&SignedInteger> for i128 {
type Error = ();
fn try_from(v: &SignedInteger) -> Result<Self, Self::Error> {
@ -161,13 +158,11 @@ impl TryFrom<&SignedInteger> for u128 {
}
}
impl<'a> From<&'a SignedInteger> for Cow<'a, BigInt> {
fn from(v: &'a SignedInteger) -> Self {
match v.repr() {
SignedIntegerRepr::I128(i) => Cow::Owned(BigInt::from(*i)),
SignedIntegerRepr::U128(u) => Cow::Owned(BigInt::from(*u)),
SignedIntegerRepr::Big(n) => Cow::Borrowed(n),
}
//--
impl From<BigInt> for SignedInteger {
fn from(v: BigInt) -> Self {
Self::from(Cow::Owned(v))
}
}
@ -181,31 +176,41 @@ impl<'a> From<&'a SignedInteger> for BigInt {
}
}
impl TryFrom<&SignedInteger> for i32 {
type Error = ();
fn try_from(v: &SignedInteger) -> Result<Self, Self::Error> {
i128::try_from(v)?.try_into().map_err(|_| ())
//--
impl<'a> From<Cow<'a, BigInt>> for SignedInteger {
fn from(v: Cow<'a, BigInt>) -> Self {
if let Some(w) = v.to_i128() {
SignedInteger(SignedIntegerRepr::I128(w))
} else if let Some(w) = v.to_u128() {
SignedInteger(SignedIntegerRepr::U128(w))
} else {
SignedInteger(SignedIntegerRepr::Big(Box::new(v.into_owned())))
}
}
}
impl TryFrom<&SignedInteger> for u32 {
type Error = ();
fn try_from(v: &SignedInteger) -> Result<Self, Self::Error> {
u128::try_from(v)?.try_into().map_err(|_| ())
impl<'a> From<&'a SignedInteger> for Cow<'a, BigInt> {
fn from(v: &'a SignedInteger) -> Self {
match v.repr() {
SignedIntegerRepr::I128(i) => Cow::Owned(BigInt::from(*i)),
SignedIntegerRepr::U128(u) => Cow::Owned(BigInt::from(*u)),
SignedIntegerRepr::Big(n) => Cow::Borrowed(n),
}
}
}
impl TryFrom<&SignedInteger> for i64 {
type Error = ();
fn try_from(v: &SignedInteger) -> Result<Self, Self::Error> {
i128::try_from(v)?.try_into().map_err(|_| ())
//--
impl From<isize> for SignedInteger {
fn from(v: isize) -> Self {
SignedInteger(SignedIntegerRepr::I128(v as i128))
}
}
impl TryFrom<&SignedInteger> for u64 {
type Error = ();
fn try_from(v: &SignedInteger) -> Result<Self, Self::Error> {
u128::try_from(v)?.try_into().map_err(|_| ())
impl From<usize> for SignedInteger {
fn from(v: usize) -> Self {
SignedInteger(SignedIntegerRepr::U128(v as u128))
}
}