From abb191f23b40a395cee6405dcab0831ab0d86fd6 Mon Sep 17 00:00:00 2001 From: John Baublitz Date: Mon, 28 Oct 2019 11:55:57 -0400 Subject: [PATCH 1/3] Migrate Bytes to u128 internally --- src/range_macros.rs | 224 ++++++++++++++++++++++++++++++-------- src/testing/loopbacked.rs | 10 +- src/testing/test_lib.rs | 2 +- src/units.rs | 9 +- 4 files changed, 194 insertions(+), 51 deletions(-) diff --git a/src/range_macros.rs b/src/range_macros.rs index d8ac900d..637f0a6f 100644 --- a/src/range_macros.rs +++ b/src/range_macros.rs @@ -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] )? @@ -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 std::ops::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 } } @@ -82,10 +105,10 @@ macro_rules! sub_assign { } macro_rules! deref { - ($T:ident) => { + ($T:ident, $inner:ty) => { impl std::ops::Deref for $T { - type Target = u64; - fn deref(&self) -> &u64 { + type Target = $inner; + fn deref(&self) -> &$inner { &self.0 } } @@ -93,9 +116,9 @@ macro_rules! deref { } macro_rules! from { - ($T:ident) => { - impl From for $T { - fn from(t: u64) -> $T { + ($T:ident, $inner:ty) => { + impl From<$inner> for $T { + fn from(t: $inner) -> $T { $T(t) } } @@ -124,7 +147,7 @@ macro_rules! display { } macro_rules! serde_macro { - ($T:ident) => { + ($T:ident, u64) => { impl serde::Serialize for $T { fn serialize(&self, serializer: S) -> Result where @@ -134,6 +157,25 @@ macro_rules! serde_macro { } } + impl<'de> serde::Deserialize<'de> for $T { + fn deserialize(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(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_u128(**self) + } + } + impl<'de> serde::Deserialize<'de> for $T { fn deserialize(deserializer: D) -> Result<$T, D::Error> where @@ -157,18 +199,27 @@ 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 std::ops::Div<$t> for $T { type Output = $T; fn div(self, rhs: $t) -> $T { @@ -176,15 +227,23 @@ macro_rules! unsigned_div { } } }; + ($t:ty, $T:ident, u128) => { + impl std::ops::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 std::ops::Div 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) } } }; @@ -192,17 +251,25 @@ macro_rules! usize_div { // 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 std::ops::Mul<$t> for $T { type Output = $T; fn mul(self, rhs: $t) -> $T { @@ -217,10 +284,25 @@ macro_rules! unsigned_mul { } } }; + ($t:ty, $T:ident, u128) => { + impl std::ops::Mul<$t> for $T { + type Output = $T; + fn mul(self, rhs: $t) -> $T { + $T(self.0 * u128::from(rhs)) + } + } + + impl std::ops::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 std::ops::Mul for $T { type Output = $T; fn mul(self, rhs: usize) -> $T { @@ -237,22 +319,47 @@ macro_rules! usize_mul { } } }; + ($T:ident, u128) => { + impl std::ops::Mul for $T { + type Output = $T; + fn mul(self, rhs: usize) -> $T { + #[allow(clippy::cast_lossless)] + $T(self.0 * rhs as u128) + } + } + + impl std::ops::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 std::ops::Rem<$t> for $T { type Output = $T; fn rem(self, rhs: $t) -> $T { @@ -260,10 +367,18 @@ macro_rules! unsigned_rem { } } }; + ($t:ty, $T:ident, u128) => { + impl std::ops::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 std::ops::Rem for $T { type Output = $T; fn rem(self, rhs: usize) -> $T { @@ -272,10 +387,19 @@ macro_rules! usize_rem { } } }; + ($T:ident, u128) => { + impl std::ops::Rem 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 std::ops::Rem<$T> for $T { type Output = $T; fn rem(self, rhs: $T) -> $T { @@ -283,6 +407,14 @@ macro_rules! self_rem { } } }; + ($T:ident, u128) => { + impl std::ops::Rem<$T> for $T { + type Output = $T; + fn rem(self, rhs: $T) -> $T { + $T(self.0 % u128::from(rhs.0)) + } + } + }; } macro_rules! checked_add { @@ -301,7 +433,7 @@ mod tests { use std::u64; - range!(Units, "units"); + range!(Units, u64, "units"); #[test] /// Test implicit derivations for Units diff --git a/src/testing/loopbacked.rs b/src/testing/loopbacked.rs index e8bee355..24eabd90 100644 --- a/src/testing/loopbacked.rs +++ b/src/testing/loopbacked.rs @@ -3,6 +3,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. use std::{ + convert::TryInto, fs::OpenOptions, io::{self, Seek, SeekFrom, Write}, os::unix::io::AsRawFd, @@ -28,7 +29,7 @@ fn write_sectors>( ) -> io::Result<()> { let mut f = OpenOptions::new().write(true).open(path)?; - f.seek(SeekFrom::Start(*offset.bytes()))?; + f.seek(SeekFrom::Start((*offset.bytes()).try_into().unwrap()))?; for _ in 0..*length { f.write_all(buf)?; } @@ -59,7 +60,12 @@ impl LoopTestDev { // Wipe one MiB at the start of the device. Devicemapper data may be // left on the device even after a teardown. - wipe_sectors(&ld.path().unwrap(), Sectors(0), Bytes(IEC::Mi).sectors()).unwrap(); + wipe_sectors( + &ld.path().unwrap(), + Sectors(0), + Bytes(u128::from(IEC::Mi)).sectors(), + ) + .unwrap(); LoopTestDev { ld } } diff --git a/src/testing/test_lib.rs b/src/testing/test_lib.rs index 9c6f6e28..4930ccef 100644 --- a/src/testing/test_lib.rs +++ b/src/testing/test_lib.rs @@ -55,7 +55,7 @@ pub fn blkdev_size(file: &File) -> Bytes { let mut val: u64 = 0; unsafe { blkgetsize64(file.as_raw_fd(), &mut val) }.unwrap(); - Bytes(val) + Bytes(u128::from(val)) } fn get_dm() -> &'static DM { diff --git a/src/units.rs b/src/units.rs index 2aa55910..1e52e5d1 100644 --- a/src/units.rs +++ b/src/units.rs @@ -22,12 +22,14 @@ const MAX_META_DEV_SIZE: MetaBlocks = MetaBlocks(255 * ((1 << 14) - 64)); range!( /// A type for data blocks DataBlocks, + u64, "data blocks" ); range!( /// A type for meta blocks MetaBlocks, + u64, "meta blocks" ); @@ -41,26 +43,29 @@ impl MetaBlocks { range!( /// A type for bytes Bytes, + u128, "bytes" ); impl Bytes { /// Return the number of Sectors fully contained in these bytes. pub fn sectors(self) -> Sectors { - Sectors(self.0 / SECTOR_SIZE as u64) + Sectors((self.0 / SECTOR_SIZE as u128) as u64) } } range!( /// A type for sectors Sectors, + u64, "sectors" ); impl Sectors { /// The number of bytes in these sectors. pub fn bytes(self) -> Bytes { - Bytes(self.0 * SECTOR_SIZE as u64) + // Keep both as u128 before multiplication or overflow could occur + Bytes(u128::from(self.0) * SECTOR_SIZE as u128) } /// The number of whole metablocks contained in these sectors. From 0900f2c2780e1df866346e88f93c6b941b72d574 Mon Sep 17 00:00:00 2001 From: John Baublitz Date: Thu, 12 Dec 2019 11:05:59 -0500 Subject: [PATCH 2/3] Clean up macros --- src/range_macros.rs | 347 +++++++++++++------------------------------- src/units.rs | 12 +- 2 files changed, 101 insertions(+), 258 deletions(-) diff --git a/src/range_macros.rs b/src/range_macros.rs index 637f0a6f..0f9b0724 100644 --- a/src/range_macros.rs +++ b/src/range_macros.rs @@ -3,62 +3,44 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. // An omnibus macro that includes all simple macros. -macro_rules! range { - ( $(#[$comment:meta])? $T: ident, u64, $display_name: expr) => { - $( - #[$comment] - )? - #[derive(Clone, Copy, Default, Eq, Ord, PartialEq, PartialOrd)] - pub struct $T(pub u64); +macro_rules! range_u64 { + ( $(#[$comment:meta])? $T: ident, $display_name: expr) => { + range!($(#[$comment])? $T, $display_name, u64, serialize_u64); + from_u64!($T); + commut_mul!($T, usize, u64, u32, u16, u8); + div!($T, u64, u32, u16, u8); + } +} - checked_add!($T); - debug_macro!($T); - display!($T, $display_name); - serde_macro!($T, u64); - sum!($T); - add!($T); - add_assign!($T); - sub!($T); - sub_assign!($T); - mul!($T, u64); - div!($T, u64); - rem!($T, u64); - deref!($T, u64); - from!($T, u64); - }; - ( $(#[$comment:meta])? $T: ident, u128, $display_name: expr) => { +macro_rules! range_u128 { + ( $(#[$comment:meta])? $T: ident, $display_name: expr) => { + range!($(#[$comment])? $T, $display_name, u128, serialize_u128); + from_u128!($T); + commut_mul!($T, usize, u128, u64, u32, u16, u8); + div!($T, u128, u64, u32, u16, u8); + } +} + +macro_rules! range { + ( $(#[$comment:meta])? $T: ident, $display_name: expr, $inner:ty, $serde_method:ident) => { $( #[$comment] )? #[derive(Clone, Copy, Default, Eq, Ord, PartialEq, PartialOrd)] - /// A type for $T - pub struct $T(pub u128); + pub struct $T(pub $inner); checked_add!($T); debug_macro!($T); display!($T, $display_name); - serde_macro!($T, u128); + serde_macro!($T, $serde_method); 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, $inner:ty) => { - impl std::ops::Div<$T> for $T { - type Output = $inner; - fn div(self, rhs: $T) -> $inner { - self.0 / *rhs - } - } + mul!($T, $inner); + rem!($T); + deref!($T, $inner); }; } @@ -116,7 +98,21 @@ macro_rules! deref { } macro_rules! from { - ($T:ident, $inner:ty) => { + ($T:ident, $inner:ty, $($t:ty),+) => { + $( + impl From<$t> for $T { + fn from(t: $t) -> $T { + $T(<$inner>::from(t)) + } + } + )+ + + impl From for $T { + fn from(t: usize) -> $T { + $T(t as $inner) + } + } + impl From<$inner> for $T { fn from(t: $inner) -> $T { $T(t) @@ -125,6 +121,18 @@ macro_rules! from { }; } +macro_rules! from_u64 { + ($T:ident) => { + from!($T, u64, u32, u16, u8); + }; +} + +macro_rules! from_u128 { + ($T:ident) => { + from!($T, u128, u64, u32, u16, u8); + }; +} + macro_rules! debug_macro { ($T:ident) => { impl std::fmt::Debug for $T { @@ -147,32 +155,13 @@ macro_rules! display { } macro_rules! serde_macro { - ($T:ident, u64) => { + ($T:ident, $serde_method:ident) => { impl serde::Serialize for $T { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { - serializer.serialize_u64(**self) - } - } - - impl<'de> serde::Deserialize<'de> for $T { - fn deserialize(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(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - serializer.serialize_u128(**self) + serializer.$serde_method(**self) } } @@ -199,219 +188,77 @@ macro_rules! sum { // Define a complete set of division operations. macro_rules! div { - ($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, u64) => { - impl std::ops::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 std::ops::Div<$t> for $T { - type Output = $T; - fn div(self, rhs: $t) -> $T { - $T(self.0 / u128::from(rhs)) + ($T:ident, $inner:ty, $($t:ty),+) => { + $( + impl std::ops::Div<$t> for $T { + type Output = $T; + fn div(self, rhs: $t) -> $T { + $T(self.0 / <$inner>::from(rhs)) + } } - } - }; -} + )+ -macro_rules! usize_div { - ($T:ident, $inner:ty) => { impl std::ops::Div for $T { type Output = $T; fn div(self, rhs: usize) -> $T { - #[allow(clippy::cast_lossless)] $T(self.0 / rhs as $inner) } } - }; -} - -// Define a complete set of multiplication operations. -macro_rules! mul { - ($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, u64) => { - impl std::ops::Mul<$t> for $T { + impl std::ops::Div<$inner> for $T { type Output = $T; - fn mul(self, rhs: $t) -> $T { - $T(self.0 * u64::from(rhs)) + fn div(self, rhs: $inner) -> $T { + $T(self.0 / rhs) } } - impl std::ops::Mul<$T> for $t { - type Output = $T; - fn mul(self, rhs: $T) -> $T { - $T(u64::from(self) * rhs.0) - } - } - }; - ($t:ty, $T:ident, u128) => { - impl std::ops::Mul<$t> for $T { - type Output = $T; - fn mul(self, rhs: $t) -> $T { - $T(self.0 * u128::from(rhs)) - } - } - - impl std::ops::Mul<$T> for $t { - type Output = $T; - fn mul(self, rhs: $T) -> $T { - $T(u128::from(self) * rhs.0) + impl std::ops::Div for $T { + type Output = $inner; + fn div(self, rhs: $T) -> $inner { + self.0 / *rhs } } }; } -macro_rules! usize_mul { - ($T:ident, u64) => { - impl std::ops::Mul for $T { - type Output = $T; - fn mul(self, rhs: usize) -> $T { - #[allow(clippy::cast_lossless)] - $T(self.0 * rhs as u64) - } - } - - impl std::ops::Mul<$T> for usize { +// Define a complete set of multiplication operations. +macro_rules! mul { + ($T:ident, $inner:ty) => { + impl std::ops::Mul for $T + where + $T: From, + { type Output = $T; - fn mul(self, rhs: $T) -> $T { - #[allow(clippy::cast_lossless)] - $T(self as u64 * rhs.0) + fn mul(self, rhs: T) -> $T { + $T(self.0 * $T::from(rhs).0) } } }; - ($T:ident, u128) => { - impl std::ops::Mul for $T { - type Output = $T; - fn mul(self, rhs: usize) -> $T { - #[allow(clippy::cast_lossless)] - $T(self.0 * rhs as u128) - } - } +} - impl std::ops::Mul<$T> for usize { - type Output = $T; - fn mul(self, rhs: $T) -> $T { - #[allow(clippy::cast_lossless)] - $T(self as u128 * rhs.0) +macro_rules! commut_mul { + ($T:ident, $( $t:ty ),+) => { + $( + impl std::ops::Mul<$T> for $t { + type Output = $T; + fn mul(self, rhs: $T) -> $T { + rhs * self + } } - } - }; + )+ + } } // Define a complete set of remainder operations. macro_rules! rem { - ($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, u64) => { - impl std::ops::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 std::ops::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, u64) => { - impl std::ops::Rem for $T { - type Output = $T; - fn rem(self, rhs: usize) -> $T { - #[allow(clippy::cast_lossless)] - $T(self.0 % rhs as u64) - } - } - }; - ($T:ident, u128) => { - impl std::ops::Rem 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, u64) => { - impl std::ops::Rem<$T> for $T { - type Output = $T; - fn rem(self, rhs: $T) -> $T { - $T(self.0 % u64::from(rhs.0)) - } - } - }; - ($T:ident, u128) => { - impl std::ops::Rem<$T> for $T { + ($T: ident) => { + impl std::ops::Rem for $T + where + $T: From, + { type Output = $T; - fn rem(self, rhs: $T) -> $T { - $T(self.0 % u128::from(rhs.0)) + fn rem(self, rhs: T) -> $T { + $T(self.0 % <$T>::from(rhs).0) } } }; @@ -433,7 +280,7 @@ mod tests { use std::u64; - range!(Units, u64, "units"); + range_u64!(Units, "units"); #[test] /// Test implicit derivations for Units @@ -462,7 +309,7 @@ mod tests { /// Test non-arithmetic derivations that are derived explicitly fn test_explicit_derivations() { // Test From - assert_eq!(Units::from(3) + Units(3), Units(6)); + assert_eq!(Units::from(3u8) + Units(3), Units(6)); // Test Deref assert_eq!(*Units(3) + 3, 6); diff --git a/src/units.rs b/src/units.rs index 1e52e5d1..41550027 100644 --- a/src/units.rs +++ b/src/units.rs @@ -19,17 +19,15 @@ const META_BLOCK_SIZE: Sectors = Sectors(8); #[allow(dead_code)] const MAX_META_DEV_SIZE: MetaBlocks = MetaBlocks(255 * ((1 << 14) - 64)); -range!( +range_u64!( /// A type for data blocks DataBlocks, - u64, "data blocks" ); -range!( +range_u64!( /// A type for meta blocks MetaBlocks, - u64, "meta blocks" ); @@ -40,10 +38,9 @@ impl MetaBlocks { } } -range!( +range_u128!( /// A type for bytes Bytes, - u128, "bytes" ); @@ -54,10 +51,9 @@ impl Bytes { } } -range!( +range_u64!( /// A type for sectors Sectors, - u64, "sectors" ); From 4fb3306025cb1168358a491e956b58bf7512f971 Mon Sep 17 00:00:00 2001 From: John Baublitz Date: Thu, 7 Jan 2021 11:02:15 -0500 Subject: [PATCH 3/3] PR revisions --- src/range_macros.rs | 58 ++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/src/range_macros.rs b/src/range_macros.rs index 0f9b0724..ead2d8eb 100644 --- a/src/range_macros.rs +++ b/src/range_macros.rs @@ -7,7 +7,7 @@ macro_rules! range_u64 { ( $(#[$comment:meta])? $T: ident, $display_name: expr) => { range!($(#[$comment])? $T, $display_name, u64, serialize_u64); from_u64!($T); - commut_mul!($T, usize, u64, u32, u16, u8); + mul!($T, u64, u32, u16, u8); div!($T, u64, u32, u16, u8); } } @@ -16,7 +16,7 @@ macro_rules! range_u128 { ( $(#[$comment:meta])? $T: ident, $display_name: expr) => { range!($(#[$comment])? $T, $display_name, u128, serialize_u128); from_u128!($T); - commut_mul!($T, usize, u128, u64, u32, u16, u8); + mul!($T, u128, u64, u32, u16, u8); div!($T, u128, u64, u32, u16, u8); } } @@ -38,7 +38,6 @@ macro_rules! range { add_assign!($T); sub!($T); sub_assign!($T); - mul!($T, $inner); rem!($T); deref!($T, $inner); }; @@ -223,30 +222,51 @@ macro_rules! div { // Define a complete set of multiplication operations. macro_rules! mul { - ($T:ident, $inner:ty) => { - impl std::ops::Mul for $T - where - $T: From, - { - type Output = $T; - fn mul(self, rhs: T) -> $T { - $T(self.0 * $T::from(rhs).0) + ($T:ident, $inner:ty, $($t:ty),+) => { + $( + impl std::ops::Mul<$t> for $T { + type Output = $T; + fn mul(self, rhs: $t) -> $T { + $T(self.0 * <$inner>::from(rhs)) + } } - } - }; -} -macro_rules! commut_mul { - ($T:ident, $( $t:ty ),+) => { - $( impl std::ops::Mul<$T> for $t { type Output = $T; fn mul(self, rhs: $T) -> $T { - rhs * self + $T(rhs.0 * <$inner>::from(self)) } } )+ - } + + impl std::ops::Mul<$inner> for $T { + type Output = $T; + fn mul(self, rhs: $inner) -> $T { + $T(self.0 * rhs) + } + } + + impl std::ops::Mul<$T> for $inner { + type Output = $T; + fn mul(self, rhs: $T) -> $T { + $T(rhs.0 * self) + } + } + + impl std::ops::Mul for $T { + type Output = $T; + fn mul(self, rhs: usize) -> $T { + $T(self.0 * rhs as $inner) + } + } + + impl std::ops::Mul<$T> for usize { + type Output = $T; + fn mul(self, rhs: $T) -> $T { + $T(rhs.0 * self as $inner) + } + } + }; } // Define a complete set of remainder operations.