use std::fmt::{Debug, Display};
use std::hash::Hash;
use num_traits::ops::wrapping::{
WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub,
};
use num_traits::{AsPrimitive, FromPrimitive, PrimInt, Signed, ToPrimitive, Unsigned};
pub trait Number: PrimInt + Default + Debug + AsPrimitive<usize> + ToPrimitive {}
impl<All: PrimInt + Default + Debug + AsPrimitive<usize> + ToPrimitive> Number for All {}
pub trait SignedNumber: Number + Signed + FromPrimitive {}
impl<All: Number + Signed + FromPrimitive> SignedNumber for All {}
pub trait ToSigned {
type Type: Number + Signed;
fn to_signed(&self) -> Self::Type;
}
macro_rules! signed_type_impl {
($U:ty, $S:ty) => {
impl ToSigned for $U {
type Type = $S;
fn to_signed(&self) -> Self::Type {
*self as Self::Type
}
}
};
}
signed_type_impl!(i8, i8);
signed_type_impl!(u8, i8);
signed_type_impl!(i16, i16);
signed_type_impl!(u16, i16);
signed_type_impl!(i32, i32);
signed_type_impl!(u32, i32);
signed_type_impl!(i64, i64);
signed_type_impl!(u64, i64);
signed_type_impl!(i128, i128);
signed_type_impl!(u128, i128);
signed_type_impl!(isize, isize);
signed_type_impl!(usize, isize);
pub trait MaxValue {
const MAX: Self;
}
macro_rules! for_each_integer_type {
($macro:ident) => {
$macro!(i8);
$macro!(u8);
$macro!(i16);
$macro!(u16);
$macro!(i32);
$macro!(u32);
$macro!(i64);
$macro!(u64);
$macro!(i128);
$macro!(u128);
$macro!(isize);
$macro!(usize);
};
}
macro_rules! max_value_impl {
($T:ty) => {
impl MaxValue for $T {
const MAX: Self = <$T>::MAX;
}
};
}
for_each_integer_type!(max_value_impl);
pub trait WrappingArithmetic:
WrappingAdd + WrappingSub + WrappingMul + WrappingNeg + WrappingShl + WrappingShr
{
}
impl<All: WrappingAdd + WrappingSub + WrappingMul + WrappingNeg + WrappingShl + WrappingShr>
WrappingArithmetic for All
{
}
#[rustfmt::skip]
pub trait LinkReference:
Sized
+ Number
+ Unsigned
+ ToSigned
+ MaxValue
+ WrappingArithmetic
+ FromPrimitive
+ TryFrom<i8, Error: Debug>
+ TryFrom<u8, Error: Debug>
+ TryFrom<i16, Error: Debug>
+ TryFrom<u16, Error: Debug>
+ TryFrom<i32, Error: Debug>
+ TryFrom<u32, Error: Debug>
+ TryFrom<i64, Error: Debug>
+ TryFrom<u64, Error: Debug>
+ TryFrom<i128, Error: Debug>
+ TryFrom<u128, Error: Debug>
+ TryFrom<isize, Error: Debug>
+ TryFrom<usize, Error: Debug>
+ TryInto<i8, Error: Debug>
+ TryInto<u8, Error: Debug>
+ TryInto<i16, Error: Debug>
+ TryInto<u16, Error: Debug>
+ TryInto<i32, Error: Debug>
+ TryInto<u32, Error: Debug>
+ TryInto<i64, Error: Debug>
+ TryInto<u64, Error: Debug>
+ TryInto<i128, Error: Debug>
+ TryInto<u128, Error: Debug>
+ TryInto<isize, Error: Debug>
+ TryInto<usize, Error: Debug>
+ Debug
+ Display
+ Hash
+ Send
+ Sync
+ 'static
{
fn from_byte(n: u8) -> Self {
Self::try_from(n).unwrap_or_else(|e| {
panic!("LinkReference::from_byte({n}) failed: {e:?}")
})
}
}
#[rustfmt::skip]
impl<
All: Sized
+ Number
+ Unsigned
+ ToSigned
+ MaxValue
+ WrappingArithmetic
+ FromPrimitive
+ TryFrom<i8, Error: Debug>
+ TryFrom<u8, Error: Debug>
+ TryFrom<i16, Error: Debug>
+ TryFrom<u16, Error: Debug>
+ TryFrom<i32, Error: Debug>
+ TryFrom<u32, Error: Debug>
+ TryFrom<i64, Error: Debug>
+ TryFrom<u64, Error: Debug>
+ TryFrom<i128, Error: Debug>
+ TryFrom<u128, Error: Debug>
+ TryFrom<isize, Error: Debug>
+ TryFrom<usize, Error: Debug>
+ TryInto<i8, Error: Debug>
+ TryInto<u8, Error: Debug>
+ TryInto<i16, Error: Debug>
+ TryInto<u16, Error: Debug>
+ TryInto<i32, Error: Debug>
+ TryInto<u32, Error: Debug>
+ TryInto<i64, Error: Debug>
+ TryInto<u64, Error: Debug>
+ TryInto<i128, Error: Debug>
+ TryInto<u128, Error: Debug>
+ TryInto<isize, Error: Debug>
+ TryInto<usize, Error: Debug>
+ Debug
+ Display
+ Hash
+ Send
+ Sync
+ 'static,
> LinkReference for All {}