Removes duplication of macros in types.
This commit is contained in:
		
							parent
							
								
									91ba26a351
								
							
						
					
					
						commit
						2cab2952a8
					
				| @ -14,3 +14,5 @@ byteorder = "1.3.1" | ||||
| [dev-dependencies] | ||||
| yaml-rust = "0.4.2" | ||||
| bls = { path = "../utils/bls" } | ||||
| slot_clock = { path = "../utils/slot_clock" } | ||||
| beacon_chain = { path = "../../beacon_node/beacon_chain" } | ||||
|  | ||||
| @ -24,6 +24,8 @@ pub mod readers; | ||||
| pub mod shard_reassignment_record; | ||||
| pub mod slashable_attestation; | ||||
| pub mod slashable_vote_data; | ||||
| #[macro_use] | ||||
| pub mod slot_epoch_macros; | ||||
| pub mod slot_epoch; | ||||
| pub mod slot_height; | ||||
| pub mod spec; | ||||
|  | ||||
| @ -21,255 +21,6 @@ use std::hash::{Hash, Hasher}; | ||||
| use std::iter::Iterator; | ||||
| use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, Sub, SubAssign}; | ||||
| 
 | ||||
| macro_rules! impl_from_into_u64 { | ||||
|     ($main: ident) => { | ||||
|         impl From<u64> for $main { | ||||
|             fn from(n: u64) -> $main { | ||||
|                 $main(n) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Into<u64> for $main { | ||||
|             fn into(self) -> u64 { | ||||
|                 self.0 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl $main { | ||||
|             pub fn as_u64(&self) -> u64 { | ||||
|                 self.0 | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_from_into_usize { | ||||
|     ($main: ident) => { | ||||
|         impl From<usize> for $main { | ||||
|             fn from(n: usize) -> $main { | ||||
|                 $main(n as u64) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Into<usize> for $main { | ||||
|             fn into(self) -> usize { | ||||
|                 self.0 as usize | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl $main { | ||||
|             pub fn as_usize(&self) -> usize { | ||||
|                 self.0 as usize | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_math_between { | ||||
|     ($main: ident, $other: ident) => { | ||||
|         impl PartialOrd<$other> for $main { | ||||
|             /// Utilizes `partial_cmp` on the underlying `u64`.
 | ||||
|             fn partial_cmp(&self, other: &$other) -> Option<Ordering> { | ||||
|                 Some(self.0.cmp(&(*other).into())) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl PartialEq<$other> for $main { | ||||
|             fn eq(&self, other: &$other) -> bool { | ||||
|                 let other: u64 = (*other).into(); | ||||
|                 self.0 == other | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Add<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn add(self, other: $other) -> $main { | ||||
|                 $main::from(self.0.saturating_add(other.into())) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl AddAssign<$other> for $main { | ||||
|             fn add_assign(&mut self, other: $other) { | ||||
|                 self.0 = self.0.saturating_add(other.into()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Sub<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn sub(self, other: $other) -> $main { | ||||
|                 $main::from(self.0.saturating_sub(other.into())) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl SubAssign<$other> for $main { | ||||
|             fn sub_assign(&mut self, other: $other) { | ||||
|                 self.0 = self.0.saturating_sub(other.into()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Mul<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn mul(self, rhs: $other) -> $main { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 $main::from(self.0.saturating_mul(rhs)) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl MulAssign<$other> for $main { | ||||
|             fn mul_assign(&mut self, rhs: $other) { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 self.0 = self.0.saturating_mul(rhs) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Div<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn div(self, rhs: $other) -> $main { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 if rhs == 0 { | ||||
|                     panic!("Cannot divide by zero-valued Slot/Epoch") | ||||
|                 } | ||||
|                 $main::from(self.0 / rhs) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl DivAssign<$other> for $main { | ||||
|             fn div_assign(&mut self, rhs: $other) { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 if rhs == 0 { | ||||
|                     panic!("Cannot divide by zero-valued Slot/Epoch") | ||||
|                 } | ||||
|                 self.0 = self.0 / rhs | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Rem<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn rem(self, modulus: $other) -> $main { | ||||
|                 let modulus: u64 = modulus.into(); | ||||
|                 $main::from(self.0 % modulus) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_math { | ||||
|     ($type: ident) => { | ||||
|         impl $type { | ||||
|             pub fn saturating_sub<T: Into<$type>>(&self, other: T) -> $type { | ||||
|                 *self - other.into() | ||||
|             } | ||||
| 
 | ||||
|             pub fn saturating_add<T: Into<$type>>(&self, other: T) -> $type { | ||||
|                 *self + other.into() | ||||
|             } | ||||
| 
 | ||||
|             pub fn checked_div<T: Into<$type>>(&self, rhs: T) -> Option<$type> { | ||||
|                 let rhs: $type = rhs.into(); | ||||
|                 if rhs == 0 { | ||||
|                     None | ||||
|                 } else { | ||||
|                     Some(*self / rhs) | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             pub fn is_power_of_two(&self) -> bool { | ||||
|                 self.0.is_power_of_two() | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Ord for $type { | ||||
|             fn cmp(&self, other: &$type) -> Ordering { | ||||
|                 let other: u64 = (*other).into(); | ||||
|                 self.0.cmp(&other) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_display { | ||||
|     ($type: ident) => { | ||||
|         impl fmt::Display for $type { | ||||
|             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|                 write!(f, "{}", self.0) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl slog::Value for $type { | ||||
|             fn serialize( | ||||
|                 &self, | ||||
|                 record: &slog::Record, | ||||
|                 key: slog::Key, | ||||
|                 serializer: &mut slog::Serializer, | ||||
|             ) -> slog::Result { | ||||
|                 self.0.serialize(record, key, serializer) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_ssz { | ||||
|     ($type: ident) => { | ||||
|         impl Encodable for $type { | ||||
|             fn ssz_append(&self, s: &mut SszStream) { | ||||
|                 s.append(&self.0); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Decodable for $type { | ||||
|             fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { | ||||
|                 let (value, i) = <_>::ssz_decode(bytes, i)?; | ||||
| 
 | ||||
|                 Ok(($type(value), i)) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl TreeHash for $type { | ||||
|             fn hash_tree_root(&self) -> Vec<u8> { | ||||
|                 let mut result: Vec<u8> = vec![]; | ||||
|                 result.append(&mut self.0.hash_tree_root()); | ||||
|                 hash(&result) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl<T: RngCore> TestRandom<T> for $type { | ||||
|             fn random_for_test(rng: &mut T) -> Self { | ||||
|                 $type::from(u64::random_for_test(rng)) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_hash { | ||||
|     ($type: ident) => { | ||||
|         // Implemented to stop clippy lint:
 | ||||
|         // https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
 | ||||
|         impl Hash for $type { | ||||
|             fn hash<H: Hasher>(&self, state: &mut H) { | ||||
|                 ssz_encode(self).hash(state) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_common { | ||||
|     ($type: ident) => { | ||||
|         impl_from_into_u64!($type); | ||||
|         impl_from_into_usize!($type); | ||||
|         impl_math_between!($type, $type); | ||||
|         impl_math_between!($type, u64); | ||||
|         impl_math!($type); | ||||
|         impl_display!($type); | ||||
|         impl_ssz!($type); | ||||
|         impl_hash!($type); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| #[derive(Eq, Debug, Clone, Copy, Default, Serialize)] | ||||
| pub struct Slot(u64); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										265
									
								
								eth2/types/src/slot_epoch_macros.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								eth2/types/src/slot_epoch_macros.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,265 @@ | ||||
| macro_rules! impl_from_into_u64 { | ||||
|     ($main: ident) => { | ||||
|         impl From<u64> for $main { | ||||
|             fn from(n: u64) -> $main { | ||||
|                 $main(n) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Into<u64> for $main { | ||||
|             fn into(self) -> u64 { | ||||
|                 self.0 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl $main { | ||||
|             pub fn as_u64(&self) -> u64 { | ||||
|                 self.0 | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| // need to truncate for some fork-choice algorithms
 | ||||
| macro_rules! impl_into_u32 { | ||||
|     ($main: ident) => { | ||||
|         impl Into<u32> for $main { | ||||
|             fn into(self) -> u32 { | ||||
|                 self.0 as u32 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl $main { | ||||
|             pub fn as_u32(&self) -> u32 { | ||||
|                 self.0 as u32 | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_from_into_usize { | ||||
|     ($main: ident) => { | ||||
|         impl From<usize> for $main { | ||||
|             fn from(n: usize) -> $main { | ||||
|                 $main(n as u64) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Into<usize> for $main { | ||||
|             fn into(self) -> usize { | ||||
|                 self.0 as usize | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl $main { | ||||
|             pub fn as_usize(&self) -> usize { | ||||
|                 self.0 as usize | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_math_between { | ||||
|     ($main: ident, $other: ident) => { | ||||
|         impl PartialOrd<$other> for $main { | ||||
|             /// Utilizes `partial_cmp` on the underlying `u64`.
 | ||||
|             fn partial_cmp(&self, other: &$other) -> Option<Ordering> { | ||||
|                 Some(self.0.cmp(&(*other).into())) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl PartialEq<$other> for $main { | ||||
|             fn eq(&self, other: &$other) -> bool { | ||||
|                 let other: u64 = (*other).into(); | ||||
|                 self.0 == other | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Add<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn add(self, other: $other) -> $main { | ||||
|                 $main::from(self.0.saturating_add(other.into())) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl AddAssign<$other> for $main { | ||||
|             fn add_assign(&mut self, other: $other) { | ||||
|                 self.0 = self.0.saturating_add(other.into()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Sub<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn sub(self, other: $other) -> $main { | ||||
|                 $main::from(self.0.saturating_sub(other.into())) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl SubAssign<$other> for $main { | ||||
|             fn sub_assign(&mut self, other: $other) { | ||||
|                 self.0 = self.0.saturating_sub(other.into()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Mul<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn mul(self, rhs: $other) -> $main { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 $main::from(self.0.saturating_mul(rhs)) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl MulAssign<$other> for $main { | ||||
|             fn mul_assign(&mut self, rhs: $other) { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 self.0 = self.0.saturating_mul(rhs) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Div<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn div(self, rhs: $other) -> $main { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 if rhs == 0 { | ||||
|                     panic!("Cannot divide by zero-valued Slot/Epoch") | ||||
|                 } | ||||
|                 $main::from(self.0 / rhs) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl DivAssign<$other> for $main { | ||||
|             fn div_assign(&mut self, rhs: $other) { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 if rhs == 0 { | ||||
|                     panic!("Cannot divide by zero-valued Slot/Epoch") | ||||
|                 } | ||||
|                 self.0 = self.0 / rhs | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Rem<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn rem(self, modulus: $other) -> $main { | ||||
|                 let modulus: u64 = modulus.into(); | ||||
|                 $main::from(self.0 % modulus) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_math { | ||||
|     ($type: ident) => { | ||||
|         impl $type { | ||||
|             pub fn saturating_sub<T: Into<$type>>(&self, other: T) -> $type { | ||||
|                 *self - other.into() | ||||
|             } | ||||
| 
 | ||||
|             pub fn saturating_add<T: Into<$type>>(&self, other: T) -> $type { | ||||
|                 *self + other.into() | ||||
|             } | ||||
| 
 | ||||
|             pub fn checked_div<T: Into<$type>>(&self, rhs: T) -> Option<$type> { | ||||
|                 let rhs: $type = rhs.into(); | ||||
|                 if rhs == 0 { | ||||
|                     None | ||||
|                 } else { | ||||
|                     Some(*self / rhs) | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             pub fn is_power_of_two(&self) -> bool { | ||||
|                 self.0.is_power_of_two() | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Ord for $type { | ||||
|             fn cmp(&self, other: &$type) -> Ordering { | ||||
|                 let other: u64 = (*other).into(); | ||||
|                 self.0.cmp(&other) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_display { | ||||
|     ($type: ident) => { | ||||
|         impl fmt::Display for $type { | ||||
|             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|                 write!(f, "{}", self.0) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl slog::Value for $type { | ||||
|             fn serialize( | ||||
|                 &self, | ||||
|                 record: &slog::Record, | ||||
|                 key: slog::Key, | ||||
|                 serializer: &mut slog::Serializer, | ||||
|             ) -> slog::Result { | ||||
|                 self.0.serialize(record, key, serializer) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_ssz { | ||||
|     ($type: ident) => { | ||||
|         impl Encodable for $type { | ||||
|             fn ssz_append(&self, s: &mut SszStream) { | ||||
|                 s.append(&self.0); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Decodable for $type { | ||||
|             fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { | ||||
|                 let (value, i) = <_>::ssz_decode(bytes, i)?; | ||||
| 
 | ||||
|                 Ok(($type(value), i)) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl TreeHash for $type { | ||||
|             fn hash_tree_root(&self) -> Vec<u8> { | ||||
|                 let mut result: Vec<u8> = vec![]; | ||||
|                 result.append(&mut self.0.hash_tree_root()); | ||||
|                 hash(&result) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl<T: RngCore> TestRandom<T> for $type { | ||||
|             fn random_for_test(rng: &mut T) -> Self { | ||||
|                 $type::from(u64::random_for_test(rng)) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_hash { | ||||
|     ($type: ident) => { | ||||
|         // Implemented to stop clippy lint:
 | ||||
|         // https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
 | ||||
|         impl Hash for $type { | ||||
|             fn hash<H: Hasher>(&self, state: &mut H) { | ||||
|                 ssz_encode(self).hash(state) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_common { | ||||
|     ($type: ident) => { | ||||
|         impl_from_into_u64!($type); | ||||
|         impl_from_into_usize!($type); | ||||
|         impl_math_between!($type, $type); | ||||
|         impl_math_between!($type, u64); | ||||
|         impl_math!($type); | ||||
|         impl_display!($type); | ||||
|         impl_ssz!($type); | ||||
|         impl_hash!($type); | ||||
|     }; | ||||
| } | ||||
| @ -1,290 +1,13 @@ | ||||
| // Copyright 2019 Sigma Prime Pty Ltd.
 | ||||
| //
 | ||||
| // Permission is hereby granted, free of charge, to any person obtaining a
 | ||||
| // copy of this software and associated documentation files (the "Software"),
 | ||||
| // to deal in the Software without restriction, including without limitation
 | ||||
| // the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | ||||
| // and/or sell copies of the Software, and to permit persons to whom the
 | ||||
| // Software is furnished to do so, subject to the following conditions:
 | ||||
| //
 | ||||
| // The above copyright notice and this permission notice shall be included in
 | ||||
| // all copies or substantial portions of the Software.
 | ||||
| //
 | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 | ||||
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | ||||
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | ||||
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | ||||
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | ||||
| // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | ||||
| // DEALINGS IN THE SOFTWARE.
 | ||||
| 
 | ||||
| use crate::slot_epoch::{Epoch, Slot}; | ||||
| use crate::test_utils::TestRandom; | ||||
| use rand::RngCore; | ||||
| use serde_derive::Serialize; | ||||
| use slog; | ||||
| use ssz::{hash, ssz_encode, Decodable, DecodeError, Encodable, SszStream, TreeHash}; | ||||
| use std::cmp::{Ord, Ordering}; | ||||
| use std::fmt; | ||||
| use std::hash::{Hash, Hasher}; | ||||
| use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, Sub, SubAssign}; | ||||
| 
 | ||||
| macro_rules! impl_from_into_u64 { | ||||
|     ($main: ident) => { | ||||
|         impl From<u64> for $main { | ||||
|             fn from(n: u64) -> $main { | ||||
|                 $main(n) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Into<u64> for $main { | ||||
|             fn into(self) -> u64 { | ||||
|                 self.0 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl $main { | ||||
|             pub fn as_u64(&self) -> u64 { | ||||
|                 self.0 | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| // need to truncate for some fork-choice algorithms
 | ||||
| macro_rules! impl_into_u32 { | ||||
|     ($main: ident) => { | ||||
|         impl Into<u32> for $main { | ||||
|             fn into(self) -> u32 { | ||||
|                 self.0 as u32 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl $main { | ||||
|             pub fn as_u32(&self) -> u32 { | ||||
|                 self.0 as u32 | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| macro_rules! impl_from_into_usize { | ||||
|     ($main: ident) => { | ||||
|         impl From<usize> for $main { | ||||
|             fn from(n: usize) -> $main { | ||||
|                 $main(n as u64) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Into<usize> for $main { | ||||
|             fn into(self) -> usize { | ||||
|                 self.0 as usize | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl $main { | ||||
|             pub fn as_usize(&self) -> usize { | ||||
|                 self.0 as usize | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_math_between { | ||||
|     ($main: ident, $other: ident) => { | ||||
|         impl PartialOrd<$other> for $main { | ||||
|             /// Utilizes `partial_cmp` on the underlying `u64`.
 | ||||
|             fn partial_cmp(&self, other: &$other) -> Option<Ordering> { | ||||
|                 Some(self.0.cmp(&(*other).into())) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl PartialEq<$other> for $main { | ||||
|             fn eq(&self, other: &$other) -> bool { | ||||
|                 let other: u64 = (*other).into(); | ||||
|                 self.0 == other | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Add<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn add(self, other: $other) -> $main { | ||||
|                 $main::from(self.0.saturating_add(other.into())) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl AddAssign<$other> for $main { | ||||
|             fn add_assign(&mut self, other: $other) { | ||||
|                 self.0 = self.0.saturating_add(other.into()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Sub<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn sub(self, other: $other) -> $main { | ||||
|                 $main::from(self.0.saturating_sub(other.into())) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl SubAssign<$other> for $main { | ||||
|             fn sub_assign(&mut self, other: $other) { | ||||
|                 self.0 = self.0.saturating_sub(other.into()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Mul<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn mul(self, rhs: $other) -> $main { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 $main::from(self.0.saturating_mul(rhs)) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl MulAssign<$other> for $main { | ||||
|             fn mul_assign(&mut self, rhs: $other) { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 self.0 = self.0.saturating_mul(rhs) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Div<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn div(self, rhs: $other) -> $main { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 if rhs == 0 { | ||||
|                     panic!("Cannot divide by zero-valued Slot/Epoch") | ||||
|                 } | ||||
|                 $main::from(self.0 / rhs) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl DivAssign<$other> for $main { | ||||
|             fn div_assign(&mut self, rhs: $other) { | ||||
|                 let rhs: u64 = rhs.into(); | ||||
|                 if rhs == 0 { | ||||
|                     panic!("Cannot divide by zero-valued Slot/Epoch") | ||||
|                 } | ||||
|                 self.0 = self.0 / rhs | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Rem<$other> for $main { | ||||
|             type Output = $main; | ||||
| 
 | ||||
|             fn rem(self, modulus: $other) -> $main { | ||||
|                 let modulus: u64 = modulus.into(); | ||||
|                 $main::from(self.0 % modulus) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_math { | ||||
|     ($type: ident) => { | ||||
|         impl $type { | ||||
|             pub fn saturating_sub<T: Into<$type>>(&self, other: T) -> $type { | ||||
|                 *self - other.into() | ||||
|             } | ||||
| 
 | ||||
|             pub fn saturating_add<T: Into<$type>>(&self, other: T) -> $type { | ||||
|                 *self + other.into() | ||||
|             } | ||||
| 
 | ||||
|             pub fn checked_div<T: Into<$type>>(&self, rhs: T) -> Option<$type> { | ||||
|                 let rhs: $type = rhs.into(); | ||||
|                 if rhs == 0 { | ||||
|                     None | ||||
|                 } else { | ||||
|                     Some(*self / rhs) | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             pub fn is_power_of_two(&self) -> bool { | ||||
|                 self.0.is_power_of_two() | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Ord for $type { | ||||
|             fn cmp(&self, other: &$type) -> Ordering { | ||||
|                 let other: u64 = (*other).into(); | ||||
|                 self.0.cmp(&other) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_display { | ||||
|     ($type: ident) => { | ||||
|         impl fmt::Display for $type { | ||||
|             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||||
|                 write!(f, "{}", self.0) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl slog::Value for $type { | ||||
|             fn serialize( | ||||
|                 &self, | ||||
|                 record: &slog::Record, | ||||
|                 key: slog::Key, | ||||
|                 serializer: &mut slog::Serializer, | ||||
|             ) -> slog::Result { | ||||
|                 self.0.serialize(record, key, serializer) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_ssz { | ||||
|     ($type: ident) => { | ||||
|         impl Encodable for $type { | ||||
|             fn ssz_append(&self, s: &mut SszStream) { | ||||
|                 s.append(&self.0); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl Decodable for $type { | ||||
|             fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { | ||||
|                 let (value, i) = <_>::ssz_decode(bytes, i)?; | ||||
| 
 | ||||
|                 Ok(($type(value), i)) | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         impl TreeHash for $type { | ||||
|             fn hash_tree_root(&self) -> Vec<u8> { | ||||
|                 let mut result: Vec<u8> = vec![]; | ||||
|                 result.append(&mut self.0.hash_tree_root()); | ||||
|                 hash(&result) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_hash { | ||||
|     ($type: ident) => { | ||||
|         // Implemented to stop clippy lint:
 | ||||
|         // https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
 | ||||
|         impl Hash for $type { | ||||
|             fn hash<H: Hasher>(&self, state: &mut H) { | ||||
|                 ssz_encode(self).hash(state) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| macro_rules! impl_common { | ||||
|     ($type: ident) => { | ||||
|         impl_from_into_u64!($type); | ||||
|         impl_from_into_usize!($type); | ||||
|         impl_math_between!($type, $type); | ||||
|         impl_math_between!($type, u64); | ||||
|         impl_math!($type); | ||||
|         impl_display!($type); | ||||
|         impl_ssz!($type); | ||||
|         impl_hash!($type); | ||||
|     }; | ||||
| } | ||||
| /// Beacon block height, effectively `Slot/GENESIS_START_BLOCK`.
 | ||||
| #[derive(Eq, Debug, Clone, Copy, Default, Serialize)] | ||||
| pub struct SlotHeight(u64); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user