aboutsummaryrefslogtreecommitdiffstats
path: root/web/template/src
diff options
context:
space:
mode:
authormsi2025-11-13 12:02:56 -0300
committermsi2025-11-13 12:02:56 -0300
commitb245dfcf9dd441674b40605df41b2920c13b66f5 (patch)
tree30ea675b5a4fe2a11482891a931b22ea2c9f7a9f /web/template/src
parent9675d584f0c981d4300f6ca06635b3b660f07e99 (diff)
downloadtemplates-b245dfcf9dd441674b40605df41b2920c13b66f5.tar.gz
Start boilerplate axum web
Diffstat (limited to 'web/template/src')
-rw-r--r--web/template/src/helpers.rs56
-rw-r--r--web/template/src/main.rs48
2 files changed, 102 insertions, 2 deletions
diff --git a/web/template/src/helpers.rs b/web/template/src/helpers.rs
new file mode 100644
index 0000000..4278884
--- /dev/null
+++ b/web/template/src/helpers.rs
@@ -0,0 +1,56 @@
+//
+// Copyright (c) 2025 murilo ijanc' <murilo@ijanc.org>
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//
+
+use tokio::signal;
+
+pub(crate) async fn shutdown_signal() {
+ let ctrl_c = async {
+ signal::ctrl_c().await.expect("failed to install Ctrl+C handler");
+ };
+
+ #[cfg(unix)]
+ let terminate = async {
+ signal::unix::signal(signal::unix::SignalKind::terminate())
+ .expect("failed to install signal handler")
+ .recv()
+ .await;
+ };
+
+ #[cfg(not(unix))]
+ let terminate = std::future::pending::<()>();
+
+ tokio::select! {
+ _ = ctrl_c => {},
+ _ = terminate => {},
+ }
+}
+
+pub(crate) fn init_tracing() {
+ use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
+ tracing_subscriber::registry()
+ .with(
+ tracing_subscriber::EnvFilter::try_from_default_env()
+ .unwrap_or_else(|_| {
+ format!(
+ "{}=debug,tower_http=debug,axum=trace",
+ env!("CARGO_CRATE_NAME")
+ )
+ .into()
+ }),
+ )
+ .with(tracing_subscriber::fmt::layer().without_time())
+ .init();
+}
diff --git a/web/template/src/main.rs b/web/template/src/main.rs
index e7a11a9..9e36cae 100644
--- a/web/template/src/main.rs
+++ b/web/template/src/main.rs
@@ -1,3 +1,47 @@
-fn main() {
- println!("Hello, world!");
+//
+// Copyright (c) 2025 murilo ijanc' <murilo@ijanc.org>
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//
+
+use std::time::Duration;
+
+use axum::{Router, response::Html, routing::get};
+use tokio::net::TcpListener;
+use tower_http::{timeout::TimeoutLayer, trace::TraceLayer};
+use tracing::info;
+
+mod helpers;
+
+#[tokio::main]
+async fn main() -> anyhow::Result<()> {
+ helpers::init_tracing();
+
+ let app = Router::new().route("/", get(handler)).layer((
+ TraceLayer::new_for_http(),
+ TimeoutLayer::new(Duration::from_secs(10)), // TODO(msi): from config
+ ));
+
+ // TODO(msi): from config
+ let listener = TcpListener::bind("0.0.0.0:3000").await?;
+ info!("listening on http://{}", listener.local_addr().unwrap());
+ axum::serve(listener, app)
+ .with_graceful_shutdown(helpers::shutdown_signal())
+ .await?;
+
+ Ok(())
+}
+
+async fn handler() -> Html<&'static str> {
+ Html("<h1>Hello, World {{project-name}} =]</h1>")
}