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
#[macro_export]
macro_rules! command {
(
$(#[$attr:meta])*
$vis:vis $msg_enum:ident => {
$(requests {
$(
$request_fn:ident($($field:ident : $ty:ty),*) -> $ret:ty;
)*
})?
$(events {
$(
$event_fn:ident($($event_field:ident : $event_ty:ty),*);
)*
})?
}
) => {
paste::paste! {
$(#[$attr])*
$vis enum $msg_enum {
$($(
[<$request_fn:camel>] { $($field: $ty,)* callback: tokio::sync::oneshot::Sender<$ret> },
)*)?
$($(
[<$event_fn:camel>] { $($event_field: $event_ty,)* },
)*)?
}
impl std::fmt::Debug for $msg_enum {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
$($(
Self::[<$request_fn:camel>] { .. } => {
write!(f, stringify!([<$request_fn:camel>]))
}
)*)?
$($(
Self::[<$event_fn:camel>] { .. } => {
write!(f, stringify!([<$event_fn:camel>]))
}
)*)?
}
}
}
impl $msg_enum {
$($(
$vis fn [<$request_fn>]($($field : $ty),*) -> (Self, tokio::sync::oneshot::Receiver<$ret>) {
let (tx, rx) = tokio::sync::oneshot::channel();
(
Self::[<$request_fn:camel>] {
$($field,)*
callback: tx,
},
rx
)
}
)*)?
$($(
$vis fn [<$event_fn>]($($event_field : $event_ty),*) -> Self {
Self::[<$event_fn:camel>] {
$($event_field,)*
}
}
)*)?
}
}
};
}
pub fn spawn_background_thread<F1, F2, T>(f: F1, on_return: Option<F2>)
where
F1: FnOnce() -> T + Send + 'static,
F2: FnOnce(T) + Send + 'static,
{
std::thread::spawn(move || {
if let Some(on_return) = on_return {
on_return(f());
} else {
f();
}
});
}