1use num_traits::float::FloatCore;
2
3pub trait RealType: Sized + core::fmt::Debug + core::fmt::Display {
6 const BYTE_WIDTH: usize;
8
9 const INFINITY: Self;
11
12 const NEG_INFINITY: Self;
14
15 const NAN: Self;
17
18 fn to_ieee754_bytes(&self) -> (impl AsRef<[u8]>, usize);
20
21 fn try_from_ieee754_bytes(bytes: &[u8]) -> Result<Self, TryFromRealError>;
23
24 fn try_from_float(value: impl FloatCore) -> Option<Self>;
26
27 fn try_to_float(&self) -> Option<impl FloatCore>;
29
30 fn is_infinity(&self) -> bool;
32
33 fn is_neg_infinity(&self) -> bool;
35
36 fn is_nan(&self) -> bool;
38}
39
40#[cfg(feature = "f64")]
41impl RealType for f64 {
42 const BYTE_WIDTH: usize = core::mem::size_of::<Self>();
43 const INFINITY: Self = Self::INFINITY;
44 const NEG_INFINITY: Self = Self::NEG_INFINITY;
45 const NAN: Self = Self::NAN;
46
47 #[inline]
48 fn to_ieee754_bytes(&self) -> (impl AsRef<[u8]>, usize) {
49 let bytes = self.to_be_bytes();
50 (bytes, bytes.len())
51 }
52
53 #[inline]
54 fn try_from_ieee754_bytes(bytes: &[u8]) -> Result<Self, TryFromRealError> {
55 let bytes = bytes
56 .try_into()
57 .map_err(|_| TryFromRealError::InvalidEncoding)?;
58
59 Ok(f64::from_be_bytes(bytes))
60 }
61
62 fn try_from_float(value: impl FloatCore) -> Option<Self> {
63 value.to_f64()
64 }
65
66 fn try_to_float(&self) -> Option<impl FloatCore> {
67 Some(*self)
68 }
69
70 #[inline]
71 fn is_infinity(&self) -> bool {
72 *self == Self::INFINITY
73 }
74
75 #[inline]
76 fn is_neg_infinity(&self) -> bool {
77 *self == Self::NEG_INFINITY
78 }
79
80 #[inline]
81 fn is_nan(&self) -> bool {
82 Self::is_nan(*self)
83 }
84}
85
86#[cfg(feature = "f32")]
87impl RealType for f32 {
88 const BYTE_WIDTH: usize = core::mem::size_of::<Self>();
89 const INFINITY: Self = Self::INFINITY;
90 const NEG_INFINITY: Self = Self::NEG_INFINITY;
91 const NAN: Self = Self::NAN;
92
93 #[inline]
94 fn to_ieee754_bytes(&self) -> (impl AsRef<[u8]>, usize) {
95 let bytes = self.to_be_bytes();
96 (bytes, bytes.len())
97 }
98
99 #[inline]
100 fn try_from_ieee754_bytes(bytes: &[u8]) -> Result<Self, TryFromRealError> {
101 let bytes = bytes
102 .try_into()
103 .map_err(|_| TryFromRealError::InvalidEncoding)?;
104
105 Ok(f32::from_be_bytes(bytes))
106 }
107
108 fn try_from_float(value: impl FloatCore) -> Option<Self> {
109 value.to_f32()
110 }
111
112 fn try_to_float(&self) -> Option<impl FloatCore> {
113 Some(*self)
114 }
115
116 #[inline]
117 fn is_infinity(&self) -> bool {
118 *self == Self::INFINITY
119 }
120
121 #[inline]
122 fn is_neg_infinity(&self) -> bool {
123 *self == Self::NEG_INFINITY
124 }
125
126 #[inline]
127 fn is_nan(&self) -> bool {
128 Self::is_nan(*self)
129 }
130}
131
132#[derive(Debug, Clone, PartialEq, Eq)]
133pub enum TryFromRealError {
134 InvalidEncoding,
135}