use num_traits::float::FloatCore;
pub trait RealType: Sized + core::fmt::Debug + core::fmt::Display {
const BYTE_WIDTH: usize;
const INFINITY: Self;
const NEG_INFINITY: Self;
const NAN: Self;
fn to_ieee754_bytes(&self) -> (impl AsRef<[u8]>, usize);
fn try_from_ieee754_bytes(bytes: &[u8]) -> Result<Self, TryFromRealError>;
fn try_from_float(value: impl FloatCore) -> Option<Self>;
fn try_to_float(&self) -> Option<impl FloatCore>;
fn is_infinity(&self) -> bool;
fn is_neg_infinity(&self) -> bool;
fn is_nan(&self) -> bool;
}
#[cfg(feature = "f64")]
impl RealType for f64 {
const BYTE_WIDTH: usize = core::mem::size_of::<Self>();
const INFINITY: Self = Self::INFINITY;
const NEG_INFINITY: Self = Self::NEG_INFINITY;
const NAN: Self = Self::NAN;
#[inline]
fn to_ieee754_bytes(&self) -> (impl AsRef<[u8]>, usize) {
let bytes = self.to_be_bytes();
(bytes, bytes.len())
}
#[inline]
fn try_from_ieee754_bytes(bytes: &[u8]) -> Result<Self, TryFromRealError> {
let bytes = bytes
.try_into()
.map_err(|_| TryFromRealError::InvalidEncoding)?;
Ok(f64::from_be_bytes(bytes))
}
fn try_from_float(value: impl FloatCore) -> Option<Self> {
value.to_f64()
}
fn try_to_float(&self) -> Option<impl FloatCore> {
Some(*self)
}
#[inline]
fn is_infinity(&self) -> bool {
*self == Self::INFINITY
}
#[inline]
fn is_neg_infinity(&self) -> bool {
*self == Self::NEG_INFINITY
}
#[inline]
fn is_nan(&self) -> bool {
Self::is_nan(*self)
}
}
#[cfg(feature = "f32")]
impl RealType for f32 {
const BYTE_WIDTH: usize = core::mem::size_of::<Self>();
const INFINITY: Self = Self::INFINITY;
const NEG_INFINITY: Self = Self::NEG_INFINITY;
const NAN: Self = Self::NAN;
#[inline]
fn to_ieee754_bytes(&self) -> (impl AsRef<[u8]>, usize) {
let bytes = self.to_be_bytes();
(bytes, bytes.len())
}
#[inline]
fn try_from_ieee754_bytes(bytes: &[u8]) -> Result<Self, TryFromRealError> {
let bytes = bytes
.try_into()
.map_err(|_| TryFromRealError::InvalidEncoding)?;
Ok(f32::from_be_bytes(bytes))
}
fn try_from_float(value: impl FloatCore) -> Option<Self> {
value.to_f32()
}
fn try_to_float(&self) -> Option<impl FloatCore> {
Some(*self)
}
#[inline]
fn is_infinity(&self) -> bool {
*self == Self::INFINITY
}
#[inline]
fn is_neg_infinity(&self) -> bool {
*self == Self::NEG_INFINITY
}
#[inline]
fn is_nan(&self) -> bool {
Self::is_nan(*self)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TryFromRealError {
InvalidEncoding,
}