artichoke_backend/extn/stdlib/securerandom/
mruby.rs1use std::ffi::CStr;
4
5use crate::extn::prelude::*;
6use crate::extn::stdlib::securerandom::{self, trampoline};
7
8const SECURE_RANDOM_CSTR: &CStr = c"SecureRandom";
9
10pub fn init(interp: &mut Artichoke) -> InitializeResult<()> {
11 interp.def_file_for_type::<_, SecureRandomFile>("securerandom.rb")?;
12 Ok(())
13}
14
15#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
16struct SecureRandomFile {
17 _private: (),
19}
20
21impl File for SecureRandomFile {
22 type Artichoke = Artichoke;
23 type Error = Error;
24
25 fn require(interp: &mut Self::Artichoke) -> Result<(), Self::Error> {
26 if interp.is_module_defined::<securerandom::SecureRandom>() {
27 return Ok(());
28 }
29
30 let spec = module::Spec::new(interp, "SecureRandom", SECURE_RANDOM_CSTR, None)?;
31 module::Builder::for_spec(interp, &spec)
32 .add_self_method("alphanumeric", securerandom_alphanumeric, sys::mrb_args_opt(1))?
33 .add_self_method("base64", securerandom_base64, sys::mrb_args_opt(1))?
34 .add_self_method("urlsafe_base64", securerandom_urlsafe_base64, sys::mrb_args_opt(2))?
35 .add_self_method("hex", securerandom_hex, sys::mrb_args_opt(1))?
36 .add_self_method("random_bytes", securerandom_random_bytes, sys::mrb_args_opt(1))?
37 .add_self_method("random_number", securerandom_random_number, sys::mrb_args_opt(1))?
38 .add_self_method("uuid", securerandom_uuid, sys::mrb_args_none())?
39 .define()?;
40 interp.def_module::<securerandom::SecureRandom>(spec)?;
41
42 Ok(())
43 }
44}
45
46unsafe extern "C-unwind" fn securerandom_alphanumeric(
47 mrb: *mut sys::mrb_state,
48 _slf: sys::mrb_value,
49) -> sys::mrb_value {
50 let len = mrb_get_args!(mrb, optional = 1);
51 unwrap_interpreter!(mrb, to => guard);
52 let len = len.map(Value::from).and_then(|len| guard.convert(len));
53 let result = trampoline::alphanumeric(&mut guard, len);
54 match result {
55 Ok(value) => value.inner(),
56 Err(exception) => {
57 unsafe { error::raise(guard, exception) }
59 }
60 }
61}
62
63unsafe extern "C-unwind" fn securerandom_base64(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
64 let len = mrb_get_args!(mrb, optional = 1);
65 unwrap_interpreter!(mrb, to => guard);
66 let len = len.map(Value::from).and_then(|len| guard.convert(len));
67 let result = trampoline::base64(&mut guard, len);
68 match result {
69 Ok(value) => value.inner(),
70 Err(exception) => {
71 unsafe { error::raise(guard, exception) }
73 }
74 }
75}
76
77unsafe extern "C-unwind" fn securerandom_urlsafe_base64(
78 mrb: *mut sys::mrb_state,
79 _slf: sys::mrb_value,
80) -> sys::mrb_value {
81 let (len, padding) = mrb_get_args!(mrb, optional = 2);
82 unwrap_interpreter!(mrb, to => guard);
83 let len = len.map(Value::from).and_then(|len| guard.convert(len));
84 let padding = padding.map(Value::from).and_then(|padding| guard.convert(padding));
85 let result = trampoline::urlsafe_base64(&mut guard, len, padding);
86 match result {
87 Ok(value) => value.inner(),
88 Err(exception) => {
89 unsafe { error::raise(guard, exception) }
91 }
92 }
93}
94
95unsafe extern "C-unwind" fn securerandom_hex(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
96 let len = mrb_get_args!(mrb, optional = 1);
97 unwrap_interpreter!(mrb, to => guard);
98 let len = len.map(Value::from).and_then(|len| guard.convert(len));
99 let result = trampoline::hex(&mut guard, len);
100 match result {
101 Ok(value) => value.inner(),
102 Err(exception) => {
103 unsafe { error::raise(guard, exception) }
105 }
106 }
107}
108
109unsafe extern "C-unwind" fn securerandom_random_bytes(
110 mrb: *mut sys::mrb_state,
111 _slf: sys::mrb_value,
112) -> sys::mrb_value {
113 let len = mrb_get_args!(mrb, optional = 1);
114 unwrap_interpreter!(mrb, to => guard);
115 let len = len.map(Value::from).and_then(|len| guard.convert(len));
116 let result = trampoline::random_bytes(&mut guard, len);
117 match result {
118 Ok(value) => value.inner(),
119 Err(exception) => {
120 unsafe { error::raise(guard, exception) }
122 }
123 }
124}
125
126unsafe extern "C-unwind" fn securerandom_random_number(
127 mrb: *mut sys::mrb_state,
128 _slf: sys::mrb_value,
129) -> sys::mrb_value {
130 let max = mrb_get_args!(mrb, optional = 1);
131 unwrap_interpreter!(mrb, to => guard);
132 let max = max.map(Value::from).and_then(|max| guard.convert(max));
133 let result = trampoline::random_number(&mut guard, max);
134 match result {
135 Ok(value) => value.inner(),
136 Err(exception) => {
137 unsafe { error::raise(guard, exception) }
139 }
140 }
141}
142
143unsafe extern "C-unwind" fn securerandom_uuid(mrb: *mut sys::mrb_state, _slf: sys::mrb_value) -> sys::mrb_value {
144 mrb_get_args!(mrb, none);
145 unwrap_interpreter!(mrb, to => guard);
146 let result = trampoline::uuid(&mut guard);
147 match result {
148 Ok(value) => value.inner(),
149 Err(exception) => {
150 unsafe { error::raise(guard, exception) }
152 }
153 }
154}