OptArgs: Optional arguments for Rust functions

This crate adds two macros to make it easy to add optional arguments to functions. - #[optargs] - derive a macro_rules to call a function with optional arguments. - #[derive(optbuilder)] - derive a typed-builder builder for a struct with optional fields.

This crate takes advantage of the recent const_generics in Rust stable (1.51), so our MSRV is 1.51.

Here's how they work:

### Optargs

```rust

[optargs::optfn]

fn example(a: u32, b: Option<&str>) -> bool { todo!() }

// now you can use the function as a macro with optional named arguments let _ = example!(a: 10, b: "abc"); ```

Of note: - All optional arguments will default to none. We don't provide a custom default. - All optional arguments must come after required arguments. - Unnamed positional arguments must be in the correct position. - All arguments can be required, but now you get to name them.

### Optbuilder

```rust

[derive(optbuilder)]

struct Params { a: u32, b: Option }

// Typed-buidler style let params = Params::builder().a(10).b("wasd").build(); ```

How it works:

The #[optargs] macro generates an intermediate builder struct with #[derive(optbuilder)]. It also generates a macro_rules that calls this builder from a given input.

The optbuilder derive macro uses const generics to create a compile-time safe builder for a given struct.

Take this input function: rust fn do_something(a: u32, b: Option<String>) -> bool { todo!() }

We would then generate a macro_rules implementation: rust // Generated code struct do_something {} impl do_something { fn call(f: impl FnOnce(SomethingBuilder<false, false>) -> SomethingBuilder<true, true>) -> () { let args = f(SomethingBuilder::<false, false>::default()); do_something(args.a.unwrap(), args.b) } }

And a builder just for its arguments: ```rust

[derive(Default)]

struct SomethingBuilder { a: Option, b: Option, }

// allow this method on builders without the "a" field set impl SomethingBuilder { fn a(self, a: u32) -> SomethingBuilder { SomethingBuilder { a: Some(a), b: self.b } } }

// allow this method on all builders regardless of state (because it's optional) impl SomethingBuilder { fn b(self, b: String) -> SomethingBuilder { SomethingBuilder { a: self.a, b: Some(b), } } } ```