Skip to main content

rustolio_utils/crypto/
rand.rs

1//
2// SPDX-License-Identifier: MPL-2.0
3//
4// Copyright (c) 2026 Tobias Binnewies. All rights reserved.
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at http://mozilla.org/MPL/2.0/.
9//
10
11pub type Result<T> = std::result::Result<T, Error>;
12
13#[derive(Debug, Clone, PartialEq)]
14pub struct Error(
15    #[cfg(not(target_arch = "wasm32"))] getrandom::Error,
16    #[cfg(target_arch = "wasm32")] wasm_bindgen::JsValue,
17);
18
19impl std::fmt::Display for Error {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        write!(f, "{self:?}")
22    }
23}
24
25impl std::error::Error for Error {}
26
27#[cfg(not(target_arch = "wasm32"))]
28impl From<getrandom::Error> for Error {
29    fn from(value: getrandom::Error) -> Self {
30        Self(value)
31    }
32}
33
34#[cfg(target_arch = "wasm32")]
35impl From<wasm_bindgen::JsValue> for Error {
36    fn from(value: wasm_bindgen::JsValue) -> Self {
37        Self(value)
38    }
39}
40
41macro_rules! gen_ints {
42    ($($ty:ident),*) => {
43        $(
44            pub fn $ty() -> Result<$ty> {
45                array().map(|a| $ty::from_be_bytes(a))
46            }
47        )*
48    };
49}
50
51gen_ints!(u8, u16, u32, u64, u128, usize);
52gen_ints!(i8, i16, i32, i64, i128, isize);
53
54pub fn array<const N: usize>() -> Result<[u8; N]> {
55    let mut arr = [0; N];
56    fill(&mut arr)?;
57    Ok(arr)
58}
59
60pub fn fill(dst: &mut [u8]) -> Result<()> {
61    #[cfg(not(target_arch = "wasm32"))]
62    getrandom::fill(dst)?;
63
64    #[cfg(target_arch = "wasm32")]
65    web_sys::window()
66        .expect("No window available")
67        .crypto()?
68        .get_random_values_with_u8_array(dst)?;
69
70    Ok(())
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    fn _test_rand() {
78        let _arr: Result<[u8; 8]> = array::<8>();
79        let _u: Result<u64> = u64();
80        let _u: Result<usize> = usize();
81    }
82}