use std::future::Future;
use super::shutdown::Shutdown;
pub fn bootstrap_with_release<F, Fut, T, E>(release: &str, body: F) -> Result<T, E>
where
F: FnOnce(Shutdown) -> Fut,
Fut: Future<Output = Result<T, E>>,
E: From<super::error::WebServerError>,
{
if let Some(phase) = std::env::args()
.nth(1)
.as_deref()
.and_then(crate::assets::Phase::from_subcommand)
{
match crate::assets::generate_static_assets(phase) {
Ok(()) => std::process::exit(0),
Err(error) => {
eprintln!("{error}");
std::process::exit(1);
}
}
}
#[cfg(feature = "observability")]
let _guard: crate::observability::ObservabilityGuard = {
let environment: crate::Environment = crate::Environment::from_env()
.map_err(|error| E::from(super::error::WebServerError::from(error)))?;
crate::observability::Observability::from_env(environment)
.map_err(|error| E::from(super::error::WebServerError::from(error)))?
.with_release(release)
.init()
};
let runtime: tokio::runtime::Runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("failed to build the tokio runtime");
runtime.block_on(async move {
let shutdown: Shutdown = Shutdown::listen();
body(shutdown).await
})
}
#[macro_export]
macro_rules! bootstrap {
($body:expr) => {
$crate::webserver::bootstrap_with_release(
concat!(env!("CARGO_PKG_NAME"), "@", env!("CARGO_PKG_VERSION")),
$body,
)
};
}