File: scan_args.rs

package info (click to toggle)
rust-magnus 0.7.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,468 kB
  • sloc: ruby: 150; sh: 17; makefile: 2
file content (62 lines) | stat: -rw-r--r-- 1,551 bytes parent folder | download
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);
}