aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormsi2025-11-13 12:02:56 -0300
committermsi2025-11-13 12:02:56 -0300
commitb245dfcf9dd441674b40605df41b2920c13b66f5 (patch)
tree30ea675b5a4fe2a11482891a931b22ea2c9f7a9f
parent9675d584f0c981d4300f6ca06635b3b660f07e99 (diff)
downloadtemplates-b245dfcf9dd441674b40605df41b2920c13b66f5.tar.gz
Start boilerplate axum web
-rw-r--r--web/template/.editorconfig11
-rw-r--r--web/template/.rustfmt.toml19
-rw-r--r--web/template/Cargo.toml7
-rw-r--r--web/template/README.md6
-rw-r--r--web/template/rust-toolchain.toml3
-rw-r--r--web/template/src/helpers.rs56
-rw-r--r--web/template/src/main.rs48
7 files changed, 148 insertions, 2 deletions
diff --git a/web/template/.editorconfig b/web/template/.editorconfig
new file mode 100644
index 0000000..d6c3cc6
--- /dev/null
+++ b/web/template/.editorconfig
@@ -0,0 +1,11 @@
+# https://EditorConfig.org
+root = true
+
+[*]
+charset = utf-8
+trim_trailing_whitespace = true
+end_of_line = lf
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+
diff --git a/web/template/.rustfmt.toml b/web/template/.rustfmt.toml
new file mode 100644
index 0000000..3aff51c
--- /dev/null
+++ b/web/template/.rustfmt.toml
@@ -0,0 +1,19 @@
+style_edition = "2024"
+max_width = 79
+# Make Rust more readable given most people have wide screens nowadays.
+# This is also the setting used by [rustc](https://github.com/rust-lang/rust/blob/master/rustfmt.toml)
+use_small_heuristics = "Max"
+
+# Use field initialize shorthand if possible
+use_field_init_shorthand = true
+
+reorder_modules = true
+
+# All unstable features that we wish for
+# unstable_features = true
+# Provide a cleaner impl order
+# reorder_impl_items = true
+# Provide a cleaner import sort order
+# group_imports = "StdExternalCrate"
+# Group "use" statements by crate
+# imports_granularity = "Crate"
diff --git a/web/template/Cargo.toml b/web/template/Cargo.toml
index 75024cc..9f7146c 100644
--- a/web/template/Cargo.toml
+++ b/web/template/Cargo.toml
@@ -7,3 +7,10 @@ license = "ISC"
edition = "2024"
[dependencies]
+anyhow = "=1.0.100"
+axum = "=0.8.6"
+serde = { version = "=1.0.228", features = ["derive"] }
+tokio = { version = "=1.48.0", features = ["macros", "rt-multi-thread", "signal"] }
+tower-http = { version = "=0.6.6", features = ["timeout", "trace"] }
+tracing = "=0.1.41"
+tracing-subscriber = { version = "=0.3.20", features = ["env-filter"] }
diff --git a/web/template/README.md b/web/template/README.md
index 18f5a8d..3dcf61b 100644
--- a/web/template/README.md
+++ b/web/template/README.md
@@ -1,5 +1,11 @@
# {{project-name}}
+## Run
+
+```
+RUST_LOG=debug cargo run
+```
+
## License
This project is licensed under the ISC license ([LICENSE](LICENSE) or http://opensource.org/licenses/ISC)
diff --git a/web/template/rust-toolchain.toml b/web/template/rust-toolchain.toml
new file mode 100644
index 0000000..02cb8fc
--- /dev/null
+++ b/web/template/rust-toolchain.toml
@@ -0,0 +1,3 @@
+[toolchain]
+channel = "stable"
+profile = "default"
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>")
}