#default #kwargs #keyword #default-value

macro default_kwargs

The macro wich enables you to use default and keyword arguments in Rust

1 unstable release

0.1.0 Apr 4, 2022

#10 in #keyword

MIT/Apache

28KB
497 lines

Rust default and keyword macro

github Crates.io docs.rs GitHub Workflow Status

Example

Basic example of using default arguments:

use default_kwargs::{default_args, keyword_args};

default_args! {
    fn thing(x: i32, y: i32 = 42) -> (i32, i32) {
        (x, y)
    }
}

fn main() {
    let (r, s) = keyword_args! { thing(42) };
    assert_eq!(r, 42);
    assert_eq!(s, 42);

    let (r, s) = keyword_args! { thing(42, y = 666) };
    assert_eq!(r, 42);
    assert_eq!(s, 666);
}

Like in the most languages that have this feature, positional argument have to come before any arguments with default value.

Limitations

  • No variadics (fn foo(a: f64, ...))

  • Complex patterns don't work, i.e. Point(x, y): Point = Point(5, 20) would produce an error.

  • You will have to pass defaulted arguments only using keywords. That is, you can't do this:

    use default_kwargs::{default_args, keyword_args};
    
    default_args! {
        fn foo(x: f64 = 3.14) {}
    }
    
    fn main() {
        keyword_args! { foo(2.71) } // error, do `foo(x = 2.71)` instead.
    }
    
  • At least for now, it is required that you use full function path in the keyword_args macro. The reason is that we can't get the full path to the args struct from the name of the function. This might change in the future.

How does it work

Basically, the default_args macro generates a new struct and implements Default for it based on function's name. The example above expands to roughly this:

struct ThingArgs {
    y: i32,
}

impl Default for ThingArgs {
    fn default() -> Self {
        Self { y: 42 }
    }
}

fn thing(x: i32, ThingArgs { y }: ThingArgs) -> (i32, i32) {
    (x, y)
}

And keyword_args does the opposite:

fn main() {
    let (r, s) = thing(
        42,
        ThingArgs {
            ..ThingArgs::default()
        },
    );
}

Credits

Thank you @dtolnay for an amazing work in parsing and macro ecosystems:

License

MIT or Apache License, Version 2.0 at your option.

Dependencies

~2.2–9.5MB
~100K SLoC