raw
1#![deny(rust_2018_idioms, unsafe_code)]
2
3use bile::config::Config;
4use tracing_subscriber::{layer::SubscriberExt as _, util::SubscriberInitExt as _};
5
6#[tokio::main]
7async fn main() -> bile::utils::error::Result<()> {
8 tracing_subscriber::registry()
9 .with(
10 tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
11 concat!(
12 env!("CARGO_CRATE_NAME"),
13 "=debug,tower_http=debug,axum::rejection=trace",
14 )
15 .into()
16 }),
17 )
18 .with(tracing_subscriber::fmt::layer().without_time())
19 .with(tracing_error::ErrorLayer::default())
20 .init();
21
22 tracing::info!("starting bile");
23
24 let config = Config::load()?;
25
26 if !config.project_root.exists() {
27 tracing::warn!(path=?config.project_root.display(), "configured project_root does not exist");
28 }
29 if config.project_root.read_dir()?.next().is_none() {
30 tracing::warn!(path=?config.project_root.display(), "configured project_root is empty");
31 }
32
33 let addr = format!("[::]:{}", config.port);
34
35 bile::set_config(config.finalize()?);
36
37 let app = bile::routes();
38
39 let listener = tokio::net::TcpListener::bind(addr).await?;
40 tracing::info!("listening on {}", listener.local_addr()?);
41 axum::serve(listener, app)
42 .with_graceful_shutdown(shutdown_signal())
43 .await?;
44
45 Ok(())
46}
47
48async fn shutdown_signal() {
49 let ctrl_c = async {
50 tokio::signal::ctrl_c()
51 .await
52 .expect("failed to install Ctrl+C handler");
53 };
54
55 #[cfg(unix)]
56 let terminate = async {
57 tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
58 .expect("failed to install signal handler")
59 .recv()
60 .await;
61 };
62
63 #[cfg(not(unix))]
64 let terminate = std::future::pending::<()>();
65
66 tokio::select! {
67 _ = ctrl_c => {},
68 _ = terminate => {},
69 }
70}
71