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
#[macro_export]
macro_rules! kvfmt_inner {
([$fmt:expr] [$($args:tt)*]) => {
format_args!($fmt, $( $args )*)
};
([""] [$($args:tt)*] ?$name:expr $(, $($t:tt)*)?) => {
$crate::kvfmt_inner!([concat!(stringify!($name), "={:?}")] [$( $args )* $name] $($($t)*)?);
};
([""] [$($args:tt)*] $name:expr $(, $($t:tt)*)?) => {
$crate::kvfmt_inner!([concat!(stringify!($name), "={}")] [$( $args )* $name ] $($($t)*)?);
};
([$fmt:expr] [$($args:tt)*] ?$name:expr $(, $($t:tt)*)?) => {
$crate::kvfmt_inner!([concat!($fmt, " ", stringify!($name), "={:?}")] [$( $args )*, $name] $($($t)*)?);
};
([$fmt:expr] [$($args:tt)*] $name:expr $(, $($t:tt)*)?) => {
$crate::kvfmt_inner!([concat!($fmt, " ", stringify!($name), "={}")] [$( $args )*, $name ] $($($t)*)?);
};
}
#[macro_export]
macro_rules! kvfmt {
($($t:tt)*) => {
std::fmt::format($crate::kvfmt_inner!([""] [] $($t)*));
};
}
#[cfg(test)]
mod tests {
#[test]
fn kv() {
let hi = "henlo!";
assert!(!kvfmt!(?hi, ?hi).is_empty());
assert!(!kvfmt!(hi, hi).is_empty());
assert!(!kvfmt!(?hi, hi).is_empty());
assert!(!kvfmt!(hi, hi, hi).is_empty());
assert!(!kvfmt!(hi, ?hi, hi).is_empty());
assert_eq!("hi=henlo! hi=\"henlo!\"", kvfmt!(hi, ?hi));
}
}