Skip to content

Commit

Permalink
Use getrandom directly instead of rand
Browse files Browse the repository at this point in the history
This works around rust-lang/cargo#5730
for no_std crates that try to use rand.
  • Loading branch information
Amanieu committed Jan 8, 2020
1 parent e95a2ea commit 87805c0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 17 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "const-random"
version = "0.1.6"
version = "0.1.7"
license = "MIT OR Apache-2.0"
repository = "https://github.com/tkaitchuck/constrandom"
documentation = "https://docs.rs/const-random"
Expand All @@ -11,5 +11,5 @@ readme = "README.md"
edition = "2018"

[dependencies]
const-random-macro = { path = "macro", version = "0.1.6"}
const-random-macro = { path = "macro", version = "0.1.7"}
proc-macro-hack = { version = "0.5" }
4 changes: 2 additions & 2 deletions macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "const-random-macro"
version = "0.1.6"
version = "0.1.7"
license = "MIT OR Apache-2.0"
repository = "https://github.com/tkaitchuck/constrandom"
documentation = "https://docs.rs/const-random"
Expand All @@ -14,4 +14,4 @@ proc-macro = true

[dependencies]
proc-macro-hack = { version = "0.5" }
rand = { version = "0.7", default-features = false, features = ["getrandom"] }
getrandom = "0.1"
35 changes: 22 additions & 13 deletions macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
extern crate proc_macro;

use getrandom;
use proc_macro::TokenStream;
use proc_macro_hack::proc_macro_hack;
use rand::rngs::OsRng;
use rand::Rng;
use std::mem;

// Ideally we would use the proper interface for this through the rand crate,
// but due to https://github.com/rust-lang/cargo/issues/5730 this leads to
// issues for no_std crates that try to use rand themselves. So instead we skip
// rand and generate random bytes straight from the OS.
fn gen_random<T>() -> T {
let mut out = [0u8; 16];
getrandom::getrandom(&mut out).unwrap();
unsafe { mem::transmute_copy(&out) }
}

#[proc_macro_hack]
pub fn const_random(input: TokenStream) -> TokenStream {
match &input.to_string()[..] {
"u8" => format!("0x{:x}", OsRng.gen::<u8>()).parse().unwrap(),
"u16" => format!("0x{:x}", OsRng.gen::<u16>()).parse().unwrap(),
"u32" => format!("0x{:x}", OsRng.gen::<u32>()).parse().unwrap(),
"u64" => format!("0x{:x}", OsRng.gen::<u64>()).parse().unwrap(),
"u128" => format!("0x{:x}", OsRng.gen::<u128>()).parse().unwrap(),
"i8" => format!("0x{:x}", OsRng.gen::<i8>()).parse().unwrap(),
"i16" => format!("0x{:x}", OsRng.gen::<i16>()).parse().unwrap(),
"i32" => format!("0x{:x}", OsRng.gen::<i32>()).parse().unwrap(),
"i64" => format!("0x{:x}", OsRng.gen::<i64>()).parse().unwrap(),
"i128" => format!("0x{:x}", OsRng.gen::<i128>()).parse().unwrap(),
"u8" => format!("0x{:x}", gen_random::<u8>()).parse().unwrap(),
"u16" => format!("0x{:x}", gen_random::<u16>()).parse().unwrap(),
"u32" => format!("0x{:x}", gen_random::<u32>()).parse().unwrap(),
"u64" => format!("0x{:x}", gen_random::<u64>()).parse().unwrap(),
"u128" => format!("0x{:x}", gen_random::<u128>()).parse().unwrap(),
"i8" => format!("0x{:x}", gen_random::<i8>()).parse().unwrap(),
"i16" => format!("0x{:x}", gen_random::<i16>()).parse().unwrap(),
"i32" => format!("0x{:x}", gen_random::<i32>()).parse().unwrap(),
"i64" => format!("0x{:x}", gen_random::<i64>()).parse().unwrap(),
"i128" => format!("0x{:x}", gen_random::<i128>()).parse().unwrap(),
_ => panic!("Invalid integer type"),
}

}

0 comments on commit 87805c0

Please sign in to comment.