From f8186ba3968a4b8bad7324227d6b9bb21fc3e8ee Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 13 Dec 2025 21:05:17 -0300 Subject: [PATCH 1/2] Add CI workflow --- .forgejo/workflows/check.yaml | 23 +++++++++++++++++++++++ .justfile | 11 +++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 .forgejo/workflows/check.yaml diff --git a/.forgejo/workflows/check.yaml b/.forgejo/workflows/check.yaml new file mode 100644 index 0000000..03f5e32 --- /dev/null +++ b/.forgejo/workflows/check.yaml @@ -0,0 +1,23 @@ +on: [push] +jobs: + print-content: + runs-on: docker + container: + image: rust:slim + steps: + - name: install action dependencies + run: apt install --no-install-recommends --update -y nodejs + - name: setup toolchain + run: rustup component add rustfmt clippy + - name: checkout code + uses: actions/checkout@v6 + - name: install dependencies + run: cargo install --path . + - name: cargo check + run: cargo check --all-targets + - name: format + run: cargo fmt -- --check + - name: lint + run: cargo clippy -- -Dwarnings + - name: test + run: cargo test diff --git a/.justfile b/.justfile index e6d95d8..871c43b 100644 --- a/.justfile +++ b/.justfile @@ -74,10 +74,17 @@ alias rb := release-build # Lint, check formatting and run tests [group('checks')] -check: lint format-check test +check: format-check lint cargo-check test alias c := check +# Run cargo check +[group('checks')] +cargo-check: + cargo check --workspace + +alias cc := cargo-check + # Lint with Clippy [group('checks')] lint: @@ -94,7 +101,7 @@ alias fc := format-check # Run tests [group('checks')] -test: build +test: cargo test alias t := test From 9b5903802654bc14b7f5bd93381e343d79cf563e Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 13 Dec 2025 23:08:27 -0300 Subject: [PATCH 2/2] Make main function control flow more explicit --- src/main.rs | 61 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/src/main.rs b/src/main.rs index e47ffa1..edeb0c7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +use std::{backtrace, env, io, panic, sync, time}; + use axum::{routing::get, Router}; use formats::Format; @@ -7,12 +9,16 @@ mod types; mod handlers; mod dev; -static ONSET: std::sync::LazyLock = - std::sync::LazyLock::new(std::time::Instant::now); +static ONSET: sync::LazyLock = + sync::LazyLock::new(time::Instant::now); #[tokio::main] -async fn main() { - std::panic::set_hook(Box::new(|info| { +async fn main() -> io::Result<()> { + let args: Vec = env::args().collect(); + let default_address = "0.0.0.0:0".to_string(); + let address: &String = args.get(1).unwrap_or(&default_address); + + panic::set_hook(Box::new(|info| { let payload = info .payload_as_str() .unwrap_or("No string payload. Is edition > 2021?"); @@ -24,8 +30,8 @@ async fn main() { eprintln!(" P! [{:?}] {location}: {payload}", ONSET.elapsed()); - let trace = std::backtrace::Backtrace::capture(); - if trace.status() == std::backtrace::BacktraceStatus::Captured { + let trace = backtrace::Backtrace::capture(); + if trace.status() == backtrace::BacktraceStatus::Captured { eprintln!("\n Stack trace:\n{trace:#?}"); } })); @@ -66,21 +72,30 @@ async fn main() { ) .fallback(handlers::error::not_found); - if let Ok(listener) = tokio::net::TcpListener::bind("0.0.0.0:3000") - .await - .or(Err("Failed to instantiate Tokio listener")) - { - match axum::serve(listener, app).await { - Ok(()) => (), - Err(e) => { - dev::log( - &main, - &format!( - "Failed to serve application with axum::serve: {e:#?}" - ), - ); - std::process::exit(1); - }, - } - } + let listener = + tokio::net::TcpListener::bind(address).await.map_err(|e| { + dev::log( + &main, + &format!("Failed to create listener at {address}: {e:#?}"), + ); + e + })?; + + dev::log( + &main, + &format!( + "Listening on {}", + listener + .local_addr() + .map(|s| s.to_string()) + .unwrap_or("".to_string()) + ), + ); + + axum::serve(listener, app).await.map_err(|e| { + dev::log(&main, &format!("Failed to serve application: {e:#?}")); + io::Error::other(e) + })?; + + Ok(()) }