Function magnus::scan_args::get_kwargs

source ·
pub fn get_kwargs<T, Req, Opt, Splat>(
    kw: RHash,
    required: &[T],
    optional: &[T]
) -> Result<KwArgs<Req, Opt, Splat>, Error>where
    T: Into<Id> + Copy,
    Req: ScanArgsRequired,
    Opt: ScanArgsOpt,
    Splat: ScanArgsKw,
Expand description

Deconstruct keyword arguments.

Extracts required and optional arguments from the given kw hash.

The format of the arguments required is driven by the types in the return value. The stuct KwArgs is returned but the types of its fields are determined by type parameters. The type () is used as a placeholder when a set of arguments is not required.

Panics

This function will panic if required or optional arguments don’t match the length of the Req and Opt type parameters.

Examples

The rough equivalent of def example(a:, b:, c: nil, **rest) would be:

use magnus::{class, error::Error, method, scan_args::get_kwargs, Module, RHash, Value};

fn example(rb_self: Value, kw: RHash) -> Result<Value, Error> {
    let args = get_kwargs(kw, &["a", "b"], &["c"])?;
    let (a, b): (String, usize) = args.required;
    let (c,): (Option<bool>,) = args.optional;
    let rest: RHash = args.splat;

    // ...
}

class::object().define_method("example", method!(example, 1)).unwrap();

The rough equivalent of def example(a: "foo") would be:

use magnus::{class, error::Error, method, scan_args::{get_kwargs, scan_args}, Module, RHash, Value};

fn example(rb_self: Value, args: &[Value]) -> Result<Value, Error> {
    let args = scan_args::<(), (), (), (), _, ()>(args)?;
    let args = get_kwargs(args.keywords, &[], &["a"])?;
    let _: () = args.required;
    let (a,): (Option<String>,) = args.optional;
    let _: () = args.splat;

    let a  = a.unwrap_or_else(|| String::from("foo"));

    // ...
    Ok(a.into())
}

class::object().define_method("example", method!(example, -1)).unwrap();

or, specifying the types slightly differently:

use magnus::{class, error::Error, method, scan_args::{get_kwargs, scan_args}, Module, RHash, Value};

fn example(rb_self: Value, args: &[Value]) -> Result<Value, Error> {
    let args = scan_args::<(), (), (), (), RHash, ()>(args)?;
    let args = get_kwargs::<_, (), (Option<String>,), ()>(args.keywords, &[], &["a"])?;
    let (a,) = args.optional;
    let a  = a.unwrap_or_else(|| String::from("foo"));

    // ...
    Ok(a.into())
}

class::object().define_method("example", method!(example, -1)).unwrap();