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 { let args = scan_args(args)?; let (a,): (String,) = args.required; let (b,): (Option,) = args.optional; let splat: RArray = args.splat; let (c,): (Symbol,) = args.trailing; let kw = get_kwargs::<_, (usize,), (Option, Option, Option), RHash>( args.keywords, &["d"], &["e", "f", "g"], )?; let (d,) = kw.required; let (e, f, g) = kw.optional; let kw_splat = kw.splat; let _: Option = 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::(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::( r#" example("a", :c, d: 1) == ["a", nil, [], :c, 1, nil, {}] "#, ) .unwrap(); assert!(res); }