Skip to content

Commit

Permalink
Migrate Bytes to u128 internally
Browse files Browse the repository at this point in the history
  • Loading branch information
jbaublitz committed Oct 28, 2019
1 parent 88d8bd8 commit e2e8066
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 51 deletions.
224 changes: 178 additions & 46 deletions src/range_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

// An omnibus macro that includes all simple macros.
macro_rules! range {
( $(#[$comment:meta])? $T: ident, $display_name: expr) => {
( $(#[$comment:meta])? $T: ident, u64, $display_name: expr) => {
$(
#[$comment]
)?
Expand All @@ -14,25 +14,48 @@ macro_rules! range {
checked_add!($T);
debug_macro!($T);
display!($T, $display_name);
serde_macro!($T);
serde_macro!($T, u64);
sum!($T);
add!($T);
add_assign!($T);
sub!($T);
sub_assign!($T);
mul!($T);
div!($T);
rem!($T);
deref!($T);
from!($T);
mul!($T, u64);
div!($T, u64);
rem!($T, u64);
deref!($T, u64);
from!($T, u64);
};
( $(#[$comment:meta])? $T: ident, u128, $display_name: expr) => {
$(
#[$comment]
)?
#[derive(Clone, Copy, Default, Eq, Ord, PartialEq, PartialOrd)]
/// A type for $T
pub struct $T(pub u128);

checked_add!($T);
debug_macro!($T);
display!($T, $display_name);
serde_macro!($T, u128);
sum!($T);
add!($T);
add_assign!($T);
sub!($T);
sub_assign!($T);
mul!($T, u128);
div!($T, u128);
rem!($T, u128);
deref!($T, u128);
from!($T, u128);
};
}

macro_rules! self_div {
($T:ident) => {
($T:ident, $inner:ty) => {
impl Div<$T> for $T {
type Output = u64;
fn div(self, rhs: $T) -> u64 {
type Output = $inner;
fn div(self, rhs: $T) -> $inner {
self.0 / *rhs
}
}
Expand Down Expand Up @@ -82,20 +105,20 @@ macro_rules! sub_assign {
}

macro_rules! deref {
($T:ident) => {
($T:ident, $inner:ty) => {
impl Deref for $T {
type Target = u64;
fn deref(&self) -> &u64 {
type Target = $inner;
fn deref(&self) -> &$inner {
&self.0
}
}
};
}

macro_rules! from {
($T:ident) => {
impl From<u64> for $T {
fn from(t: u64) -> $T {
($T:ident, $inner:ty) => {
impl From<$inner> for $T {
fn from(t: $inner) -> $T {
$T(t)
}
}
Expand Down Expand Up @@ -124,7 +147,7 @@ macro_rules! display {
}

macro_rules! serde_macro {
($T:ident) => {
($T:ident, u64) => {
impl serde::Serialize for $T {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand All @@ -134,6 +157,25 @@ macro_rules! serde_macro {
}
}

impl<'de> serde::Deserialize<'de> for $T {
fn deserialize<D>(deserializer: D) -> Result<$T, D::Error>
where
D: serde::de::Deserializer<'de>,
{
Ok($T(serde::Deserialize::deserialize(deserializer)?))
}
}
};
($T:ident, u128) => {
impl serde::Serialize for $T {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u128(**self)
}
}

impl<'de> serde::Deserialize<'de> for $T {
fn deserialize<D>(deserializer: D) -> Result<$T, D::Error>
where
Expand All @@ -157,52 +199,77 @@ macro_rules! sum {

// Define a complete set of division operations.
macro_rules! div {
($T: ident) => {
unsigned_div!(u64, $T);
unsigned_div!(u32, $T);
unsigned_div!(u16, $T);
unsigned_div!(u8, $T);
usize_div!($T);
self_div!($T);
($T:ident, u64) => {
unsigned_div!(u64, $T, u64);
unsigned_div!(u32, $T, u64);
unsigned_div!(u16, $T, u64);
unsigned_div!(u8, $T, u64);
usize_div!($T, u64);
self_div!($T, u64);
};
($T:ident, u128) => {
unsigned_div!(u128, $T, u128);
unsigned_div!(u64, $T, u128);
unsigned_div!(u32, $T, u128);
unsigned_div!(u16, $T, u128);
unsigned_div!(u8, $T, u128);
usize_div!($T, u128);
self_div!($T, u128);
};
}

macro_rules! unsigned_div {
($t:ty, $T:ident) => {
($t:ty, $T:ident, u64) => {
impl Div<$t> for $T {
type Output = $T;
fn div(self, rhs: $t) -> $T {
$T(self.0 / u64::from(rhs))
}
}
};
($t:ty, $T:ident, u128) => {
impl Div<$t> for $T {
type Output = $T;
fn div(self, rhs: $t) -> $T {
$T(self.0 / u128::from(rhs))
}
}
};
}

macro_rules! usize_div {
($T:ident) => {
($T:ident, $inner:ty) => {
impl Div<usize> for $T {
type Output = $T;
fn div(self, rhs: usize) -> $T {
#[allow(clippy::cast_lossless)]
$T(self.0 / rhs as u64)
$T(self.0 / rhs as $inner)
}
}
};
}

// Define a complete set of multiplication operations.
macro_rules! mul {
($T: ident) => {
unsigned_mul!(u64, $T);
unsigned_mul!(u32, $T);
unsigned_mul!(u16, $T);
unsigned_mul!(u8, $T);
usize_mul!($T);
($T: ident, u64) => {
unsigned_mul!(u64, $T, u64);
unsigned_mul!(u32, $T, u64);
unsigned_mul!(u16, $T, u64);
unsigned_mul!(u8, $T, u64);
usize_mul!($T, u64);
};
($T: ident, u128) => {
unsigned_mul!(u128, $T, u128);
unsigned_mul!(u64, $T, u128);
unsigned_mul!(u32, $T, u128);
unsigned_mul!(u16, $T, u128);
unsigned_mul!(u8, $T, u128);
usize_mul!($T, u128);
};
}

macro_rules! unsigned_mul {
($t:ty, $T:ident) => {
($t:ty, $T:ident, u64) => {
impl Mul<$t> for $T {
type Output = $T;
fn mul(self, rhs: $t) -> $T {
Expand All @@ -217,10 +284,25 @@ macro_rules! unsigned_mul {
}
}
};
($t:ty, $T:ident, u128) => {
impl Mul<$t> for $T {
type Output = $T;
fn mul(self, rhs: $t) -> $T {
$T(self.0 * u128::from(rhs))
}
}

impl Mul<$T> for $t {
type Output = $T;
fn mul(self, rhs: $T) -> $T {
$T(u128::from(self) * rhs.0)
}
}
};
}

macro_rules! usize_mul {
($T:ident) => {
($T:ident, u64) => {
impl Mul<usize> for $T {
type Output = $T;
fn mul(self, rhs: usize) -> $T {
Expand All @@ -237,33 +319,66 @@ macro_rules! usize_mul {
}
}
};
($T:ident, u128) => {
impl Mul<usize> for $T {
type Output = $T;
fn mul(self, rhs: usize) -> $T {
#[allow(clippy::cast_lossless)]
$T(self.0 * rhs as u128)
}
}

impl Mul<$T> for usize {
type Output = $T;
fn mul(self, rhs: $T) -> $T {
#[allow(clippy::cast_lossless)]
$T(self as u128 * rhs.0)
}
}
};
}

// Define a complete set of remainder operations.
macro_rules! rem {
($T: ident) => {
unsigned_rem!(u64, $T);
unsigned_rem!(u32, $T);
unsigned_rem!(u16, $T);
unsigned_rem!(u8, $T);
usize_rem!($T);
self_rem!($T);
($T: ident, u64) => {
unsigned_rem!(u64, $T, u64);
unsigned_rem!(u32, $T, u64);
unsigned_rem!(u16, $T, u64);
unsigned_rem!(u8, $T, u64);
usize_rem!($T, u64);
self_rem!($T, u64);
};
($T: ident, u128) => {
unsigned_rem!(u64, $T, u128);
unsigned_rem!(u32, $T, u128);
unsigned_rem!(u16, $T, u128);
unsigned_rem!(u8, $T, u128);
usize_rem!($T, u128);
self_rem!($T, u128);
};
}

macro_rules! unsigned_rem {
($t:ty, $T:ident) => {
($t:ty, $T:ident, u64) => {
impl Rem<$t> for $T {
type Output = $T;
fn rem(self, rhs: $t) -> $T {
$T(self.0 % u64::from(rhs))
}
}
};
($t:ty, $T:ident, u128) => {
impl Rem<$t> for $T {
type Output = $T;
fn rem(self, rhs: $t) -> $T {
$T(self.0 % u128::from(rhs))
}
}
};
}

macro_rules! usize_rem {
($T:ident) => {
($T:ident, u64) => {
impl Rem<usize> for $T {
type Output = $T;
fn rem(self, rhs: usize) -> $T {
Expand All @@ -272,17 +387,34 @@ macro_rules! usize_rem {
}
}
};
($T:ident, u128) => {
impl Rem<usize> for $T {
type Output = $T;
fn rem(self, rhs: usize) -> $T {
#[allow(clippy::cast_lossless)]
$T(self.0 % rhs as u128)
}
}
};
}

macro_rules! self_rem {
($T:ident) => {
($T:ident, u64) => {
impl Rem<$T> for $T {
type Output = $T;
fn rem(self, rhs: $T) -> $T {
$T(self.0 % u64::from(rhs.0))
}
}
};
($T:ident, u128) => {
impl Rem<$T> for $T {
type Output = $T;
fn rem(self, rhs: $T) -> $T {
$T(self.0 % u128::from(rhs.0))
}
}
};
}

macro_rules! checked_add {
Expand All @@ -306,7 +438,7 @@ mod tests {
u64,
};

range!(Units, "units");
range!(Units, u64, "units");

#[test]
/// Test implicit derivations for Units
Expand Down
Loading

0 comments on commit e2e8066

Please sign in to comment.