minor fixes

This commit is contained in:
arkpar 2015-12-26 15:48:41 +01:00
parent 416c2ec3e4
commit fa1b74fa53
7 changed files with 103 additions and 57 deletions

View File

@ -1,27 +1,27 @@
//! Unified interfaces for bytes operations on basic types //! Unified interfaces for bytes operations on basic types
//! //!
//! # Examples //! # Examples
//! ```rust //! ```rust
//! extern crate ethcore_util as util; //! extern crate ethcore_util as util;
//! //!
//! fn bytes_convertable() { //! fn bytes_convertable() {
//! use util::bytes::BytesConvertable; //! use util::bytes::BytesConvertable;
//! //!
//! let arr = [0; 5]; //! let arr = [0; 5];
//! let slice: &[u8] = arr.bytes(); //! let slice: &[u8] = arr.bytes();
//! } //! }
//! //!
//! fn to_bytes() { //! fn to_bytes() {
//! use util::bytes::ToBytes; //! use util::bytes::ToBytes;
//! //!
//! let a: Vec<u8> = "hello_world".to_bytes(); //! let a: Vec<u8> = "hello_world".to_bytes();
//! let b: Vec<u8> = 400u32.to_bytes(); //! let b: Vec<u8> = 400u32.to_bytes();
//! let c: Vec<u8> = 0xffffffffffffffffu64.to_bytes(); //! let c: Vec<u8> = 0xffffffffffffffffu64.to_bytes();
//! } //! }
//! //!
//! fn from_bytes() { //! fn from_bytes() {
//! use util::bytes::FromBytes; //! use util::bytes::FromBytes;
//! //!
//! let a = String::from_bytes(&[b'd', b'o', b'g']); //! let a = String::from_bytes(&[b'd', b'o', b'g']);
//! let b = u16::from_bytes(&[0xfa]); //! let b = u16::from_bytes(&[0xfa]);
//! let c = u64::from_bytes(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); //! let c = u64::from_bytes(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
@ -138,7 +138,7 @@ impl <'a> ToBytes for &'a str {
fn to_bytes(&self) -> Vec<u8> { fn to_bytes(&self) -> Vec<u8> {
From::from(*self) From::from(*self)
} }
fn to_bytes_len(&self) -> usize { self.len() } fn to_bytes_len(&self) -> usize { self.len() }
} }
@ -147,7 +147,7 @@ impl ToBytes for String {
let s: &str = self.as_ref(); let s: &str = self.as_ref();
From::from(s) From::from(s)
} }
fn to_bytes_len(&self) -> usize { self.len() } fn to_bytes_len(&self) -> usize { self.len() }
} }
@ -166,6 +166,14 @@ impl ToBytes for u64 {
fn to_bytes_len(&self) -> usize { 8 - self.leading_zeros() as usize / 8 } fn to_bytes_len(&self) -> usize { 8 - self.leading_zeros() as usize / 8 }
} }
impl ToBytes for bool {
fn to_bytes(&self) -> Vec<u8> {
vec![ if *self { 1u8 } else { 0u8 } ]
}
fn to_bytes_len(&self) -> usize { 1 }
}
macro_rules! impl_map_to_bytes { macro_rules! impl_map_to_bytes {
($from: ident, $to: ty) => { ($from: ident, $to: ty) => {
impl ToBytes for $from { impl ToBytes for $from {
@ -182,7 +190,7 @@ impl_map_to_bytes!(u32, u64);
macro_rules! impl_uint_to_bytes { macro_rules! impl_uint_to_bytes {
($name: ident) => { ($name: ident) => {
impl ToBytes for $name { impl ToBytes for $name {
fn to_bytes(&self) -> Vec<u8> { fn to_bytes(&self) -> Vec<u8> {
let mut res= vec![]; let mut res= vec![];
let count = self.to_bytes_len(); let count = self.to_bytes_len();
res.reserve(count); res.reserve(count);
@ -210,7 +218,7 @@ impl <T>ToBytes for T where T: FixedHash {
ptr::copy(self.bytes().as_ptr(), res.as_mut_ptr(), T::size()); ptr::copy(self.bytes().as_ptr(), res.as_mut_ptr(), T::size());
res.set_len(T::size()); res.set_len(T::size());
} }
res res
} }
} }
@ -264,6 +272,17 @@ impl FromBytes for u64 {
} }
} }
impl FromBytes for bool {
fn from_bytes(bytes: &[u8]) -> FromBytesResult<bool> {
match bytes.len() {
0 => Ok(false),
1 => Ok(bytes[0] != 0),
_ => Err(FromBytesError::DataIsTooLong),
}
}
}
macro_rules! impl_map_from_bytes { macro_rules! impl_map_from_bytes {
($from: ident, $to: ident) => { ($from: ident, $to: ident) => {
impl FromBytes for $from { impl FromBytes for $from {

View File

@ -14,7 +14,7 @@ use math::log2;
use uint::U256; use uint::U256;
/// Trait for a fixed-size byte array to be used as the output of hash functions. /// Trait for a fixed-size byte array to be used as the output of hash functions.
/// ///
/// Note: types implementing `FixedHash` must be also `BytesConvertable`. /// Note: types implementing `FixedHash` must be also `BytesConvertable`.
pub trait FixedHash: Sized + BytesConvertable { pub trait FixedHash: Sized + BytesConvertable {
fn new() -> Self; fn new() -> Self;
@ -33,7 +33,7 @@ pub trait FixedHash: Sized + BytesConvertable {
macro_rules! impl_hash { macro_rules! impl_hash {
($from: ident, $size: expr) => { ($from: ident, $size: expr) => {
#[derive(Eq)] #[derive(Eq, Copy)]
pub struct $from (pub [u8; $size]); pub struct $from (pub [u8; $size]);
impl BytesConvertable for $from { impl BytesConvertable for $from {

View File

@ -1,10 +1,10 @@
//! Rlp serialization module //! Rlp serialization module
//! //!
//! Allows encoding, decoding, and view onto rlp-slice //! Allows encoding, decoding, and view onto rlp-slice
//! //!
//!# What should you use when? //!# What should you use when?
//! //!
//!### Use `encode` function when: //!### Use `encode` function when:
//! * You want to encode something inline. //! * You want to encode something inline.
//! * You do not work on big set of data. //! * You do not work on big set of data.
//! * You want to encode whole data structure at once. //! * You want to encode whole data structure at once.
@ -23,7 +23,7 @@
//! * You want to get view onto rlp-slice. //! * You want to get view onto rlp-slice.
//! * You don't want to decode whole rlp at once. //! * You don't want to decode whole rlp at once.
//! //!
//!### Use `UntrustedRlp` when: //!### Use `UntrustedRlp` when:
//! * You are working on untrusted data (~corrupted). //! * You are working on untrusted data (~corrupted).
//! * You need to handle data corruption errors. //! * You need to handle data corruption errors.
//! * You are working on input data. //! * You are working on input data.
@ -47,14 +47,16 @@ pub use self::rlpstream::{RlpStream};
use super::hash::H256; use super::hash::H256;
pub const NULL_RLP: [u8; 1] = [0x80; 1]; pub const NULL_RLP: [u8; 1] = [0x80; 1];
pub const EMPTY_LIST_RLP: [u8; 1] = [0xC0; 1];
pub const SHA3_NULL_RLP: H256 = H256( [0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21] ); pub const SHA3_NULL_RLP: H256 = H256( [0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21] );
pub const SHA3_EMPTY_LIST_RLP: H256 = H256( [0x1d, 0xcc, 0x4d, 0xe8, 0xde, 0xc7, 0x5d, 0x7a, 0xab, 0x85, 0xb5, 0x67, 0xb6, 0xcc, 0xd4, 0x1a, 0xd3, 0x12, 0x45, 0x1b, 0x94, 0x8a, 0x74, 0x13, 0xf0, 0xa1, 0x42, 0xfd, 0x40, 0xd4, 0x93, 0x47] );
/// Shortcut function to decode trusted rlp /// Shortcut function to decode trusted rlp
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
/// let animals: Vec<String> = decode(&data); /// let animals: Vec<String> = decode(&data);
@ -71,7 +73,7 @@ pub fn decode<T>(bytes: &[u8]) -> T where T: Decodable {
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let animals = vec!["cat", "dog"]; /// let animals = vec!["cat", "dog"];
/// let out = encode(&animals); /// let out = encode(&animals);

View File

@ -1,10 +1,11 @@
use rlp::DecoderError; use rlp::{DecoderError, UntrustedRlp};
pub trait Decoder: Sized { pub trait Decoder: Sized {
fn read_value<T, F>(&self, f: F) -> Result<T, DecoderError> fn read_value<T, F>(&self, f: F) -> Result<T, DecoderError>
where F: FnOnce(&[u8]) -> Result<T, DecoderError>; where F: FnOnce(&[u8]) -> Result<T, DecoderError>;
fn as_list(&self) -> Result<Vec<Self>, DecoderError>; fn as_list(&self) -> Result<Vec<Self>, DecoderError>;
fn as_rlp<'a>(&'a self) -> &'a UntrustedRlp<'a>;
} }
pub trait Decodable: Sized { pub trait Decodable: Sized {
@ -22,11 +23,11 @@ pub trait View<'a, 'view>: Sized {
fn new(bytes: &'a [u8]) -> Self; fn new(bytes: &'a [u8]) -> Self;
/// The raw data of the RLP. /// The raw data of the RLP.
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
/// let rlp = Rlp::new(&data); /// let rlp = Rlp::new(&data);
@ -34,7 +35,7 @@ pub trait View<'a, 'view>: Sized {
/// assert_eq!(dog, &[0x83, b'd', b'o', b'g']); /// assert_eq!(dog, &[0x83, b'd', b'o', b'g']);
/// } /// }
/// ``` /// ```
fn raw(&'view self) -> &'a [u8]; fn raw(&'view self) -> &'a [u8];
/// Get the prototype of the RLP. /// Get the prototype of the RLP.
fn prototype(&self) -> Self::Prototype; fn prototype(&self) -> Self::Prototype;
@ -44,11 +45,11 @@ pub trait View<'a, 'view>: Sized {
fn data(&'view self) -> Self::Data; fn data(&'view self) -> Self::Data;
/// Returns number of RLP items. /// Returns number of RLP items.
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
/// let rlp = Rlp::new(&data); /// let rlp = Rlp::new(&data);
@ -60,11 +61,11 @@ pub trait View<'a, 'view>: Sized {
fn item_count(&self) -> usize; fn item_count(&self) -> usize;
/// Returns the number of bytes in the data, or zero if it isn't data. /// Returns the number of bytes in the data, or zero if it isn't data.
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
/// let rlp = Rlp::new(&data); /// let rlp = Rlp::new(&data);
@ -76,14 +77,14 @@ pub trait View<'a, 'view>: Sized {
fn size(&self) -> usize; fn size(&self) -> usize;
/// Get view onto RLP-slice at index. /// Get view onto RLP-slice at index.
/// ///
/// Caches offset to given index, so access to successive /// Caches offset to given index, so access to successive
/// slices is faster. /// slices is faster.
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
/// let rlp = Rlp::new(&data); /// let rlp = Rlp::new(&data);
@ -93,11 +94,11 @@ pub trait View<'a, 'view>: Sized {
fn at(&'view self, index: usize) -> Self::Item; fn at(&'view self, index: usize) -> Self::Item;
/// No value /// No value
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let data = vec![]; /// let data = vec![];
/// let rlp = Rlp::new(&data); /// let rlp = Rlp::new(&data);
@ -107,11 +108,11 @@ pub trait View<'a, 'view>: Sized {
fn is_null(&self) -> bool; fn is_null(&self) -> bool;
/// Contains a zero-length string or zero-length list. /// Contains a zero-length string or zero-length list.
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let data = vec![0xc0]; /// let data = vec![0xc0];
/// let rlp = Rlp::new(&data); /// let rlp = Rlp::new(&data);
@ -121,11 +122,11 @@ pub trait View<'a, 'view>: Sized {
fn is_empty(&self) -> bool; fn is_empty(&self) -> bool;
/// List value /// List value
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
/// let rlp = Rlp::new(&data); /// let rlp = Rlp::new(&data);
@ -135,11 +136,11 @@ pub trait View<'a, 'view>: Sized {
fn is_list(&self) -> bool; fn is_list(&self) -> bool;
/// String value /// String value
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
/// let rlp = Rlp::new(&data); /// let rlp = Rlp::new(&data);
@ -149,11 +150,11 @@ pub trait View<'a, 'view>: Sized {
fn is_data(&self) -> bool; fn is_data(&self) -> bool;
/// Int value /// Int value
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let data = vec![0xc1, 0x10]; /// let data = vec![0xc1, 0x10];
/// let rlp = Rlp::new(&data); /// let rlp = Rlp::new(&data);
@ -164,11 +165,11 @@ pub trait View<'a, 'view>: Sized {
fn is_int(&self) -> bool; fn is_int(&self) -> bool;
/// Get iterator over rlp-slices /// Get iterator over rlp-slices
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g']; /// let data = vec![0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g'];
/// let rlp = Rlp::new(&data); /// let rlp = Rlp::new(&data);
@ -204,7 +205,7 @@ pub trait Stream: Sized {
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let mut stream = RlpStream::new_list(2); /// let mut stream = RlpStream::new_list(2);
/// stream.append(&"cat").append(&"dog"); /// stream.append(&"cat").append(&"dog");
@ -219,11 +220,11 @@ pub trait Stream: Sized {
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let mut stream = RlpStream::new_list(2); /// let mut stream = RlpStream::new_list(2);
/// stream.append_list(2).append(&"cat").append(&"dog"); /// stream.append_list(2).append(&"cat").append(&"dog");
/// stream.append(&""); /// stream.append(&"");
/// let out = stream.out(); /// let out = stream.out();
/// assert_eq!(out, vec![0xca, 0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g', 0x80]); /// assert_eq!(out, vec![0xca, 0xc8, 0x83, b'c', b'a', b't', 0x83, b'd', b'o', b'g', 0x80]);
/// } /// }
@ -235,7 +236,7 @@ pub trait Stream: Sized {
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let mut stream = RlpStream::new_list(2); /// let mut stream = RlpStream::new_list(2);
/// stream.append_empty_data().append_empty_data(); /// stream.append_empty_data().append_empty_data();
@ -249,11 +250,11 @@ pub trait Stream: Sized {
fn append_raw<'a>(&'a mut self, bytes: &[u8], item_count: usize) -> &'a mut Self; fn append_raw<'a>(&'a mut self, bytes: &[u8], item_count: usize) -> &'a mut Self;
/// Clear the output stream so far. /// Clear the output stream so far.
/// ///
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let mut stream = RlpStream::new_list(3); /// let mut stream = RlpStream::new_list(3);
/// stream.append(&"cat"); /// stream.append(&"cat");
@ -269,7 +270,7 @@ pub trait Stream: Sized {
/// ```rust /// ```rust
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use util::rlp::*; /// use util::rlp::*;
/// ///
/// fn main () { /// fn main () {
/// let mut stream = RlpStream::new_list(2); /// let mut stream = RlpStream::new_list(2);
/// stream.append(&"cat"); /// stream.append(&"cat");
@ -284,7 +285,7 @@ pub trait Stream: Sized {
fn raw(&self) -> &[u8]; fn raw(&self) -> &[u8];
/// Streams out encoded bytes. /// Streams out encoded bytes.
/// ///
/// panic! if stream is not finished. /// panic! if stream is not finished.
fn out(self) -> Vec<u8>; fn out(self) -> Vec<u8>;
} }

View File

@ -321,6 +321,10 @@ impl<'a> Decoder for BasicDecoder<'a> {
.collect(); .collect();
Ok(v) Ok(v)
} }
fn as_rlp<'s>(&'s self) -> &'s UntrustedRlp<'s> {
&self.rlp
}
} }
impl<T> Decodable for T where T: FromBytes { impl<T> Decodable for T where T: FromBytes {

View File

@ -6,20 +6,22 @@ use bytes::BytesConvertable;
use hash::{FixedHash, H256}; use hash::{FixedHash, H256};
/// Types implementing this trait are sha3able. /// Types implementing this trait are sha3able.
/// ///
/// ``` /// ```
/// extern crate ethcore_util as util; /// extern crate ethcore_util as util;
/// use std::str::FromStr; /// use std::str::FromStr;
/// use util::sha3::*; /// use util::sha3::*;
/// use util::hash::*; /// use util::hash::*;
/// ///
/// fn main() { /// fn main() {
/// assert_eq!([0u8; 0].sha3(), H256::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap()); /// assert_eq!([0u8; 0].sha3(), H256::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap());
/// } /// }
/// ``` /// ```
pub trait Hashable { pub trait Hashable {
fn sha3(&self) -> H256; fn sha3(&self) -> H256;
fn sha3_into(&self, dest: &mut [u8]); fn sha3_into(&self, dest: &mut [u8]) {
self.sha3().copy_to(dest);
}
} }
impl<T> Hashable for T where T: BytesConvertable { impl<T> Hashable for T where T: BytesConvertable {

View File

@ -52,11 +52,17 @@ macro_rules! construct_uint {
impl $name { impl $name {
/// Conversion to u32 /// Conversion to u32
#[inline] #[inline]
fn low_u32(&self) -> u32 { pub fn low_u32(&self) -> u32 {
let &$name(ref arr) = self; let &$name(ref arr) = self;
arr[0] as u32 arr[0] as u32
} }
/// Conversion to u64
#[inline]
pub fn low_u64(&self) -> u64 {
let &$name(ref arr) = self;
arr[0]
}
/// Return the least number of bits needed to represent the number /// Return the least number of bits needed to represent the number
#[inline] #[inline]
pub fn bits(&self) -> usize { pub fn bits(&self) -> usize {
@ -101,7 +107,7 @@ macro_rules! construct_uint {
pub fn zero() -> $name { pub fn zero() -> $name {
From::from(0u64) From::from(0u64)
} }
#[inline] #[inline]
pub fn one() -> $name { pub fn one() -> $name {
From::from(1u64) From::from(1u64)
@ -410,7 +416,7 @@ macro_rules! construct_uint {
fn from_dec_str(value: &str) -> Result<Self, Self::Err> { fn from_dec_str(value: &str) -> Result<Self, Self::Err> {
Ok(value.bytes() Ok(value.bytes()
.map(|b| b - 48) .map(|b| b - 48)
.fold($name::from(0u64), | acc, c | .fold($name::from(0u64), | acc, c |
// fast multiplication by 10 // fast multiplication by 10
// (acc << 3) + (acc << 1) => acc * 10 // (acc << 3) + (acc << 1) => acc * 10
(acc << 3) + (acc << 1) + $name::from(c) (acc << 3) + (acc << 1) + $name::from(c)
@ -434,6 +440,18 @@ impl From<U128> for U256 {
} }
} }
impl From<U256> for u64 {
fn from(value: U256) -> u64 {
value.low_u64()
}
}
impl From<U256> for u32 {
fn from(value: U256) -> u32 {
value.low_u32()
}
}
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]);