pub trait Number:
num_traits::Num
+ num_traits::ToPrimitive
+ num_traits::NumCast
+ num_traits::Zero
+ std::ops::Add
+ std::ops::AddAssign
+ std::iter::Sum
+ std::ops::Sub
+ std::ops::SubAssign
+ num_traits::One
+ std::ops::Mul
+ std::ops::MulAssign
+ std::ops::Div
+ std::ops::DivAssign
+ std::ops::Rem
+ std::ops::RemAssign
+ Copy
+ Clone
+ PartialOrd
+ Send
+ Sync
+ std::fmt::Debug
+ std::fmt::Display
{
fn num_bytes() -> usize;
fn to_le_bytes(&self) -> Vec<u8>;
fn from_le_bytes(bytes: &[u8]) -> Result<Self, String>;
fn to_be_bytes(&self) -> Vec<u8>;
fn from_be_bytes(bytes: &[u8]) -> Result<Self, String>;
fn as_f64(&self) -> f64;
fn as_f32(&self) -> f32;
fn as_i64(&self) -> i64;
fn as_u64(&self) -> u64;
}
macro_rules! impl_number {
($($ty:ty),*) => {
$(
impl Number for $ty {
fn num_bytes() -> usize {
(0 as $ty).to_be_bytes().to_vec().len()
}
fn to_le_bytes(&self) -> Vec<u8> {
<$ty>::to_le_bytes(*self).to_vec()
}
fn to_be_bytes(&self) -> Vec<u8> {
<$ty>::to_be_bytes(*self).to_vec()
}
fn from_le_bytes(bytes: &[u8]) -> Result<Self, String> {
let (value, _) = bytes.split_at(std::mem::size_of::<$ty>());
Ok(<$ty>::from_le_bytes(value.try_into().map_err(|reason| {
format!("Could not construct Number from bytes {:?} because {}", value, reason)
})?))
}
fn from_be_bytes(bytes: &[u8]) -> Result<Self, String> {
let (value, _) = bytes.split_at(std::mem::size_of::<$ty>());
Ok(<$ty>::from_be_bytes(value.try_into().map_err(|reason| {
format!("Could not construct Number from bytes {:?} because {}", value, reason)
})?))
}
fn as_f64(&self) -> f64 {
*self as f64
}
fn as_f32(&self) -> f32 {
*self as f32
}
fn as_i64(&self) -> i64 {
*self as i64
}
fn as_u64(&self) -> u64 {
*self as u64
}
}
)*
}
}
impl_number!(f32, f64, u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, isize, usize);