implemented rem, lenient from_str, from_dec_str for uint
This commit is contained in:
parent
16cadf1a64
commit
862702b9c7
52
src/uint.rs
52
src/uint.rs
@ -28,6 +28,11 @@ use std::str::FromStr;
|
|||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use rustc_serialize::hex::{FromHex, FromHexError};
|
use rustc_serialize::hex::{FromHex, FromHexError};
|
||||||
|
|
||||||
|
pub trait FromDecStr: Sized {
|
||||||
|
type Err;
|
||||||
|
fn from_dec_str(value: &str) -> Result<Self, Self::Err>;
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! impl_map_from {
|
macro_rules! impl_map_from {
|
||||||
($thing:ident, $from:ty, $to:ty) => {
|
($thing:ident, $from:ty, $to:ty) => {
|
||||||
impl From<$from> for $thing {
|
impl From<$from> for $thing {
|
||||||
@ -139,8 +144,13 @@ macro_rules! construct_uint {
|
|||||||
type Err = FromHexError;
|
type Err = FromHexError;
|
||||||
|
|
||||||
fn from_str(value: &str) -> Result<$name, Self::Err> {
|
fn from_str(value: &str) -> Result<$name, Self::Err> {
|
||||||
let bytes: &[u8] = &try!(value.from_hex());
|
let bytes: Vec<u8> = match value.len() % 2 == 0 {
|
||||||
Ok(From::from(bytes))
|
true => try!(value.from_hex()),
|
||||||
|
false => try!(("0".to_string() + value).from_hex())
|
||||||
|
};
|
||||||
|
|
||||||
|
let bytes_ref: &[u8] = &bytes;
|
||||||
|
Ok(From::from(bytes_ref))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,6 +232,15 @@ macro_rules! construct_uint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Rem<$name> for $name {
|
||||||
|
type Output = $name;
|
||||||
|
|
||||||
|
fn rem(self, other: $name) -> $name {
|
||||||
|
let times = self / other;
|
||||||
|
self - (times * other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl BitAnd<$name> for $name {
|
impl BitAnd<$name> for $name {
|
||||||
type Output = $name;
|
type Output = $name;
|
||||||
|
|
||||||
@ -358,9 +377,21 @@ macro_rules! construct_uint {
|
|||||||
state.finish();
|
state.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromDecStr for $name {
|
||||||
|
type Err = FromHexError;
|
||||||
|
|
||||||
|
/// TODO: optimize, throw appropriate err
|
||||||
|
fn from_dec_str(value: &str) -> Result<Self, Self::Err> {
|
||||||
|
let ten = $name::from(10u64);
|
||||||
|
Ok(value.bytes().map(|b| b - 48).fold($name::from(0u64), | acc, c | acc * ten + $name::from(c) ))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
construct_uint!(U512, 8);
|
||||||
construct_uint!(U256, 4);
|
construct_uint!(U256, 4);
|
||||||
construct_uint!(U128, 2);
|
construct_uint!(U128, 2);
|
||||||
|
|
||||||
@ -374,6 +405,10 @@ impl From<U128> for U256 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub const ZERO_U256: U256 = U256([0x00u64; 4]);
|
pub const ZERO_U256: U256 = U256([0x00u64; 4]);
|
||||||
pub const ONE_U256: U256 = U256([0x01u64, 0x00u64, 0x00u64, 0x00u64]);
|
pub const ONE_U256: U256 = U256([0x01u64, 0x00u64, 0x00u64, 0x00u64]);
|
||||||
pub const BAD_U256: U256 = U256([0xffffffffffffffffu64; 4]);
|
pub const BAD_U256: U256 = U256([0xffffffffffffffffu64; 4]);
|
||||||
@ -381,6 +416,7 @@ pub const BAD_U256: U256 = U256([0xffffffffffffffffu64; 4]);
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use uint::U256;
|
use uint::U256;
|
||||||
|
use uint::FromDecStr;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -565,5 +601,17 @@ mod tests {
|
|||||||
assert_eq!(U256::from(10u64) / U256::from(2u64), U256::from(5u64));
|
assert_eq!(U256::from(10u64) / U256::from(2u64), U256::from(5u64));
|
||||||
assert_eq!(U256::from(10u64) / U256::from(3u64), U256::from(3u64));
|
assert_eq!(U256::from(10u64) / U256::from(3u64), U256::from(3u64));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn uint256_rem() {
|
||||||
|
assert_eq!(U256::from(10u64) % U256::from(1u64), U256::from(0u64));
|
||||||
|
assert_eq!(U256::from(10u64) % U256::from(3u64), U256::from(1u64));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn uint256_from_dec_str() {
|
||||||
|
assert_eq!(U256::from_dec_str("10").unwrap(), U256::from(10u64));
|
||||||
|
assert_eq!(U256::from_dec_str("1024").unwrap(), U256::from(1024u64));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user