use futures::{stream::FuturesUnordered, Future}; use std::sync::Arc; use tokio::sync::RwLock; use clap::Parser; use futures::StreamExt; use logging::setup_logger; mod args; mod bot; mod logging; mod server; pub mod utils; async fn error_wrap(fut: impl Future>) -> anyhow::Result { let res = fut.await?; Ok(res) } #[tokio::main] async fn main() -> anyhow::Result<()> { dotenvy::dotenv().ok(); let args = args::Arguments::parse(); setup_logger(args.log_level)?; let token_lock = Arc::new(RwLock::new(None)); [ // Spawining bot task tokio::task::spawn(bot::start(args.bot.clone(), token_lock.clone())), // Spawning server task. tokio::task::spawn(error_wrap(server::create( args.server.clone(), token_lock.clone(), )?)), ] .into_iter() // Turning all tasks in unirdered futures set. .collect::>() // Grab first completed future .take(1) // Take the value .next() // Await for it to complete .await // Unwrap (since we can guarantee that it's not empty). // Throw all errors by using ??. First for joining task, second from the task itself. .unwrap()??; Ok(()) }