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
126
127
128
macro_rules! message_display {
($enumname:ident) => {
impl fmt::Display for $enumname {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.get_message().unwrap())
}
}
}
}
macro_rules! inputs {
() => {};
($(#[$attr:meta])* fn $fnname:ident -> $fnret:ty, $varname:expr, |($kp:tt, $vp:tt)| $code:expr; $($rest:tt)*) => {
$(#[$attr])*
pub fn $fnname() -> $crate::Result<$fnret> {
::std::env::vars_os()
.filter_map(|(k, $vp)| match k.into_string() {
Ok(ref mut s) if s.starts_with($varname) => {
let $kp = &s[$varname.len()..];
$code
}
_ => None
})
.collect()
}
inputs!($($rest)*);
};
($(#[$attr:meta])* fn $fnname:ident -> $fnret:ty, $varname:expr, |$param:tt| $code:expr; $($rest:tt)*) => {
$(#[$attr])*
pub fn $fnname() -> $crate::Result<$fnret> {
let $param = ::std::env::var($varname)?;
$code
}
inputs!($($rest)*);
};
($(#[$attr:meta])* fn $fnname:ident -> $fnret:ty, $varname:expr, parse $kind:ident; $($rest:tt)*) => {
inputs! {
$(#[$attr])*
fn $fnname -> $fnret, $varname,
|s| s.parse().map_err(|e| $crate::Error::from_kind($crate::ErrorKind::$kind(e)));
$($rest)*
}
};
($(#[$attr:meta])* fn $fnname:ident -> $fnret:ty, $varname:expr; $($rest:tt)*) => {
inputs! {
$(#[$attr])*
fn $fnname -> $fnret, $varname, |x| ::std::result::Result::Ok(x);
$($rest)*
}
};
}
macro_rules! outputs {
() => {};
(@inner [($($fndecl:tt)*) ($(($($gen:tt)*))*) ($($rest:tt)*)]
() -> ($(, $n:ident : $t:ty)*)
($($strings:expr),*)
($($vars:tt)*)) => {
$($fndecl)*<$($($gen)*),*>($($n: $t),*) {
println!(concat!($($strings),*) $($vars)*);
}
outputs!($($rest)*);
};
(@inner [$fndecl:tt ($($gen:tt)*) $rest:tt]
(<$typ:ident> $(,)*) -> ($($params:tt)*)
($($strings:tt)*)
($($vars:tt)*)) => {
outputs!(@inner [$fndecl ($($gen)* ($typ: ::std::convert::AsRef<::std::ffi::OsStr> + ?::std::marker::Sized)) $rest]
() -> ($($params)*, n: &$typ)
($($strings)*, "{}")
($($vars)*, ::std::path::Path::new(n).display()));
};
(@inner $thru:tt
($typ:ty $(,)*) -> ($($params:tt)*)
($($strings:tt)*)
($($vars:tt)*)) => {
outputs!(@inner $thru
() -> ($($params)*, n: $typ)
($($strings)*, "{}")
($($vars)*, n));
};
(@inner [$fndecl:tt ($($gen:tt)*) $rest:tt]
(<$typ:ident>, $($types:tt)*) -> ($($params:tt)*)
($($strings:tt)*)
($($vars:tt)*)) => {
outputs!(@inner [$fndecl ($($gen)* ($typ: ::std::convert::AsRef<::std::ffi::OsStr> + ?::std::marker::Sized)) $rest]
($($types),*) -> ($($params)*, n: &$typ)
($($strings)*, "{}", "=")
($($vars)*, ::std::path::Path::new(n).display()));
};
(@inner $thru:tt
($typ:ty, $($types:tt)*) -> ($($params:tt)*)
($($strings:tt)*)
($($vars:tt)*)) => {
outputs!(@inner $thru
($($types)*) -> ($($params)*, n: $typ)
($($strings)*, "{}", "=")
($($vars)*, n));
};
($(#[$attr:meta])* fn $fnname:ident($($types:tt)*) => None; $($rest:tt)*) => {
outputs!(@inner [($(#[$attr])* pub fn $fnname) () ($($rest)*)]
($($types)*,) -> ()
("cargo:")
());
};
($(#[$attr:meta])* fn $fnname:ident($($types:tt)*) => $string:expr; $($rest:tt)*) => {
outputs!(@inner [($(#[$attr])* pub fn $fnname) () ($($rest)*)]
($($types)*,) -> ()
("cargo:", $string, "=")
());
};
}