artichoke_backend/sys/args.rs
1//! Helpers for retrieving args from mruby function calls.
2
3use super::mrb_aspec;
4
5/// Function requires n arguments.
6///
7/// ```text
8/// @param n
9/// The number of required arguments.
10/// ```
11#[inline]
12#[must_use]
13pub const fn mrb_args_req(n: u32) -> mrb_aspec {
14 // ```c
15 // #define MRB_ARGS_REQ(n) ((mrb_aspec)((n)&0x1f) << 18)
16 // ```
17 (n & 0x1f) << 18
18}
19
20/// Function takes `n` optional arguments
21///
22/// ```text
23/// @param n
24/// The number of optional arguments.
25/// ```
26#[inline]
27#[must_use]
28pub const fn mrb_args_opt(n: u32) -> mrb_aspec {
29 // ```c
30 // #define MRB_ARGS_OPT(n) ((mrb_aspec)((n)&0x1f) << 13)
31 // ```
32 (n & 0x1f) << 13
33}
34
35/// Function takes `n1` mandatory arguments and `n2` optional arguments
36///
37/// ```text
38/// @param n1
39/// The number of required arguments.
40/// @param n2
41/// The number of optional arguments.
42/// ```
43#[inline]
44#[must_use]
45pub const fn mrb_args_req_and_opt(n_req: u32, n_opt: u32) -> mrb_aspec {
46 // ```c
47 // #define MRB_ARGS_ARG(n1,n2) (MRB_ARGS_REQ(n1)|MRB_ARGS_OPT(n2))
48 // ```
49 mrb_args_req(n_req) | mrb_args_opt(n_opt)
50}
51
52/// rest argument
53///
54/// ```ruby
55/// def foo(n1, *rest); end
56/// ```
57#[inline]
58#[must_use]
59pub const fn mrb_args_rest() -> mrb_aspec {
60 // ```c
61 // #define MRB_ARGS_REST() ((mrb_aspec)(1 << 12))
62 // ```
63 1 << 12
64}
65
66/// required arguments after rest
67#[inline]
68#[must_use]
69pub const fn mrb_args_post(n: u32) -> mrb_aspec {
70 // ```c
71 // #define MRB_ARGS_POST(n) ((mrb_aspec)((n)&0x1f) << 7)
72 // ```
73 (n & 0x1f) << 7
74}
75
76/// keyword arguments (`n` of keys, `kdict`)
77#[inline]
78#[must_use]
79pub const fn mrb_args_key(n1: u32, n2: u32) -> mrb_aspec {
80 // ```c
81 // #define MRB_ARGS_KEY(n1,n2) ((mrb_aspec)((((n1)&0x1f) << 2) | ((n2)?(1<<1):0)))
82 // ```
83 if n2 == 0 {
84 (n1 & 0x1f) << 2
85 } else {
86 ((n1 & 0x1f) << 2) | (1 << 1)
87 }
88}
89
90/// Function takes a block argument
91#[inline]
92#[must_use]
93pub const fn mrb_args_block() -> mrb_aspec {
94 // ```c
95 // #define MRB_ARGS_BLOCK() ((mrb_aspec)1)
96 // ```
97 1
98}
99
100/// Function accepts any number of arguments
101#[inline]
102#[must_use]
103pub const fn mrb_args_any() -> mrb_aspec {
104 // ```c
105 // #define MRB_ARGS_ANY() MRB_ARGS_REST()
106 // ```
107 mrb_args_rest()
108}
109
110/// Function accepts no arguments
111#[inline]
112#[must_use]
113pub const fn mrb_args_none() -> mrb_aspec {
114 // ```c
115 // #define MRB_ARGS_NONE() ((mrb_aspec)0)
116 // ```
117 0
118}
119
120/// Format specifiers for [`mrb_get_args`](crate::sys::mrb_get_args) function.
121///
122/// `mrb_get_args` has the following prototype and returns the number of
123/// arguments parsed.
124///
125/// ```c
126/// MRB_API mrb_int mrb_get_args(mrb_state *mrb, const char *format, ...)
127/// ```
128///
129/// `format` must be a C string composed of the following format specifiers:
130///
131/// ```text
132/// string mruby type C type note
133/// ----------------------------------------------------------------------------------------------
134/// o: Object `mrb_value`
135/// C: class/module `mrb_value`
136/// S: String `mrb_value` when ! follows, the value may be nil
137/// A: Array `mrb_value` when ! follows, the value may be nil
138/// H: Hash `mrb_value` when ! follows, the value may be nil
139/// s: String `char*`,`mrb_int` Receive two arguments; s! gives (NULL,0) for nil
140/// z: String `char*` NUL terminated string; z! gives NULL for nil
141/// a: Array `mrb_value*`,`mrb_int` Receive two arguments; a! gives (NULL,0) for nil
142/// f: Float `mrb_float`
143/// i: Integer `mrb_int`
144/// b: Boolean `mrb_bool`
145/// n: Symbol `mrb_sym`
146/// d: Data `void*`,`mrb_data_type` 2nd argument will be used to check data type so it won't be modified
147/// I: Inline struct `void*`
148/// &: Block `mrb_value` &! raises exception if no block given
149/// *: rest argument `mrb_value*`,`mrb_int` The rest of the arguments as an array; *! avoid copy of the stack
150/// |: optional Following arguments are optional
151/// ?: optional given `mrb_bool` true if preceding argument (optional) is given
152/// ```
153pub mod specifiers {
154 /// Could be used to retrieve any type of argument
155 pub const OBJECT: &str = "o";
156
157 /// Retrieve a Class argument
158 pub const CLASS: &str = "C";
159
160 /// Retrieve a Module argument
161 pub const MODULE: &str = "C";
162
163 /// Retrieve a String argument
164 pub const STRING: &str = "S";
165
166 /// Retrieve a String argument or `nil`
167 pub const NILABLE_STRING: &str = "S!";
168
169 /// Retrieve an Array argument
170 pub const ARRAY: &str = "A";
171
172 /// Retrieve an Array argument or `nil`
173 pub const NILABLE_ARRAY: &str = "A!";
174
175 /// Retrieve a Hash argument
176 pub const HASH: &str = "H";
177
178 /// Retrieve a Hash argument or `nil`
179 pub const NILABLE_HASH: &str = "H!";
180
181 /// Retrieve a `CString` and its length. Usable like:
182 ///
183 /// ```c
184 /// mrb_get_args(mrb, "s", &ptr, &plen);
185 /// ```
186 pub const CSTRING_AND_LEN: &str = "s";
187
188 /// Retrieve a `CString` and its length. Gives (NULL, 0) for `nil`. Usable
189 /// like:
190 ///
191 /// ```c
192 /// mrb_get_args(mrb, "s", &ptr, &plen);
193 /// ```
194 pub const NULLABLE_CSTRING_AND_LEN: &str = "s!";
195
196 /// Retrieve a NUL-terminated `CString` argument
197 pub const CSTRING: &str = "z";
198
199 /// Retrieve a NUL-terminated `CString` argument. Gives NULL for `nil`
200 pub const NULLABLE_CSTRING: &str = "z!";
201
202 /// Receive two arguments, a C Array of `mrb_value`s and its length. Usable
203 /// like:
204 ///
205 /// ```c
206 /// mrb_get_args(mrb, "a", &ptr, &blen);
207 /// ```
208 pub const CARRAY_AND_LEN: &str = "a";
209
210 /// Receive two arguments, a C Array of `mrb_value`s and its length. Gives
211 /// (NULL, 0) for `nil`. Usable like:
212 ///
213 /// ```c
214 /// mrb_get_args(mrb, "a", &ptr, &blen);
215 /// ```
216 pub const NULLABLE_CARRAY_AND_LEN: &str = "a!";
217
218 /// Retrieve a Float argument.
219 pub const FLOAT: &str = "f";
220
221 /// Retrieve an Integer argument.
222 pub const INTEGER: &str = "i";
223
224 /// Retrieve a Boolean argument.
225 pub const BOOLEAN: &str = "b";
226
227 /// Retrieve a Symbol argument.
228 pub const SYMBOL: &str = "n";
229
230 /// Receive two arguments, a `void *` pointer to data and an
231 /// `mrb_data_type`.
232 ///
233 /// 2nd argument will be used to check data type so it won't be modified.
234 pub const DATA: &str = "d";
235
236 /// Internal, retrieve a `void *`.
237 pub const INLINE_STRUCT: &str = "I";
238
239 /// Retrieve a Block argument.
240 pub const BLOCK: &str = "&";
241
242 /// Retrieve a Block argument and raise an exception if none is given.
243 pub const BLOCK_REQUIRED: &str = "&!";
244
245 /// Retrieve the rest of arguments as an array; Usable like:
246 ///
247 /// ```c
248 /// mrb_get_args(mrb, "*", &argv, &argc);
249 /// ```
250 pub const REST: &str = "*";
251
252 /// Retrieve the rest of arguments as an array; avoid copy of the stack.
253 ///
254 /// ```c
255 /// mrb_get_args(mrb, "*", &argv, &argc);
256 /// ```
257 pub const REST_NO_COPY: &str = "*!";
258
259 /// The following args specified are optional.
260 pub const FOLLOWING_ARGS_OPTIONAL: &str = "|";
261
262 /// Retrieve a Boolean indicating whether the previous optional argument
263 /// was given.
264 pub const PREVIOUS_OPTIONAL_ARG_GIVEN: &str = "?";
265}