use crate::traits::FixedEquiv;
#[cfg(feature = "arbitrary")]
use arbitrary::Arbitrary;
use az::{
Cast, CastFrom, CheckedCast, CheckedCastFrom, OverflowingCast, OverflowingCastFrom,
SaturatingCast, SaturatingCastFrom, UnwrappedCast, UnwrappedCastFrom, WrappingCast,
WrappingCastFrom,
};
#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
use bytemuck::{Contiguous, Pod};
use core::{
fmt::{Binary, Debug, Display, LowerExp, LowerHex, Octal, UpperExp, UpperHex},
hash::Hash,
iter::{Product, Sum},
num::ParseIntError,
ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
SubAssign,
},
str::FromStr,
};
#[cfg(feature = "num-traits")]
use num_traits::{
cast::{AsPrimitive, FromPrimitive},
int::PrimInt,
ops::{
checked::{CheckedNeg, CheckedRem, CheckedShl, CheckedShr},
euclid::{CheckedEuclid, Euclid},
mul_add::{MulAdd, MulAddAssign},
overflowing::{OverflowingAdd, OverflowingMul, OverflowingSub},
saturating::{SaturatingAdd, SaturatingMul, SaturatingSub},
wrapping::{WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub},
},
Num, NumAssignRef, NumRef,
};
#[cfg(feature = "serde")]
use serde::{de::Deserialize, ser::Serialize};
macro_rules! impl_bits {
($Bits:ident) => {
impl FixedBits for $Bits {
const MIN: $Bits = $Bits::MIN;
const MAX: $Bits = $Bits::MAX;
const IS_SIGNED: bool = $Bits::MIN != 0;
const BITS: u32 = $Bits::BITS;
}
impl Sealed for $Bits {}
impl FixedBitsCast<i8> for $Bits {}
impl FixedBitsCast<i16> for $Bits {}
impl FixedBitsCast<i32> for $Bits {}
impl FixedBitsCast<i64> for $Bits {}
impl FixedBitsCast<i128> for $Bits {}
impl FixedBitsCast<isize> for $Bits {}
impl FixedBitsCast<u8> for $Bits {}
impl FixedBitsCast<u16> for $Bits {}
impl FixedBitsCast<u32> for $Bits {}
impl FixedBitsCast<u64> for $Bits {}
impl FixedBitsCast<u128> for $Bits {}
impl FixedBitsCast<usize> for $Bits {}
impl FixedBitsOptionalArbitrary for $Bits {}
impl FixedBitsOptionalBorsh for $Bits {}
impl FixedBitsOptionalNum for $Bits {}
impl FixedBitsOptionalSerde for $Bits {}
};
}
pub trait FixedBits
where
Self: Default + Hash + Ord,
Self: Contiguous + Pod,
Self: Debug + Display + LowerExp + UpperExp,
Self: Binary + Octal + LowerHex + UpperHex,
Self: FromStr<Err = ParseIntError>,
Self: Add<Output = Self> + AddAssign,
Self: Sub<Output = Self> + SubAssign,
Self: Mul<Output = Self> + MulAssign,
Self: Div<Output = Self> + DivAssign,
Self: Rem<Output = Self> + RemAssign,
Self: Not<Output = Self>,
Self: BitAnd<Output = Self> + BitAndAssign,
Self: BitOr<Output = Self> + BitOrAssign,
Self: BitXor<Output = Self> + BitXorAssign,
Self: Shl<u32, Output = Self> + ShlAssign<u32>,
Self: Shr<u32, Output = Self> + ShrAssign<u32>,
Self: Sum + Product,
Self: FixedEquiv,
Self: FixedBitsCast<i8> + FixedBitsCast<i16> + FixedBitsCast<i32>,
Self: FixedBitsCast<i64> + FixedBitsCast<i128> + FixedBitsCast<isize>,
Self: FixedBitsCast<u8> + FixedBitsCast<u16> + FixedBitsCast<u32>,
Self: FixedBitsCast<u64> + FixedBitsCast<u128> + FixedBitsCast<usize>,
Self: FixedBitsOptionalArbitrary,
Self: FixedBitsOptionalBorsh,
Self: FixedBitsOptionalNum,
Self: FixedBitsOptionalSerde,
Self: Sealed,
{
const MIN: Self;
const MAX: Self;
const IS_SIGNED: bool;
const BITS: u32;
}
pub trait FixedBitsCast<Prim>
where
Self: TryInto<Prim> + TryFrom<Prim>,
Self: Cast<Prim> + CastFrom<Prim>,
Self: CheckedCast<Prim> + CheckedCastFrom<Prim>,
Self: SaturatingCast<Prim> + SaturatingCastFrom<Prim>,
Self: WrappingCast<Prim> + WrappingCastFrom<Prim>,
Self: UnwrappedCast<Prim> + UnwrappedCastFrom<Prim>,
Self: OverflowingCast<Prim> + OverflowingCastFrom<Prim>,
Self: Sealed,
{
}
pub trait Sealed {}
impl_bits! { i8 }
impl_bits! { i16 }
impl_bits! { i32 }
impl_bits! { i64 }
impl_bits! { i128 }
impl_bits! { u8 }
impl_bits! { u16 }
impl_bits! { u32 }
impl_bits! { u64 }
impl_bits! { u128 }
#[cfg(not(feature = "arbitrary"))]
pub trait FixedBitsOptionalArbitrary: Sealed {}
#[cfg(feature = "arbitrary")]
pub trait FixedBitsOptionalArbitrary: Sealed
where
Self: for<'a> Arbitrary<'a>,
{
}
#[cfg(not(feature = "borsh"))]
pub trait FixedBitsOptionalBorsh: Sealed {}
#[cfg(feature = "borsh")]
pub trait FixedBitsOptionalBorsh: Sealed
where
Self: BorshSerialize + BorshDeserialize,
{
}
#[cfg(not(feature = "num-traits"))]
pub trait FixedBitsOptionalNum: Sealed {}
#[cfg(feature = "num-traits")]
pub trait FixedBitsOptionalNum: Sealed
where
Self: Num<FromStrRadixErr = ParseIntError> + NumRef + NumAssignRef,
Self: PrimInt + FromPrimitive,
Self: AsPrimitive<i8> + AsPrimitive<i16> + AsPrimitive<i32>,
Self: AsPrimitive<i64> + AsPrimitive<i128> + AsPrimitive<isize>,
Self: AsPrimitive<u8> + AsPrimitive<u16> + AsPrimitive<u32>,
Self: AsPrimitive<u64> + AsPrimitive<u128> + AsPrimitive<usize>,
Self: AsPrimitive<f32> + AsPrimitive<f64>,
Self: CheckedNeg + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: OverflowingAdd + OverflowingSub + OverflowingMul,
Self: Euclid + CheckedEuclid,
Self: MulAdd + MulAddAssign,
{
}
#[cfg(not(feature = "serde"))]
pub trait FixedBitsOptionalSerde: Sealed {}
#[cfg(feature = "serde")]
pub trait FixedBitsOptionalSerde: Sealed
where
Self: Serialize + for<'de> Deserialize<'de>,
{
}