Keyword arguments

Calling a function with custom keyword arguments involves a few small steps:

  1. Create a NamedTuple with the custom arguments with named_tuple!.
  2. Provide those arguments to the function we want to call with ProvideKeyword::provide_keywords.
  3. Call the resulting WithKeywords instance with the positional arguments; WithKeywords implements Call.
use jlrs::prelude::*;

fn main() {
    let handle = Builder::new().start_local().expect("cannot init Julia");

    handle.local_scope::<_, 8>(|mut frame| {
        unsafe {
            let func = Value::eval_string(
                &mut frame,
                "add(a, b; c=3.0, d=4.0, e=5.0) = a + b + c + d + e"
            )
            .expect("an exception occurred");

            let a = Value::new(&mut frame, 1.0);
            let b = Value::new(&mut frame, 2.0);
            let c = Value::new(&mut frame, 5.0);
            let d = Value::new(&mut frame, 1.0);
            let kwargs = named_tuple!(&mut frame, "c" => c, "d" => d)
                .expect("invalid keyword arguments");

            let res = func.call(&mut frame, [a, b])
                .expect("caught exception")
                .unbox::<f64>()
                .expect("not an f64");

            assert_eq!(res, 15.0);

            let res = func
                .call_kw(&mut frame, [a, b], kwargs)
                .expect("caught exception")
                .unbox::<f64>()
                .expect("not an f64");

            assert_eq!(res, 14.0);
        };
    });
}