use core::{
fmt::{Debug, Display},
str::FromStr,
};
use super::{Addition, Multiplication};
pub trait Number:
Addition + Multiplication + PartialEq + Clone + Send + Sync + Debug + Display + Default + FromStr
{
const MIN: Self;
const MAX: Self;
const EPSILON: Self;
const NUM_BYTES: usize;
#[deprecated(since = "1.8.0", note = "Use `Number::ZERO` instead")]
#[must_use]
fn zero() -> Self {
Self::ZERO
}
#[deprecated(since = "1.8.0", note = "Use `Number::ONE` instead")]
#[must_use]
fn one() -> Self {
Self::ONE
}
#[deprecated(since = "1.8.0", note = "Use `Number::MIN` instead")]
#[must_use]
fn min_value() -> Self {
Self::MIN
}
#[deprecated(since = "1.8.0", note = "Use `Number::MAX` instead")]
#[must_use]
fn max_value() -> Self {
Self::MAX
}
#[deprecated(since = "1.8.0", note = "Use `Number::EPSILON` instead")]
#[must_use]
fn epsilon() -> Self {
Self::EPSILON
}
fn from<T: Number>(n: T) -> Self;
fn as_f32(self) -> f32;
fn as_f64(self) -> f64;
fn as_u64(self) -> u64;
fn as_i64(self) -> i64;
fn as_u32(self) -> u32;
fn as_i32(self) -> i32;
#[deprecated(since = "1.8.0", note = "Use `Number::NUM_BYTES` instead")]
#[must_use]
fn num_bytes() -> usize {
Self::NUM_BYTES
}
fn from_le_bytes(bytes: &[u8]) -> Self;
fn to_le_bytes(self) -> Vec<u8>;
fn from_be_bytes(bytes: &[u8]) -> Self;
fn to_be_bytes(self) -> Vec<u8>;
#[must_use]
fn type_name<'a>() -> &'a str {
core::any::type_name::<Self>()
}
fn next_random<R: rand::Rng>(rng: &mut R) -> Self;
}
impl Number for f32 {
const MAX: Self = Self::MAX;
const MIN: Self = Self::MIN;
const EPSILON: Self = Self::EPSILON;
const NUM_BYTES: usize = core::mem::size_of::<Self>();
fn as_f32(self) -> f32 {
self
}
fn from<T: Number>(n: T) -> Self {
n.as_f32()
}
#[allow(clippy::cast_lossless)]
fn as_f64(self) -> f64 {
self as f64
}
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
fn as_u64(self) -> u64 {
self as u64
}
#[allow(clippy::cast_possible_truncation)]
fn as_i64(self) -> i64 {
self as i64
}
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
fn as_u32(self) -> u32 {
self as u32
}
#[allow(clippy::cast_possible_truncation)]
fn as_i32(self) -> i32 {
self as i32
}
fn from_le_bytes(bytes: &[u8]) -> Self {
let mut ty_bytes = [0_u8; 4];
ty_bytes.copy_from_slice(bytes);
Self::from_le_bytes(ty_bytes)
}
fn to_le_bytes(self) -> Vec<u8> {
self.to_le_bytes().to_vec()
}
fn from_be_bytes(bytes: &[u8]) -> Self {
let mut ty_bytes = [0_u8; 4];
ty_bytes.copy_from_slice(bytes);
Self::from_be_bytes(ty_bytes)
}
fn to_be_bytes(self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
fn next_random<R: rand::Rng>(rng: &mut R) -> Self {
rng.gen()
}
}
impl Number for f64 {
const MAX: Self = Self::MAX;
const MIN: Self = Self::MIN;
const EPSILON: Self = Self::EPSILON;
const NUM_BYTES: usize = core::mem::size_of::<Self>();
fn from<T: Number>(n: T) -> Self {
n.as_f64()
}
#[allow(clippy::cast_possible_truncation)]
fn as_f32(self) -> f32 {
self as f32
}
fn as_f64(self) -> f64 {
self
}
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
fn as_u64(self) -> u64 {
self as u64
}
#[allow(clippy::cast_possible_truncation)]
fn as_i64(self) -> i64 {
self as i64
}
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
fn as_u32(self) -> u32 {
self as u32
}
#[allow(clippy::cast_possible_truncation)]
fn as_i32(self) -> i32 {
self as i32
}
fn from_le_bytes(bytes: &[u8]) -> Self {
let mut ty_bytes = [0_u8; 8];
ty_bytes.copy_from_slice(bytes);
Self::from_le_bytes(ty_bytes)
}
fn to_le_bytes(self) -> Vec<u8> {
self.to_le_bytes().to_vec()
}
fn from_be_bytes(bytes: &[u8]) -> Self {
let mut ty_bytes = [0_u8; 8];
ty_bytes.copy_from_slice(bytes);
Self::from_be_bytes(ty_bytes)
}
fn to_be_bytes(self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
fn next_random<R: rand::Rng>(rng: &mut R) -> Self {
rng.gen()
}
}
macro_rules! impl_number_iint {
($($ty:ty),*) => {
$(
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss, clippy::cast_precision_loss, clippy::cast_lossless)]
impl Number for $ty {
const MAX: Self = <$ty>::MAX;
const MIN: Self = <$ty>::MIN;
const EPSILON: Self = 1;
const NUM_BYTES: usize = core::mem::size_of::<$ty>();
fn from<T: Number>(n: T) -> Self {
n.as_i64() as $ty
}
fn as_f32(self) -> f32 {
self as f32
}
fn as_f64(self) -> f64 {
self as f64
}
fn as_u64(self) -> u64 {
self as u64
}
fn as_i64(self) -> i64 {
self as i64
}
fn as_u32(self) -> u32 {
self as u32
}
fn as_i32(self) -> i32 {
self as i32
}
fn from_le_bytes(bytes: &[u8]) -> Self {
let mut ty_bytes = [0_u8; core::mem::size_of::<$ty>()];
ty_bytes.copy_from_slice(bytes);
Self::from_le_bytes(ty_bytes)
}
fn to_le_bytes(self) -> Vec<u8> {
self.to_le_bytes().to_vec()
}
fn from_be_bytes(bytes: &[u8]) -> Self {
let mut ty_bytes = [0_u8; core::mem::size_of::<$ty>()];
ty_bytes.copy_from_slice(bytes);
Self::from_be_bytes(ty_bytes)
}
fn to_be_bytes(self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
fn next_random<R: rand::Rng>(rng: &mut R) -> Self {
rng.gen()
}
}
)*
}
}
impl_number_iint!(i8, i16, i32, i64, i128, isize);
macro_rules! impl_number_uint {
($($ty:ty),*) => {
$(
#[allow(clippy::cast_possible_truncation, clippy::cast_lossless, clippy::cast_precision_loss)]
impl Number for $ty {
const MAX: Self = <$ty>::MAX;
const MIN: Self = <$ty>::MIN;
const EPSILON: Self = 1;
const NUM_BYTES: usize = core::mem::size_of::<$ty>();
fn from<T: Number>(n: T) -> Self {
n.as_u64() as $ty
}
fn as_f32(self) -> f32 {
self as f32
}
fn as_f64(self) -> f64 {
self as f64
}
fn as_u64(self) -> u64 {
self as u64
}
#[allow(clippy::cast_possible_wrap)]
fn as_i64(self) -> i64 {
self as i64
}
fn as_u32(self) -> u32 {
self as u32
}
#[allow(clippy::cast_possible_wrap)]
fn as_i32(self) -> i32 {
self as i32
}
fn from_le_bytes(bytes: &[u8]) -> Self {
let mut ty_bytes = [0_u8; core::mem::size_of::<$ty>()];
ty_bytes.copy_from_slice(bytes);
Self::from_le_bytes(ty_bytes)
}
fn to_le_bytes(self) -> Vec<u8> {
self.to_le_bytes().to_vec()
}
fn from_be_bytes(bytes: &[u8]) -> Self {
let mut ty_bytes = [0_u8; core::mem::size_of::<$ty>()];
ty_bytes.copy_from_slice(bytes);
Self::from_be_bytes(ty_bytes)
}
fn to_be_bytes(self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
fn next_random<R: rand::Rng>(rng: &mut R) -> Self {
rng.gen()
}
}
)*
}
}
impl_number_uint!(u8, u16, u32, u64, u128, usize);