/
lib.rs
79 lines (70 loc) · 1.69 KB
/
lib.rs
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
#[macro_export]
macro_rules! or {
($head:expr $(=> $tail:expr)*) => (
$head
$(
.or_else(|| $tail)
)*
)
}
#[macro_export]
macro_rules! and {
($head:expr $(=> $tail:expr)*) => (
(
|| -> Option<_> {
Some(($head?, $($tail? ),*))
}
)()
)
}
#[macro_export]
macro_rules! try_ {
($($body:stmt);*) => (
(
|| -> Option<_> {
Some({$($body);*})
}
)()
)
}
#[cfg(test)]
mod tests {
#[test]
fn or_works() {
assert_eq!(Some(1), or!(Some(1) => Some(2) => Some(3)));
assert_eq!(Some(2), or!(None => Some(2) => Some(3)));
assert_eq!(Some(3), or!(None => None => Some(3)));
assert_eq!(None::<()>, or!(None => None => None));
}
#[test]
fn and_works() {
assert_eq!(Some((1, 2, 3)), and!(Some(1) => Some(2) => Some(3)));
assert_eq!(None, and!(None => Some(2) => Some(3)));
assert_eq!(None, and!(None => None => Some(3)));
assert_eq!(None, and!(None => None => None));
}
struct Config {
log: Option<LogConfig>,
}
struct LogConfig {
level: Option<String>,
}
#[test]
fn try_works() {
assert_eq!(
Some(6),
try_! {
let x = Some(3);
let y = Some(2);
x? * y?
}
);
let config = Config {
log: Some(LogConfig {
level: Some("debug".to_owned()),
}),
};
let x = try_! { config.log?.level? }.unwrap_or("foo".to_owned());
assert_eq!(x, "debug");
}
}