//! use core::convert::Infallible; use core::future::*; use core::pin::Pin; use axum::serve::*; use tower::Service; use crate::res::*; use crate::req::*; use super::*; type F1 = Pin + Send>>; type Ca = WithGracefulShutdown, S, F1>; /// A Catalyzed application that is ready to be launched. #[repr(transparent)] #[allow(missing_debug_implementations)] pub struct CatalyzedApp(Ca) where State: Clone + Send + Sync + 'static, AxumRouter: for<'a> Service, Error = Infallible, Response = S> + Send + 'static, for<'a> as Service>>::Future: Send, S: Service + Clone + Send + 'static, S::Future: Send; impl IntoFuture for CatalyzedApp where State: Clone + Send + Sync + 'static, AxumRouter: for<'a> Service, Error = Infallible, Response = S> + Send + 'static, for<'a> as Service>>::Future: Send, S: Service + Clone + Send + 'static, S::Future: Send, { type Output = as IntoFuture>::Output; type IntoFuture = as IntoFuture>::IntoFuture; #[inline] fn into_future(self) -> Self::IntoFuture { self.0.into_future() } } impl App where State: Clone + Send + Sync + 'static, AxumRouter: for<'a> Service, Error = Infallible, Response = S> + Send + 'static, for<'a> as Service>>::Future: Send, S: Service + Clone + Send + 'static, S::Future: Send, { /// Catalyzes the application and launches it. /// /// This should be the last method called on the [`App`](crate::App) instance. pub async fn launch(self) -> Result> { let addr = self.address.ok_or(CatalyzerError::NoAddress)?; let tcp = tokio::net::TcpListener::bind(addr).await?; let app = axum::serve(tcp, self.router); Ok(CatalyzedApp(app.with_graceful_shutdown(signal_handler()))) } } #[inline] fn signal_handler() -> Pin + Send>> { use super::runtime::signals::*; Box::pin(async { tokio::select! { _ = ctrl_c() => {}, _ = term() => {}, } }) }