//! 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, Option<&str>) = (None, None); { $( example_src!(@setter_helper inners $key $key $($value)? ); )* } // Validate struct Validator {} impl Validator { fn validate(self) {} } impl Validator { fn a(self) -> Validator { unsafe {std::mem::transmute(self)} } } impl Validator { fn b(self) -> Validator { self }} #[allow(unused_mut)] let mut validator = Validator:: {}; 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); }