Skip to content

Commit b345f2d

Browse files
committed
add and , rename to
1 parent 0835ba2 commit b345f2d

File tree

8 files changed

+112
-30
lines changed

8 files changed

+112
-30
lines changed

ci/expect_scripts/random.exp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@ set timeout 7
77

88
source ./ci/expect_scripts/shared-code.exp
99

10-
spawn $env(EXAMPLES_DIR)random-seed
10+
spawn $env(EXAMPLES_DIR)random
1111

12-
expect -re "Seed is: \\d+" {
12+
set expected_output [normalize_output "
13+
Random U64 is: \\\d+
14+
Random U32 is: \\\d+
15+
Random bytes are: \\\[\\\d+, \\\d+, \\\d+, \\\d+\\\]
16+
"]
17+
18+
expect -re $expected_output {
1319
expect eof {
1420
check_exit_and_segfault
1521
}

crates/roc_host/src/lib.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,9 @@ pub fn init() {
349349
roc_fx_temp_dir as _,
350350
roc_fx_get_locale as _,
351351
roc_fx_get_locales as _,
352-
roc_fx_random_seed as _,
352+
roc_fx_random_u64 as _,
353+
roc_fx_random_u32 as _,
354+
roc_fx_random_bytes as _,
353355
roc_fx_sqlite_bind as _,
354356
roc_fx_sqlite_column_value as _,
355357
roc_fx_sqlite_columns as _,
@@ -811,8 +813,18 @@ pub extern "C" fn roc_fx_get_locales() -> RocList<RocStr> {
811813
}
812814

813815
#[no_mangle]
814-
pub extern "C" fn roc_fx_random_seed() -> RocResult<u64, IOErr> {
815-
roc_random::seed()
816+
pub extern "C" fn roc_fx_random_u64() -> RocResult<u64, IOErr> {
817+
roc_random::random_u64()
818+
}
819+
820+
#[no_mangle]
821+
pub extern "C" fn roc_fx_random_u32() -> RocResult<u32, IOErr> {
822+
roc_random::random_u32()
823+
}
824+
825+
#[no_mangle]
826+
pub extern "C" fn roc_fx_random_bytes(count: u64) -> RocResult<RocList<u8>, IOErr> {
827+
roc_random::random_bytes(count)
816828
}
817829

818830
#[no_mangle]

crates/roc_random/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "roc_random"
3-
description = "Common functionality for Roc to interface with rand"
3+
description = "Common functionality for Roc to interface with getrandom"
44
authors.workspace = true
55
edition.workspace = true
66
license.workspace = true

crates/roc_random/src/lib.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
1-
use roc_std::RocResult;
1+
use roc_std::{RocList, RocResult};
22
use roc_io_error::IOErr;
33

44

5-
pub fn seed() -> RocResult<u64, IOErr> {
5+
pub fn random_u64() -> RocResult<u64, IOErr> {
66
getrandom::u64()
77
.map_err(|e| std::io::Error::from(e))
88
.map_err(|e| IOErr::from(e))
99
.into()
1010
}
11+
12+
pub fn random_u32() -> RocResult<u32, IOErr> {
13+
getrandom::u32()
14+
.map_err(|e| std::io::Error::from(e))
15+
.map_err(|e| IOErr::from(e))
16+
.into()
17+
}
18+
19+
pub fn random_bytes(count: u64) -> RocResult<RocList<u8>, IOErr> {
20+
let mut buf = RocList::from_iter((0..count).map(|_| 0u8));
21+
getrandom::fill(buf.as_mut_slice())
22+
.map(|_| buf)
23+
.map_err(|e| std::io::Error::from(e))
24+
.map_err(|e| IOErr::from(e))
25+
.into()
26+
}

examples/random-seed.roc

Lines changed: 0 additions & 15 deletions
This file was deleted.

examples/random.roc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
app [main!] { pf: platform "../platform/main.roc" }
2+
3+
# To run this example: check the README.md in this folder
4+
5+
# Demo of basic-cli Random functions
6+
7+
import pf.Stdout
8+
import pf.Random
9+
import pf.Arg exposing [Arg]
10+
11+
main! : List Arg => Result {} _
12+
main! = |_args|
13+
random_u64 = Random.random_u64!({})?
14+
Stdout.line!("Random U64 is: ${Inspect.to_str(random_u64)}")?
15+
16+
random_u32 = Random.random_u32!({})?
17+
Stdout.line!("Random U32 is: ${Inspect.to_str(random_u32)}")?
18+
19+
random_bytes = Random.random_bytes!(4)?
20+
Stdout.line!("Random bytes are: ${Inspect.to_str(random_bytes)}")

platform/Host.roc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ hosted [
3333
hard_link!,
3434
path_type!,
3535
posix_time!,
36-
random_seed!,
36+
random_u64!,
37+
random_u32!,
38+
random_bytes!,
3739
send_request!,
3840
set_cwd!,
3941
sleep_millis!,
@@ -148,4 +150,6 @@ env_var! : Str => Result Str {}
148150
exe_path! : {} => Result (List U8) {}
149151
set_cwd! : List U8 => Result {} {}
150152

151-
random_seed! : {} => Result U64 InternalIOErr.IOErrFromHost
153+
random_u64! : {} => Result U64 InternalIOErr.IOErrFromHost
154+
random_u32! : {} => Result U32 InternalIOErr.IOErrFromHost
155+
random_bytes! : U64 => Result (List U8) InternalIOErr.IOErrFromHost

platform/Random.roc

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module [
22
IOErr,
3-
seed!,
3+
random_u64!,
4+
random_u32!,
5+
random_bytes!,
46
]
57

68
import InternalIOErr
@@ -13,8 +15,45 @@ import Host
1315
IOErr : InternalIOErr.IOErr
1416

1517
## Generate a random U64 using the system's source of randomness.
16-
## This uses the Rust crate `getrandom`.
17-
seed! : {} => Result U64 [RandomErr IOErr]
18-
seed! = |{}|
19-
Host.random_seed!({})
18+
##
19+
## This uses Rust's [getrandom](https://crates.io/crates/getrandom) crate to produce
20+
## a single random 64-bit integer. Note that this is a direct interface to the
21+
## system's source of randomness, meaning that each call introduces a significant
22+
## amount of overhead. If you need to generate a lot of random numbers, consider
23+
## calling this function once to generate a single "seed", then using a library
24+
## such as [roc-random](https://github.com/lukewilliamboswell/roc-random) to generate
25+
## additional random numbers.
26+
##
27+
## > Note that 64 bits is NOT considered sufficient randomness for cryptographic
28+
## applications such as encryption keys. Prefer using `random_bytes()` to generate
29+
## larger random values for security-sensitive applications.
30+
random_u64! : {} => Result U64 [RandomErr IOErr]
31+
random_u64! = |{}|
32+
Host.random_u64!({})
33+
|> Result.map_err(|err| RandomErr(InternalIOErr.handle_err(err)))
34+
35+
## Generate a random U32 using the system's source of randomness.
36+
##
37+
## This uses Rust's [getrandom](https://crates.io/crates/getrandom) crate to produce
38+
## a single random 32-bit integer. Note that this is a direct interface to the
39+
## system's source of randomness, meaning that each call introduces a significant
40+
## amount of overhead. If you need to generate a lot of random numbers, consider
41+
## calling this function once to generate a single "seed", then using a library
42+
## such as [roc-random](https://github.com/lukewilliamboswell/roc-random) to generate
43+
## additional random numbers.
44+
##
45+
## > Note that 32 bits is NOT considered sufficient randomness for cryptographic
46+
## applications such as encryption keys. Prefer using `random_bytes()` to generate
47+
## larger random values for security-sensitive applications.
48+
random_u32! : {} => Result U32 [RandomErr IOErr]
49+
random_u32! = |{}|
50+
Host.random_u32!({})
51+
|> Result.map_err(|err| RandomErr(InternalIOErr.handle_err(err)))
52+
53+
## Generate an arbitrary number of bytes using the system's source of randomness.
54+
## For additional details on the specific source of randomness used on various
55+
## platforms, see the Rust crate [getrandom](https://docs.rs/getrandom/0.3.3/getrandom/index.html).
56+
random_bytes! : U64 => Result (List U8) [RandomErr IOErr]
57+
random_bytes! = |count|
58+
Host.random_bytes!(count)
2059
|> Result.map_err(|err| RandomErr(InternalIOErr.handle_err(err)))

0 commit comments

Comments
 (0)