mod impls;
mod number_writer;
mod tests;
use {
core::{
convert::TryFrom,
fmt::{self, Display, Formatter},
},
crate::Error,
};
#[cfg(feature="std")]
pub use self::number_writer::*;
#[derive(Debug, Clone)]
pub struct Number {
inner: Inner,
}
#[derive(Debug, Clone)]
enum Inner {
I8(i8), I16(i16), I32(i32), I64(i64), I128(i128), ISize(isize),
U8(u8), U16(u16), U32(u32), U64(u64), U128(u128), USize(usize),
F32(f32), F64(f64),
}
impl Display for Number {
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
match self.inner {
Inner::I8(i) => i.fmt(f),
Inner::U8(u) => u.fmt(f),
Inner::I16(i) => i.fmt(f),
Inner::U16(u) => u.fmt(f),
Inner::I32(i) => i.fmt(f),
Inner::U32(u) => u.fmt(f),
Inner::I64(i) => i.fmt(f),
Inner::U64(u) => u.fmt(f),
Inner::I128(i) => i.fmt(f),
Inner::U128(u) => u.fmt(f),
Inner::ISize(i) => i.fmt(f),
Inner::USize(u) => u.fmt(f),
Inner::F32(x) => x.fmt(f),
Inner::F64(x) => x.fmt(f),
}
}
}
macro_rules! impl_from_primitives_for_number { ($($ty: ty, $code: tt,)+) => {
$(
impl From<$ty> for Number {
fn from(n: $ty) -> Self {
Self {
inner: Inner::$code(n),
}
}
}
)+
}}
impl_from_primitives_for_number! {
i8, I8, i16, I16, i32, I32, i64, I64, i128, I128, isize, ISize,
u8, U8, u16, U16, u32, U32, u64, U64, u128, U128, usize, USize,
f32, F32, f64, F64,
}
macro_rules! impl_try_from_number_for_integers { ($($ty: ty,)+) => {
$(
impl TryFrom<&Number> for $ty {
type Error = Error;
fn try_from(n: &Number) -> Result<Self, Self::Error> {
match n.inner {
Inner::I8(i) => Self::try_from(i).map_err(|e| Error::from(__!("{}", e))),
Inner::I16(i) => Self::try_from(i).map_err(|e| Error::from(__!("{}", e))),
Inner::I32(i) => Self::try_from(i).map_err(|e| Error::from(__!("{}", e))),
Inner::I64(i) => Self::try_from(i).map_err(|e| Error::from(__!("{}", e))),
Inner::I128(i) => Self::try_from(i).map_err(|e| Error::from(__!("{}", e))),
Inner::ISize(i) => Self::try_from(i).map_err(|e| Error::from(__!("{}", e))),
Inner::U8(u) => Self::try_from(u).map_err(|e| Error::from(__!("{}", e))),
Inner::U16(u) => Self::try_from(u).map_err(|e| Error::from(__!("{}", e))),
Inner::U32(u) => Self::try_from(u).map_err(|e| Error::from(__!("{}", e))),
Inner::U64(u) => Self::try_from(u).map_err(|e| Error::from(__!("{}", e))),
Inner::U128(u) => Self::try_from(u).map_err(|e| Error::from(__!("{}", e))),
Inner::USize(u) => Self::try_from(u).map_err(|e| Error::from(__!("{}", e))),
_ => Err(Error::from(__!("Floating numbers are not supported"))),
}
}
}
impl TryFrom<Number> for $ty {
type Error = Error;
fn try_from(n: Number) -> Result<Self, Self::Error> {
Self::try_from(&n)
}
}
)+
}}
impl_try_from_number_for_integers! {
i8, i16, i32, i64, i128, isize,
u8, u16, u32, u64, u128, usize,
}
impl TryFrom<&Number> for f32 {
type Error = Error;
fn try_from(n: &Number) -> Result<Self, Self::Error> {
match n.inner {
Inner::I8(i) => Ok(Self::from(i)),
Inner::I16(i) => Ok(Self::from(i)),
Inner::U8(u) => Ok(Self::from(u)),
Inner::U16(u) => Ok(Self::from(u)),
Inner::F32(f) => Ok(f),
_ => Err(Error::from(__!("Not supported"))),
}
}
}
impl TryFrom<Number> for f32 {
type Error = Error;
fn try_from(n: Number) -> Result<Self, Self::Error> {
Self::try_from(&n)
}
}
impl TryFrom<&Number> for f64 {
type Error = Error;
fn try_from(n: &Number) -> Result<Self, Self::Error> {
match n.inner {
Inner::I8(i) => Ok(Self::from(i)),
Inner::I16(i) => Ok(Self::from(i)),
Inner::I32(i) => Ok(Self::from(i)),
Inner::U8(u) => Ok(Self::from(u)),
Inner::U16(u) => Ok(Self::from(u)),
Inner::U32(u) => Ok(Self::from(u)),
Inner::F32(f) => Ok(Self::from(f)),
Inner::F64(f) => Ok(f),
_ => Err(Error::from(__!("Not supported"))),
}
}
}
impl TryFrom<Number> for f64 {
type Error = Error;
fn try_from(n: Number) -> Result<Self, Self::Error> {
Self::try_from(&n)
}
}