-
Notifications
You must be signed in to change notification settings - Fork 432
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for wasm-bindgen #541
Conversation
Thanks, but I hope someone else can review. (I don't know enough about the target platforms.) |
@fitzgen want to help take a look at this? |
CI is failing on
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! A few comments below, but I'm also not super familiar with the rand
code base.
README.md
Outdated
@@ -119,6 +119,10 @@ optional features are available: | |||
- `serde1` enables serialization for some types, via Serde version 1. | |||
- `stdweb` enables support for `OsRng` on `wasm-unknown-unknown` via `stdweb` | |||
combined with `cargo-web`. | |||
- `stdweb` enables support for `OsRng` on `wasm-unknown-unknown` via |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/stdweb/wasm-bindgen/
Also wasm-unknown-unknown
should be wasm32-unknown-unknown
here and the existing spot above.
use super::OsRngImpl; | ||
|
||
#[derive(Clone)] | ||
pub enum OsRng { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this definition exposed publicly, or does it get wrapped? If the former, might want to hide the fact that it is an enum:
pub struct OsRng(OsRngKind);
enum OsRngKind {
Node(..),
Browser(..),
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah this is wrapped above
Updated! |
src/rngs/os.rs
Outdated
impl OsRngImpl for OsRng { | ||
fn new() -> Result<OsRng, Error> { | ||
if this.window().is_undefined() { | ||
return Ok(OsRng::Node(node_require("crypto"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the logic inverted here or is it simply assumed that node_require("crypto")
will not fail?
I assume that window()
being undefined implies we can't use browser-crypto, so I guess this is just missing a check that NodeCrypto
is available?
(If it really cannot fail then I don't understand why you return errors below instead of falling back to Node
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently it's assumed that require("crypto")
won't fail as I figured that node has had that API for quite some time. Is that something that should be checked for?
I figured below it'd be good to test that if we see we're in a browser whether crypto actually works, and falling back to an error if it looks like an older browser or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The crypto
module has been around since Node 0.x so it's safe to assume importing it won't fail.
crypto.randomFillSync
was backported to Node 6.x, the oldest version still being maintained, so that's also safe to use blindly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I've updated with a comment about this
src/rngs/os.rs
Outdated
} | ||
let crypto: BrowserCrypto = crypto.into(); | ||
if crypto.get_random_values_fn().is_undefined() { | ||
let msg = "crypto.getRandomValues is undefined"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be "window.crypto.getRandomValues is undefined"?
Either way these aren't very user-friendly messages, though I guess they may not need to be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least for browsers window
is the ambient environment so I believe that window.crypto
is basically the same as a bare crypto
Don't forget to update the docs in os.rs (lines 62-64)
|
src/rngs/os.rs
Outdated
// | ||
// > A QuotaExceededError DOMException is thrown if the requested | ||
// > length is greater than 65536 bytes. | ||
65536 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There doesn't appear to be a limit in Nodes API, should this return 65536 in browsers and usize::MAX
on node?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Ah, thanks for the extra docs; makes that clear 👍 |
@alexcrichton can you rebase please? I fixed the build errors in the master branch. Once the CI is green I think this is good to go. |
This commit adds support to implement the `rand` crate on the wasm32-unknown-unknown target with the `wasm-bindgen`-based runtime. This supports being run both in node.js as well as browsers by delegating appropriately. Closes rust-random#478
Done! |
It compiles on unknown-unknown for me using the latest nightly, but if I call rand::random from a wasm-bindgen lib, I receive the following error in browser:
Including rand in cargo.toml doesn't trigger this alone, nor does importing it. Using rand::random does, even if the value isn't passed to JS. |
@David-OConnor interesting! The "am I in a browser" check I think may be subtly wrong here (as I later discovered) which may be what's at fault here perhaps? In any case that's a pretty bad error message :( |
This commit adds support to implement the
rand
crate on thewasm32-unknown-unknown target with the
wasm-bindgen
-based runtime. Thissupports being run both in node.js as well as browsers by delegating
appropriately.
Closes #478