logo
macro_rules! register_custom_getrandom {
    ($path:path) => { ... };
}
This is supported on crate feature custom only.
Expand description

Register a function to be invoked by getrandom on unsupported targets.

Writing a custom getrandom implementation

The function to register must have the same signature as getrandom::getrandom. The function can be defined wherever you want, either in root crate or a dependent crate.

For example, if we wanted a failure-getrandom crate containing an implementation that always fails, we would first depend on getrandom (for the Error type) in failure-getrandom/Cargo.toml:

[dependencies]
getrandom = "0.2"

Note that the crate containing this function does not need to enable the "custom" Cargo feature.

Next, in failure-getrandom/src/lib.rs, we define our function:

use core::num::NonZeroU32;
use getrandom::Error;

// Some application-specific error code
const MY_CUSTOM_ERROR_CODE: u32 = Error::CUSTOM_START + 42;
pub fn always_fail(buf: &mut [u8]) -> Result<(), Error> {
    let code = NonZeroU32::new(MY_CUSTOM_ERROR_CODE).unwrap();
    Err(Error::from(code))
}

Registering a custom getrandom implementation

Functions can only be registered in the root binary crate. Attempting to register a function in a non-root crate will result in a linker error. This is similar to #[panic_handler] or #[global_allocator], where helper crates define handlers/allocators but only the binary crate actually uses the functionality.

To register the function, we first depend on failure-getrandom and getrandom in Cargo.toml:

[dependencies]
failure-getrandom = "0.1"
getrandom = { version = "0.2", features = ["custom"] }

Then, we register the function in src/main.rs:

use failure_getrandom::always_fail;
use getrandom::register_custom_getrandom;

register_custom_getrandom!(always_fail);

Now any user of getrandom (direct or indirect) on this target will use the registered function. As noted in the top-level documentation this registration only has an effect on unsupported targets.