Skip to content

Commit

Permalink
Merge pull request #33 from yangby-cryptape/readable-constructor
Browse files Browse the repository at this point in the history
Add readable constructors via proc-macro.
  • Loading branch information
chaoticlonghair authored Mar 27, 2019
2 parents 1481b3d + 64f50ad commit 6ebdd0e
Show file tree
Hide file tree
Showing 17 changed files with 492 additions and 104 deletions.
5 changes: 4 additions & 1 deletion constructor/src/fixed_hash/core/internal/public_conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,10 @@ impl HashConstructor {
}
);
self.attach_common(part);
let part = quote!(#[fail(display = "failed to parse from string {}", _0)]
let part = quote!(#[fail(
display = "failed to parse from string since {}",
_0
)]
FromStr(
#[fail(cause)]
FromStrError
Expand Down
5 changes: 4 additions & 1 deletion constructor/src/fixed_uint/core/internal/public_conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,10 @@ impl UintConstructor {
}
);
self.attach_common(part);
let part = quote!(#[fail(display = "failed to parse from string {}", _0)]
let part = quote!(#[fail(
display = "failed to parse from string since {}",
_0
)]
FromStr(
#[fail(cause)]
FromStrError
Expand Down
29 changes: 29 additions & 0 deletions fixed-hash-tests/tests/constructor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2018-2019 Cryptape Technologies LLC.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use nfhash::{h128, h4096, H128, H4096};
use std::str::FromStr;

const H64MAX: H4096 = h4096!("0x_ffff_ffff_ffff_ffff");

#[test]
fn constructor() {
{
let x1 = h128!("0x123456789abcdef");
let x2 = h128!("0x00000000000000000123456789abcdef");
let y = H128::from_str("00000000000000000123456789abcdef").unwrap();
assert_eq!(x1, y);
assert_eq!(x2, y);
}
{
let x = h4096!("0x_ffff_ffff_ffff_ffff");
let y = H4096::from_trimmed_hex_str("ffffffffffffffff").unwrap();
assert_eq!(x, y);
assert_eq!(H64MAX, y);
}
}
16 changes: 6 additions & 10 deletions fixed-hash/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,16 @@ categories = ["algorithms", "data-structures"]
license = "Apache-2.0 OR MIT"

[dependencies]
numext-constructor = { version = "~0.1.2", path = "../constructor" }
nfuint = { package = "numext-fixed-uint", version = "~0.1.2", path = "../fixed-uint" }
failure = "~0.1"
rand = { version = "~0.5", optional = true }
heapsize = { version = "~0.4", optional = true }
serde = { version = "~1.0", optional = true }
faster-hex = { version = "~0.1", optional = true }
numext-fixed-hash-core = { path = "core" }
numext-fixed-hash-hack = { path = "hack" }
proc-macro-hack = "~0.5"

[features]
default = []
support_all = ["support_rand", "support_heapsize", "support_serde"]
support_rand = ["rand", "nfuint/support_rand"]
support_heapsize = ["heapsize", "nfuint/support_heapsize"]
support_serde = ["serde", "faster-hex", "nfuint/support_serde"]
support_rand = ["numext-fixed-hash-core/support_rand", "numext-fixed-hash-hack/support_rand"]
support_heapsize = ["numext-fixed-hash-core/support_heapsize", "numext-fixed-hash-hack/support_heapsize"]
support_serde = ["numext-fixed-hash-core/support_serde", "numext-fixed-hash-hack/support_serde"]

[badges]
travis-ci = { repository = "cryptape/rust-numext" }
21 changes: 21 additions & 0 deletions fixed-hash/core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "numext-fixed-hash-core"
version = "0.1.2"
authors = ["Cryptape Technologies <[email protected]>"]
edition = "2018"

[dependencies]
numext-constructor = { version = "~0.1.2", path = "../../constructor" }
failure = "~0.1"
rand = { version = "~0.5", optional = true }
heapsize = { version = "~0.4", optional = true }
serde = { version = "~1.0", optional = true }
faster-hex = { version = "~0.1", optional = true }
numext-fixed-uint = { version = "~0.1.2", path = "../../fixed-uint" }

[features]
default = []
support_all = ["support_rand", "support_heapsize", "support_serde"]
support_rand = ["rand", "numext-fixed-uint/support_rand"]
support_heapsize = ["heapsize", "numext-fixed-uint/support_heapsize"]
support_serde = ["serde", "faster-hex", "numext-fixed-uint/support_serde"]
55 changes: 55 additions & 0 deletions fixed-hash/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2018-2019 Cryptape Technologies LLC.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use failure::Fail;

#[macro_use]
mod tools;

numext_constructor::construct_fixed_hashes!(
H128 {
size = 128,
},
H160 {
size = 160,
},
H224 {
size = 224,
},
H256 {
size = 256,
},
H384 {
size = 384,
},
H512 {
size = 512,
},
H520 {
size = 520,
},
H1024 {
size = 1024,
},
H2048 {
size = 2048,
},
H4096 {
size = 4096,
},
);

convert_between!(U128, H128, 16);
convert_between!(U160, H160, 20);
convert_between!(U224, H224, 28);
convert_between!(U256, H256, 32);
convert_between!(U384, H384, 48);
convert_between!(U512, H512, 64);
convert_between!(U1024, H1024, 128);
convert_between!(U2048, H2048, 256);
convert_between!(U4096, H4096, 512);
14 changes: 7 additions & 7 deletions fixed-hash/src/tools.rs → fixed-hash/core/src/tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

macro_rules! convert_between {
($uint:ident, $hash:ident, $bytes_size:expr) => {
impl<'a> From<&'a nfuint::$uint> for $hash {
impl<'a> From<&'a numext_fixed_uint::$uint> for $hash {
#[inline]
fn from(u: &nfuint::$uint) -> Self {
fn from(u: &numext_fixed_uint::$uint) -> Self {
let mut ret = [0u8; $bytes_size];
u.into_big_endian(&mut ret).unwrap_or_else(|e| {
panic!(
Expand All @@ -23,16 +23,16 @@ macro_rules! convert_between {
ret.into()
}
}
impl From<nfuint::$uint> for $hash {
impl From<numext_fixed_uint::$uint> for $hash {
#[inline]
fn from(u: nfuint::$uint) -> Self {
fn from(u: numext_fixed_uint::$uint) -> Self {
(&u).into()
}
}
impl<'a> From<&'a $hash> for nfuint::$uint {
impl<'a> From<&'a $hash> for numext_fixed_uint::$uint {
#[inline]
fn from(h: &$hash) -> Self {
nfuint::$uint::from_big_endian(h.as_bytes()).unwrap_or_else(|e| {
numext_fixed_uint::$uint::from_big_endian(h.as_bytes()).unwrap_or_else(|e| {
panic!(
"failed to convert from {} to {}: {}",
stringify!($hash),
Expand All @@ -42,7 +42,7 @@ macro_rules! convert_between {
})
}
}
impl From<$hash> for nfuint::$uint {
impl From<$hash> for numext_fixed_uint::$uint {
#[inline]
fn from(h: $hash) -> Self {
(&h).into()
Expand Down
21 changes: 21 additions & 0 deletions fixed-hash/hack/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "numext-fixed-hash-hack"
version = "0.1.2"
authors = ["Cryptape Technologies <[email protected]>"]
edition = "2018"

[lib]
proc-macro = true

[dependencies]
numext-fixed-hash-core = { path = "../core" }
proc-macro-hack = "~0.5"
syn = { version = "~0.15", features = ["extra-traits"] }
quote = "~0.6"
proc-macro2 = "~0.4"

[features]
default = []
support_rand = ["numext-fixed-hash-core/support_rand"]
support_heapsize = ["numext-fixed-hash-core/support_heapsize"]
support_serde = ["numext-fixed-hash-core/support_serde"]
66 changes: 66 additions & 0 deletions fixed-hash/hack/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2018-2019 Cryptape Technologies LLC.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate proc_macro;

use numext_fixed_hash_core as nfhash;
use proc_macro_hack::proc_macro_hack;
use quote::quote;
use syn::parse_macro_input;

macro_rules! impl_hack {
($(($name:ident, $type:ident),)+) => {
$(impl_hack!($name, $type);)+
};
($(($name:ident, $type:ident)),+) => {
$(impl_hack!($name, $type);)+
};
($name:ident, $type:ident) => {
#[proc_macro_hack]
pub fn $name(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as syn::LitStr);
let expanded = {
let input = input.value().replace("_", "");
if &input[..2] != "0x" {
panic!("Input has to be a hexadecimal string with 0x-prefix.");
};
let input_str = &input[2..];
let value = match &input_str[..1] {
"0" => {
nfhash::$type::from_hex_str(input_str)
},
_ => {
nfhash::$type::from_trimmed_hex_str(input_str)
},
}
.unwrap_or_else(|err| {
panic!("Failed to parse the input hexadecimal string: {}", err);
});
let eval_str = format!("{:?}", value);
let eval_ts: proc_macro2::TokenStream = eval_str.parse().unwrap_or_else(|_| {
panic!("Failed to parse the string \"{}\" to TokenStream.", eval_str);
});
quote!(#eval_ts)
};
expanded.into()
}
};
}

impl_hack!(
(h128, H128),
(h160, H160),
(h224, H224),
(h256, H256),
(h384, H384),
(h512, H512),
(h520, H520),
(h1024, H1024),
(h2048, H2048),
(h4096, H4096),
);
59 changes: 15 additions & 44 deletions fixed-hash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,21 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use]
mod tools;
use proc_macro_hack::proc_macro_hack;

use failure::Fail;
pub use numext_fixed_hash_core::*;

numext_constructor::construct_fixed_hashes!(
H128 {
size = 128,
},
H160 {
size = 160,
},
H224 {
size = 224,
},
H256 {
size = 256,
},
H384 {
size = 384,
},
H512 {
size = 512,
},
H520 {
size = 520,
},
H1024 {
size = 1024,
},
H2048 {
size = 2048,
},
H4096 {
size = 4096,
},
);
macro_rules! reexport {
([$($name:ident,)+]) => {
$(reexport!($name);)+
};
([$($name:ident),+]) => {
$(reexport!($name);)+
};
($name:ident) => {
#[proc_macro_hack]
pub use numext_fixed_hash_hack::$name;
};
}

convert_between!(U128, H128, 16);
convert_between!(U160, H160, 20);
convert_between!(U224, H224, 28);
convert_between!(U256, H256, 32);
convert_between!(U384, H384, 48);
convert_between!(U512, H512, 64);
convert_between!(U1024, H1024, 128);
convert_between!(U2048, H2048, 256);
convert_between!(U4096, H4096, 512);
reexport!([h128, h160, h224, h256, h384, h512, h520, h1024, h2048, h4096]);
Loading

0 comments on commit 6ebdd0e

Please sign in to comment.