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
|
#[allow(unused_macros)]
macro_rules! main {
(@bmain) => {{
use std::sync::mpsc;
let (snd, rcv) = mpsc::channel();
let srv = std::thread::spawn(move || server::main(snd));
let _ = rcv.recv();
if let Err(e) = client::main() {
eprintln!("Client exited early with error: {:#}", e);
}
if let Err(e) = srv.join().expect("server thread panicked") {
eprintln!("Server exited early with error: {:#}", e);
}
Ok(())
}};
() => {
mod client;
mod server;
fn main() -> anyhow::Result<()> {
main!(@bmain)
}
};
($($pred:tt)*) => {
#[cfg(all($($pred)*))]
mod client;
#[cfg(all($($pred)*))]
mod server;
#[cfg(all($($pred)*))]
fn main() -> anyhow::Result<()> {
main!(@bmain);
}
#[cfg(not(all($($pred)*)))]
fn main() -> anyhow::Result<()> {
eprintln!("not supported on this platform");
Ok(())
}
};
}
#[allow(unused_macros)]
macro_rules! tokio_main {
(@bmain) => {{
use tokio::sync::oneshot;
let (snd, rcv) = oneshot::channel();
let a = async {
if let Err(e) = main_a(snd).await {
eprintln!("Server exited early with error: {:#}", e);
}
};
let b = async {
if rcv.await.is_ok() {
if let Err(e) = main_b().await {
eprintln!("Client exited early with error: {:#}", e);
}
}
};
tokio::join!(a, b);
Ok(())
}};
() => {
mod client;
mod server;
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
tokio_main!(@bmain)
}
};
(nomod $($pred:tt)*) => {
#[cfg(all($($pred)*))]
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
tokio_main!(@bmain)
}
#[cfg(not(all($($pred)*)))]
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
eprintln!("not supported on this platform or feature set");
Ok(())
}
};
($($pred:tt)*) => {
#[cfg(all($($pred)*))]
mod client;
#[cfg(all($($pred)*))]
mod server;
#[cfg(all($($pred)*))]
use {server::main as main_a, client::main as main_b};
tokio_main!(nomod $($pred)*);
};
}
|