optargs 0.1.2

Easily create macros for functions with optional arguments
Documentation
//! This example shows how the optfn proc macro expands your function with a macro_rules
//! The goal here is to demistify what gets generated by the macro.

/// How you would go about using optfn
#[optargs::optfn]
fn example(a: i32, b: Option<&str>) {}

/// A rough translation of what opftn generates
#[doc(hidden)]
#[macro_export]
macro_rules! example_src {
    ($($key:ident $(: $value:expr)? ), *) => {
        {
            #[allow(unused_mut)]
            let mut inners: (Option<i32>, Option<&str>) = (None, None);
            { $( example_src!(@setter_helper inners $key $key $($value)? ); )* }

            // Validate
            struct Validator<const A: bool> {}
            impl Validator<true> { fn validate(self) {} }
            impl Validator<false> { fn a(self) -> Validator<true> { unsafe {std::mem::transmute(self)} } }
            impl<const A: bool> Validator<A> { fn b(self) -> Validator<A> { self  }}

            #[allow(unused_mut)]
            let mut validator = Validator::<false> {};
            validator $(.$key())* .validate();
            example(inners.0.unwrap(), inners.1)
        }
    };

    (@setter_helper $src:ident a $key:ident) => {
        $src.0 = Some($key);
    };

    (@setter_helper $src:ident a $key:ident $value:expr) => {
        $src.0 = Some($value);
    };

    (@setter_helper $src:ident b $key:ident) => {
        $src.1 = Some($key);
    };

    (@setter_helper $src:ident b $key:ident $value:expr) => {
        $src.1 = Some($value);
    };
}

fn main() {
    example!(a: 10, b: "asd");

    example_src!(a: 10, b: "asd");
    example_src!(a: 10);

    let a = 10;
    example!(a);
}