2015-10-04 02:59:26 -04:00
|
|
|
use std::cmp::PartialEq;
|
2015-10-09 13:02:54 -04:00
|
|
|
use std::mem::size_of;
|
2015-10-04 02:59:26 -04:00
|
|
|
use std::num::{Zero, One};
|
|
|
|
use std::ops::{Add, Sub, Mul, Div, Rem};
|
2015-12-31 02:58:21 -05:00
|
|
|
use std::str::FromStr;
|
2015-10-04 02:59:26 -04:00
|
|
|
|
2015-10-09 13:02:54 -04:00
|
|
|
use super::bounded::Bounded;
|
|
|
|
|
2015-10-04 02:59:26 -04:00
|
|
|
|
|
|
|
/// A trait that defines what is required to be considered
|
|
|
|
/// a number.
|
|
|
|
pub trait Number : Zero + One + Add<Output=Self> + Sub<Output=Self> +
|
|
|
|
Mul<Output=Self> + Div<Output=Self> + Rem<Output=Self> +
|
|
|
|
PartialEq + Copy + Clone
|
|
|
|
{
|
|
|
|
type StrRadixError;
|
|
|
|
|
2016-01-06 00:54:44 -05:00
|
|
|
|
2015-10-04 02:59:26 -04:00
|
|
|
/// Create a number from a given string and base radix.
|
2015-10-09 13:02:54 -04:00
|
|
|
///
|
|
|
|
///```
|
|
|
|
/// // Parse the hex value "FF" into an i32.
|
|
|
|
/// // Hex values have a radix (base) of 16.
|
|
|
|
/// use sigils::Number;
|
|
|
|
///
|
|
|
|
/// let x: i32 = Number::from_str_radix("FF", 16u32).unwrap();
|
|
|
|
/// # assert_eq!(x, 255i32);
|
|
|
|
///```
|
2015-10-04 02:59:26 -04:00
|
|
|
fn from_str_radix(src: &str, radix: u32) ->
|
|
|
|
Result<Self, Self::StrRadixError>;
|
|
|
|
}
|
|
|
|
|
2015-10-09 13:02:54 -04:00
|
|
|
/// A trait that defines converting something to a Number.
|
|
|
|
pub trait ToNumber
|
|
|
|
{
|
|
|
|
/// Convert this to an u8.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_u8(&self) -> Option<u8>
|
|
|
|
{
|
|
|
|
let option: Option<u64>;
|
|
|
|
|
|
|
|
option = self.to_u64();
|
|
|
|
match option
|
|
|
|
{
|
|
|
|
Some(val) =>
|
|
|
|
{
|
|
|
|
val.to_u8()
|
|
|
|
}
|
|
|
|
|
|
|
|
None =>
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert this to an u16.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_u16(&self) -> Option<u16>
|
|
|
|
{
|
|
|
|
let option: Option<u64>;
|
|
|
|
|
|
|
|
option = self.to_u64();
|
|
|
|
match option
|
|
|
|
{
|
|
|
|
Some(val) =>
|
|
|
|
{
|
|
|
|
val.to_u16()
|
|
|
|
}
|
|
|
|
|
|
|
|
None =>
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert this to an u32.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_u32(&self) -> Option<u32>
|
|
|
|
{
|
|
|
|
let option: Option<u64>;
|
|
|
|
|
|
|
|
option = self.to_u64();
|
|
|
|
match option
|
|
|
|
{
|
|
|
|
Some(val) =>
|
|
|
|
{
|
|
|
|
val.to_u32()
|
|
|
|
}
|
|
|
|
|
|
|
|
None =>
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert this to an u64.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_u64(&self) -> Option<u64>;
|
|
|
|
|
|
|
|
/// Convert this to an usize.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_usize(&self) -> Option<usize>
|
|
|
|
{
|
|
|
|
let option: Option<u64>;
|
|
|
|
|
|
|
|
option = self.to_u64();
|
|
|
|
match option
|
|
|
|
{
|
|
|
|
Some(val) =>
|
|
|
|
{
|
|
|
|
val.to_usize()
|
|
|
|
}
|
|
|
|
|
|
|
|
None =>
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Convert this to an i8.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_i8(&self) -> Option<i8>
|
|
|
|
{
|
|
|
|
let option: Option<i64>;
|
|
|
|
|
|
|
|
option = self.to_i64();
|
|
|
|
match option
|
|
|
|
{
|
|
|
|
Some(val) =>
|
|
|
|
{
|
|
|
|
val.to_i8()
|
|
|
|
}
|
|
|
|
|
|
|
|
None =>
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert this to an i16.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_i16(&self) -> Option<i16>
|
|
|
|
{
|
|
|
|
let option: Option<i64>;
|
|
|
|
|
|
|
|
option = self.to_i64();
|
|
|
|
match option
|
|
|
|
{
|
|
|
|
Some(val) =>
|
|
|
|
{
|
|
|
|
val.to_i16()
|
|
|
|
}
|
|
|
|
|
|
|
|
None =>
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert this to an i32.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_i32(&self) -> Option<i32>
|
|
|
|
{
|
|
|
|
let option: Option<i64>;
|
|
|
|
|
|
|
|
option = self.to_i64();
|
|
|
|
match option
|
|
|
|
{
|
|
|
|
Some(val) =>
|
|
|
|
{
|
|
|
|
val.to_i32()
|
|
|
|
}
|
|
|
|
|
|
|
|
None =>
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert this to an i64.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_i64(&self) -> Option<i64>;
|
|
|
|
|
|
|
|
/// Convert this to an isize.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_isize(&self) -> Option<isize>
|
|
|
|
{
|
|
|
|
let option: Option<i64>;
|
|
|
|
|
|
|
|
option = self.to_i64();
|
|
|
|
match option
|
|
|
|
{
|
|
|
|
Some(val) =>
|
|
|
|
{
|
|
|
|
val.to_isize()
|
|
|
|
}
|
|
|
|
|
|
|
|
None =>
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Convert this to an f32.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_f32(&self) -> Option<f32>
|
|
|
|
{
|
|
|
|
let option: Option<f64>;
|
|
|
|
|
|
|
|
option = self.to_f64();
|
|
|
|
match option
|
|
|
|
{
|
|
|
|
Some(val) =>
|
|
|
|
{
|
|
|
|
val.to_f32()
|
|
|
|
}
|
|
|
|
|
|
|
|
None =>
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert this to an f64.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn to_f64(&self) -> Option<f64>
|
|
|
|
{
|
|
|
|
let option: Option<i64>;
|
|
|
|
|
|
|
|
option = self.to_i64();
|
|
|
|
match option
|
|
|
|
{
|
|
|
|
Some(val) =>
|
|
|
|
{
|
|
|
|
val.to_f64()
|
|
|
|
}
|
|
|
|
|
|
|
|
None =>
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A trait that defines convertung a Number to something else.
|
|
|
|
pub trait FromNumber : Sized
|
|
|
|
{
|
|
|
|
/// Convert an i8 to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_i8(number: i8) -> Option<Self>
|
|
|
|
{
|
|
|
|
FromNumber::from_i64(number as i64)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert an i16 to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_i16(number: i16) -> Option<Self>
|
|
|
|
{
|
|
|
|
FromNumber::from_i64(number as i64)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert an i32 to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_i32(number: i32) -> Option<Self>
|
|
|
|
{
|
|
|
|
FromNumber::from_i64(number as i64)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert an i64 to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_i64(number: i64) -> Option<Self>;
|
|
|
|
|
|
|
|
/// Convert an isize to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_isize(number: isize) -> Option<Self>
|
|
|
|
{
|
|
|
|
FromNumber::from_i64(number as i64)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Convert an u8 to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_u8(number: u8) -> Option<Self>
|
|
|
|
{
|
|
|
|
FromNumber::from_u64(number as u64)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert an u16 to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_u16(number: u16) -> Option<Self>
|
|
|
|
{
|
|
|
|
FromNumber::from_u64(number as u64)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert an u32 to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_u32(number: u32) -> Option<Self>
|
|
|
|
{
|
|
|
|
FromNumber::from_u64(number as u64)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert an u64 to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_u64(number: u64) -> Option<Self>;
|
|
|
|
|
|
|
|
/// Convert an usize to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_usize(number: usize) -> Option<Self>
|
|
|
|
{
|
|
|
|
FromNumber::from_u64(number as u64)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Convert an f32 to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_f32(number: f32) -> Option<Self>
|
|
|
|
{
|
|
|
|
FromNumber::from_f64(number as f64)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Convert an f64 to an optional value of this type.
|
|
|
|
/// None is returned if the conversion is not possible.
|
|
|
|
fn from_f64(number: f64) -> Option<Self>
|
|
|
|
{
|
|
|
|
FromNumber::from_i64(number as i64)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-04 02:59:26 -04:00
|
|
|
|
|
|
|
// Create some macros to ease typing and reading.
|
2015-10-09 13:02:54 -04:00
|
|
|
macro_rules! convert_int_to_int
|
|
|
|
{
|
|
|
|
($srcType: ty, $dstType: ty, $val: expr) =>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let num: i64;
|
|
|
|
let min_value: $dstType;
|
|
|
|
let max_value: $dstType;
|
|
|
|
|
|
|
|
num = $val as i64;
|
|
|
|
min_value = Bounded::min_value();
|
|
|
|
max_value = Bounded::max_value();
|
|
|
|
|
|
|
|
if (min_value as i64) <= num && num <= (max_value as i64)
|
|
|
|
{
|
|
|
|
Some($val as $dstType)
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! convert_int_to_uint
|
|
|
|
{
|
|
|
|
($srcType: ty, $dstType: ty, $val: expr) =>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let zero: $srcType;
|
|
|
|
let max_value: $dstType;
|
|
|
|
|
|
|
|
zero = Zero::zero();
|
|
|
|
max_value = Bounded::max_value();
|
|
|
|
|
|
|
|
if zero <= $val && ($val as u64) <= (max_value as u64)
|
|
|
|
{
|
|
|
|
Some($val as $dstType)
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! convert_uint_to_int
|
|
|
|
{
|
|
|
|
($dstType: ty, $val: expr) =>
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let max_value: $dstType;
|
|
|
|
|
|
|
|
max_value = Bounded::max_value();
|
|
|
|
if ($val as u64) <= (max_value as u64)
|
|
|
|
{
|
|
|
|
Some($val as $dstType)
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! convert_uint_to_uint
|
|
|
|
{
|
|
|
|
($srcType: ty, $dstType: ty, $val: expr) =>
|
|
|
|
{
|
|
|
|
if size_of::<$srcType>() <= size_of::<$dstType>()
|
|
|
|
{
|
|
|
|
Some($val as $dstType)
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
let zero: $srcType;
|
|
|
|
let max_value: $dstType;
|
|
|
|
|
|
|
|
zero = Zero::zero();
|
|
|
|
max_value = Bounded::max_value();
|
|
|
|
|
|
|
|
if zero <= $val && ($val as u64) <= (max_value as u64)
|
|
|
|
{
|
|
|
|
Some($val as $dstType)
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! convert_float_to_float
|
|
|
|
{
|
|
|
|
($srcType: ty, $dstType: ty, $val: expr) =>
|
|
|
|
{
|
|
|
|
if size_of::<$srcType>() <= size_of::<$dstType>()
|
|
|
|
{
|
|
|
|
Some($val as $dstType)
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
let num: f64;
|
|
|
|
let min_value: $srcType;
|
|
|
|
let max_value: $srcType;
|
|
|
|
|
|
|
|
num = $val as f64;
|
|
|
|
min_value = Bounded::min_value();
|
|
|
|
max_value = Bounded::max_value();
|
|
|
|
|
|
|
|
if (min_value as f64) <= num && num <= (max_value as f64)
|
|
|
|
{
|
|
|
|
Some($val as $dstType)
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! int_to_number_impl
|
|
|
|
{
|
|
|
|
($traitName: ident for $($varType: ty)*) =>
|
|
|
|
($(
|
|
|
|
impl $traitName for $varType
|
|
|
|
{
|
|
|
|
fn to_u8(&self) -> Option<u8>
|
|
|
|
{
|
|
|
|
convert_int_to_uint!($varType, u8, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_u16(&self) -> Option<u16>
|
|
|
|
{
|
|
|
|
convert_int_to_uint!($varType, u16, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_u32(&self) -> Option<u32>
|
|
|
|
{
|
|
|
|
convert_int_to_uint!($varType, u32, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_u64(&self) -> Option<u64>
|
|
|
|
{
|
|
|
|
convert_int_to_uint!($varType, u64, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_usize(&self) -> Option<usize>
|
|
|
|
{
|
|
|
|
convert_int_to_uint!($varType, usize, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn to_i8(&self) -> Option<i8>
|
|
|
|
{
|
|
|
|
convert_int_to_int!($varType, i8, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_i16(&self) -> Option<i16>
|
|
|
|
{
|
|
|
|
convert_int_to_int!($varType, i16, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_i32(&self) -> Option<i32>
|
|
|
|
{
|
|
|
|
convert_int_to_int!($varType, i32, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_i64(&self) -> Option<i64>
|
|
|
|
{
|
|
|
|
convert_int_to_int!($varType, i64, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_isize(&self) -> Option<isize>
|
|
|
|
{
|
|
|
|
convert_int_to_int!($varType, isize, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn to_f32(&self) -> Option<f32>
|
|
|
|
{
|
|
|
|
Some(*self as f32)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_f64(&self) -> Option<f64>
|
|
|
|
{
|
|
|
|
Some(*self as f64)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)*)
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! uint_to_number_impl
|
2015-10-04 02:59:26 -04:00
|
|
|
{
|
|
|
|
($traitName: ident for $($varType: ty)*) =>
|
2015-10-09 13:02:54 -04:00
|
|
|
($(
|
|
|
|
impl $traitName for $varType
|
|
|
|
{
|
|
|
|
fn to_u8(&self) -> Option<u8>
|
|
|
|
{
|
|
|
|
convert_uint_to_uint!($varType, u8, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_u16(&self) -> Option<u16>
|
2015-10-04 02:59:26 -04:00
|
|
|
{
|
2015-10-09 13:02:54 -04:00
|
|
|
convert_uint_to_uint!($varType, u16, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_u32(&self) -> Option<u32>
|
|
|
|
{
|
|
|
|
convert_uint_to_uint!($varType, u32, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_u64(&self) -> Option<u64>
|
|
|
|
{
|
|
|
|
convert_uint_to_uint!($varType, u64, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_usize(&self) -> Option<usize>
|
|
|
|
{
|
|
|
|
convert_uint_to_uint!($varType, usize, *self)
|
|
|
|
}
|
|
|
|
|
2015-10-04 02:59:26 -04:00
|
|
|
|
2015-10-09 13:02:54 -04:00
|
|
|
fn to_i8(&self) -> Option<i8>
|
|
|
|
{
|
|
|
|
convert_uint_to_int!(i8, *self)
|
2015-10-04 02:59:26 -04:00
|
|
|
}
|
2015-10-09 13:02:54 -04:00
|
|
|
|
|
|
|
fn to_i16(&self) -> Option<i16>
|
|
|
|
{
|
|
|
|
convert_uint_to_int!(i16, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_i32(&self) -> Option<i32>
|
|
|
|
{
|
|
|
|
convert_uint_to_int!(i32, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_i64(&self) -> Option<i64>
|
|
|
|
{
|
|
|
|
convert_uint_to_int!(i64, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_isize(&self) -> Option<isize>
|
|
|
|
{
|
|
|
|
convert_uint_to_int!(isize, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn to_f32(&self) -> Option<f32>
|
|
|
|
{
|
|
|
|
Some(*self as f32)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_f64(&self) -> Option<f64>
|
|
|
|
{
|
|
|
|
Some(*self as f64)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)*)
|
2015-10-04 02:59:26 -04:00
|
|
|
}
|
|
|
|
|
2015-10-09 13:02:54 -04:00
|
|
|
macro_rules! float_to_number_impl
|
|
|
|
{
|
|
|
|
($traitName: ident for $($varType: ty)*) =>
|
|
|
|
($(
|
|
|
|
impl $traitName for $varType
|
|
|
|
{
|
|
|
|
fn to_u8(&self) -> Option<u8>
|
|
|
|
{
|
|
|
|
Some(*self as u8)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_u16(&self) -> Option<u16>
|
|
|
|
{
|
|
|
|
Some(*self as u16)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_u32(&self) -> Option<u32>
|
|
|
|
{
|
|
|
|
Some(*self as u32)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_u64(&self) -> Option<u64>
|
|
|
|
{
|
|
|
|
Some(*self as u64)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_usize(&self) -> Option<usize>
|
|
|
|
{
|
|
|
|
Some(*self as usize)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn to_i8(&self) -> Option<i8>
|
|
|
|
{
|
|
|
|
Some(*self as i8)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_i16(&self) -> Option<i16>
|
|
|
|
{
|
|
|
|
Some(*self as i16)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_i32(&self) -> Option<i32>
|
|
|
|
{
|
|
|
|
Some(*self as i32)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_i64(&self) -> Option<i64>
|
|
|
|
{
|
|
|
|
Some(*self as i64)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_isize(&self) -> Option<isize>
|
|
|
|
{
|
|
|
|
Some(*self as isize)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn to_f32(&self) -> Option<f32>
|
|
|
|
{
|
|
|
|
convert_float_to_float!($varType, f32, *self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_f64(&self) -> Option<f64>
|
|
|
|
{
|
|
|
|
convert_float_to_float!($varType, f64, *self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)*)
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! from_number_impl
|
|
|
|
{
|
|
|
|
($varType: ty, $toTypeFunc: ident) =>
|
|
|
|
{
|
|
|
|
impl FromNumber for $varType
|
|
|
|
{
|
|
|
|
fn from_u8(number: u8) -> Option<$varType>
|
|
|
|
{
|
|
|
|
number.$toTypeFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn from_u16(number: u16) -> Option<$varType>
|
|
|
|
{
|
|
|
|
number.$toTypeFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn from_u32(number: u32) -> Option<$varType>
|
|
|
|
{
|
|
|
|
number.$toTypeFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn from_u64(number: u64) -> Option<$varType>
|
|
|
|
{
|
|
|
|
number.$toTypeFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn from_i8(number: i8) -> Option<$varType>
|
|
|
|
{
|
|
|
|
number.$toTypeFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn from_i16(number: i16) -> Option<$varType>
|
|
|
|
{
|
|
|
|
number.$toTypeFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn from_i32(number: i32) -> Option<$varType>
|
|
|
|
{
|
|
|
|
number.$toTypeFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn from_i64(number: i64) -> Option<$varType>
|
|
|
|
{
|
|
|
|
number.$toTypeFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn from_f32(number: f32) -> Option<$varType>
|
|
|
|
{
|
|
|
|
number.$toTypeFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn from_f64(number: f64) -> Option<$varType>
|
|
|
|
{
|
|
|
|
number.$toTypeFunc()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A macro to make implementing the Number trait easier for all the
|
|
|
|
/// base integer types in rust.
|
|
|
|
macro_rules! int_number_trait_impl
|
|
|
|
{
|
|
|
|
($traitName: ident for $($varType: ty)*) =>
|
|
|
|
($(
|
|
|
|
impl $traitName for $varType
|
|
|
|
{
|
|
|
|
type StrRadixError = ::std::num::ParseIntError;
|
|
|
|
|
2016-01-06 00:54:44 -05:00
|
|
|
|
2015-10-09 13:02:54 -04:00
|
|
|
fn from_str_radix(src: &str, radix: u32) ->
|
|
|
|
Result<Self, ::std::num::ParseIntError>
|
|
|
|
{
|
|
|
|
<$varType>::from_str_radix(src, radix)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)*)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A macro to make implementing the Number trait easier for all the
|
2015-10-04 02:59:26 -04:00
|
|
|
/// base float types in rust.
|
2015-10-09 13:02:54 -04:00
|
|
|
macro_rules! float_number_trait_impl
|
2015-10-04 02:59:26 -04:00
|
|
|
{
|
2016-01-06 00:54:44 -05:00
|
|
|
($traitName: ident for $($varType: ty, $numBytes: expr)*) =>
|
2015-10-04 02:59:26 -04:00
|
|
|
($(
|
|
|
|
impl $traitName for $varType
|
|
|
|
{
|
|
|
|
type StrRadixError = ::std::num::ParseFloatError;
|
|
|
|
|
2016-01-06 00:54:44 -05:00
|
|
|
|
2015-10-04 02:59:26 -04:00
|
|
|
fn from_str_radix(src: &str, radix: u32) ->
|
|
|
|
Result<Self, ::std::num::ParseFloatError>
|
|
|
|
{
|
2015-12-31 02:58:21 -05:00
|
|
|
// TODO: Currently this will panic on a non base 10 radix.
|
|
|
|
// This is because the std library deprecated the
|
|
|
|
// from_str_radix function. Until a function can be
|
|
|
|
// written this will use the from_str function and
|
|
|
|
// panic for non base 10 requests.
|
|
|
|
assert!(radix == 10);
|
|
|
|
<$varType>::from_str(src)
|
2015-10-04 02:59:26 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
)*)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-09 13:02:54 -04:00
|
|
|
// Implement the Number trait for the types that are Numbers.
|
|
|
|
int_number_trait_impl!(Number for u8 u16 u32 u64 usize);
|
|
|
|
int_number_trait_impl!(Number for i8 i16 i32 i64 isize);
|
2016-01-06 00:54:44 -05:00
|
|
|
float_number_trait_impl!(Number for f32, 4 f64, 8);
|
2015-10-09 13:02:54 -04:00
|
|
|
|
|
|
|
// Implement the ToNumber and FromNumber traits for
|
|
|
|
// the types that are Numbers. The FromNumber trait needs
|
|
|
|
// to be defined after ToNumber since FromNumber uses
|
|
|
|
// ToNumber definitions.
|
|
|
|
uint_to_number_impl!(ToNumber for u8 u16 u32 u64 usize);
|
|
|
|
int_to_number_impl!(ToNumber for i8 i16 i32 i64 isize);
|
|
|
|
float_to_number_impl!(ToNumber for f32 f64);
|
|
|
|
|
|
|
|
from_number_impl!(u8, to_u8);
|
|
|
|
from_number_impl!(u16, to_u16);
|
|
|
|
from_number_impl!(u32, to_u32);
|
|
|
|
from_number_impl!(u64, to_u64);
|
|
|
|
from_number_impl!(usize, to_usize);
|
|
|
|
|
|
|
|
from_number_impl!(i8, to_i8);
|
|
|
|
from_number_impl!(i16, to_i16);
|
|
|
|
from_number_impl!(i32, to_i32);
|
|
|
|
from_number_impl!(i64, to_i64);
|
|
|
|
from_number_impl!(isize, to_isize);
|
|
|
|
|
|
|
|
from_number_impl!(f32, to_f32);
|
|
|
|
from_number_impl!(f64, to_f64);
|