1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
use magnus::{
block::Proc,
error::Error,
method,
scan_args::{get_kwargs, scan_args},
value::Value,
RArray, RHash, Ruby, Symbol,
};
fn example(ruby: &Ruby, _rb_self: Value, args: &[Value]) -> Result<RArray, Error> {
let args = scan_args(args)?;
let (a,): (String,) = args.required;
let (b,): (Option<String>,) = args.optional;
let splat: RArray = args.splat;
let (c,): (Symbol,) = args.trailing;
let kw = get_kwargs::<_, (usize,), (Option<usize>, Option<usize>, Option<usize>), RHash>(
args.keywords,
&["d"],
&["e", "f", "g"],
)?;
let (d,) = kw.required;
let (e, f, g) = kw.optional;
let kw_splat = kw.splat;
let _: Option<Proc> = args.block;
let res = ruby.ary_new_capa(7);
res.push(a)?;
res.push(b)?;
res.push(splat)?;
res.push(c)?;
res.push(d)?;
if let Some(e) = e {
res.push(e)?;
}
res.push(f)?;
if let Some(g) = g {
res.push(g)?;
}
res.push(kw_splat)?;
Ok(res)
}
#[test]
fn it_scans_args() {
let ruby = unsafe { magnus::embed::init() };
ruby.define_global_function("example", method!(example, -1));
let res = ruby.eval::<bool>(r#"
example("a", "b", "splat1", "splat2", :c, d: 1, f: 2, h: 3) == ["a", "b", ["splat1", "splat2"], :c, 1, 2, {h: 3}]
"#).unwrap();
assert!(res);
let res = ruby
.eval::<bool>(
r#"
example("a", :c, d: 1) == ["a", nil, [], :c, 1, nil, {}]
"#,
)
.unwrap();
assert!(res);
}
|