default_kwargs

Crates.iodefault_kwargs
lib.rsdefault_kwargs
version0.1.0
sourcesrc
created_at2022-04-04 14:53:22.716956
updated_at2022-04-04 14:53:22.716956
descriptionThe macro wich enables you to use default and keyword arguments in Rust
homepage
repositoryhttps://github.com/zohnannor/default_kwargs
max_upload_size
id562059
size54,840
(zohnannor)

documentation

https://docs.rs/default_kwargs

README

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.

Commit count: 8

cargo fmt