1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
extern crate proc_macro;
use TokenStream;
use quote;
/// Turns your function with default arguments into valid Rust function.
///
/// This macro will move all the arguments with default values into generated
/// struct and implement [`Default`] for it, modifying the function's signature
/// from `bar(x: A, b: B = B)` to `bar(x: A, BarArgs { b }: BarArgs)`. You don't
/// need to change function's body or anything else (hopefully).
///
/// Generic types would be used in the struct's declaration if defaulted types
/// are generic.
///
/// If you use this, consider also using [`keyword_args!`] when calling the
/// function, otherwise you will have to pass the generated struct manually.
///
/// # Example:
///
/// ```rust
/// default_kwargs::default_args! {
/// #[must_use]
/// #[allow(unused, clippy::unnecessary_wraps)]
/// #[allow(clippy::toplevel_ref_arg, clippy::extra_unused_lifetimes)]
/// pub(in self) unsafe fn unsafe_thingy<'asd, T: Sized>(
/// #[allow(unused)] ref mut _x: &mut (),
/// ref mut y: T = T::default(),
/// ) -> Option<*mut T>
/// where
/// T: Default + Copy,
/// {
/// Some(Box::into_raw(Box::new(*y)))
/// }
/// }
/// ```
///
/// is literally turned into
///
/// ```rust
/// #[allow(unused)]
/// pub(self) struct Unsafe_thingyArgs<T>
/// where
/// T: Default + Copy,
/// {
/// pub(self) y: T,
/// }
/// impl<T> ::core::default::Default for Unsafe_thingyArgs<T>
/// where
/// T: Default + Copy,
/// {
/// fn default() -> Self {
/// Self { y: T::default() }
/// }
/// }
/// #[must_use]
/// #[allow(unused, clippy::unnecessary_wraps)]
/// #[allow(clippy::toplevel_ref_arg, clippy::extra_unused_lifetimes)]
/// pub(self) unsafe fn unsafe_thingy<'asd, T: Sized>(
/// #[allow(unused)] ref mut _x: &mut (),
/// Unsafe_thingyArgs { ref mut y }: Unsafe_thingyArgs<T>,
/// ) -> Option<*mut T>
/// where
/// T: Default + Copy,
/// {
/// Some(Box::into_raw(Box::new(*y)))
/// }
/// ```
///
/// See [crate-level docs](crate) for more info.
/// Turns function call with keyword arguments into plain function, passing the
/// arguments struct, generated by [`default_args!`] macro.
///
/// The main downside is, if you call the function that is not declared in the
/// current scope, this will not work. [`default_args!`] macro responsible of
/// declaring the args struct cannot communicate with this macro, and it is not
/// possible for this macro to see the surrounding scope, so we can't get full
/// path to the struct without knowing the path of the function. That said, when
/// using this macro, either manually import the generated struct (but that
/// might confuse the readers (and possibly you)) or write the full path to the
/// function when calling it inside this macro.
///
/// # Example
///
/// ```rust
/// # mod path { pub(super) struct FooArgs { pub(super) u: () }
/// # impl Default for FooArgs { fn default() -> Self { Self { u: () } } }
/// # pub(super) fn foo(_: FooArgs) {} }
/// use default_kwargs::keyword_args;
/// keyword_args! { path::foo(u = ()) };
/// ```
///
/// is literally turned into
///
/// ```rust
/// # mod path { pub(super) struct FooArgs { pub(super) u: () }
/// # impl Default for FooArgs { fn default() -> Self { Self { u: () } } }
/// # pub(super) fn foo(_: FooArgs) {} }
/// use default_kwargs::keyword_args;
/// path::foo(
/// #[allow(clippy::needless_update)]
/// path::FooArgs {
/// u: (),
/// ..path::FooArgs::default()
/// },
/// );
/// ```
///
/// See [crate-level docs](crate) for more info.