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
#[macro_export]
macro_rules! future_chain_processed {
(
types {}
$( $rest: tt )*
) => {
future_chain_processed! {
types {
Error, ErrorKind, FutureExt, FutureChain;
}
$( $rest )*
}
};
(
types {
$error_name:ident, $error_kind_name:ident,
$future_ext_name:ident, $future_name:ident;
}
$( $rest: tt )*
) => {
future_chain_processed! {
types {
$error_name, $error_kind_name,
$future_ext_name;
}
$( $rest )*
}
#[allow(unused)]
pub type $future_name<T> = ::futures::BoxFuture<T, $error_name>;
#[allow(unused)]
pub use futures::Future;
};
(
types {
$error_name:ident, $error_kind_name:ident,
$future_ext_name:ident;
}
) => {
pub trait $future_ext_name<T> {
fn chain_err<F, E>(self, callback: F) -> ::futures::BoxFuture<T, $error_name>
where F: FnOnce() -> E + 'static + Send,
E: Into<$error_kind_name>;
}
impl<F> $future_ext_name<F::Item> for F
where F: ::futures::future::Future + 'static + Send,
F::Error: ::std::error::Error + Send + 'static,
F::Item: Send,
{
fn chain_err<C, E>(self, callback: C) -> ::futures::BoxFuture<F::Item, $error_name>
where C: FnOnce() -> E + 'static + Send,
E: Into<$error_kind_name>,
{
Box::new(self.then(|r| r.chain_err(callback)))
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! future_chain_processing {
(
({})
types $content:tt
$( $tail:tt )*
) => {
future_chain_processing! {
($content)
$($tail)*
}
};
( ($a:tt) ) => {
future_chain_processed! {
types $a
}
};
}
#[macro_export]
macro_rules! future_chain {
( $( $block_name:ident { $( $block_content:tt )* } )* ) => {
future_chain_processing! {
({})
$($block_name { $( $block_content )* })*
}
};
}