From c8c8b39a4e599fedc57297b2d5ca2b24c25c366a Mon Sep 17 00:00:00 2001 From: Tuntii <121901995+Tuntii@users.noreply.github.com> Date: Wed, 20 May 2026 02:54:05 +0000 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9A=A1=20Optimize=20list=5Fnotes=20to=20?= =?UTF-8?q?sort=20references=20before=20cloning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 02-crud-api/src/main.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/02-crud-api/src/main.rs b/02-crud-api/src/main.rs index 9e81fd1..55653fc 100644 --- a/02-crud-api/src/main.rs +++ b/02-crud-api/src/main.rs @@ -80,9 +80,9 @@ impl From for ApiError { #[summary("List all notes")] async fn list_notes(State(state): State) -> Json> { let notes = state.notes.read().await; - let mut items: Vec<_> = notes.values().cloned().collect(); + let mut items: Vec<_> = notes.values().collect(); items.sort_by_key(|n| n.id); - Json(items) + Json(items.into_iter().cloned().collect()) } #[post("/notes")] @@ -130,7 +130,9 @@ async fn update_note( Json(payload): Json, ) -> Result, ApiError> { let mut notes = state.notes.write().await; - let note = notes.get_mut(&id).ok_or_else(|| ApiError::not_found("Note not found"))?; + let note = notes + .get_mut(&id) + .ok_or_else(|| ApiError::not_found("Note not found"))?; if let Some(t) = payload.title { note.title = t; } From 83164c65201dd6fb5e739d229fd6cd9b10ae73e4 Mon Sep 17 00:00:00 2001 From: Tuntii <121901995+Tuntii@users.noreply.github.com> Date: Wed, 20 May 2026 03:02:15 +0000 Subject: [PATCH 2/3] Fix CI checks for missing directories and Node.js warning --- .github/workflows/ci.yml | 86 +++++++++------------------------------- 1 file changed, 19 insertions(+), 67 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 223854f..7264094 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,29 +1,28 @@ name: CI - on: push: branches: [main, master] pull_request: branches: [main, master] - env: CARGO_TERM_COLOR: always RUSTFLAGS: -Dwarnings - jobs: check: name: Check Examples runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable with: components: clippy, rustfmt - - name: Cache cargo registry uses: actions/cache@v4 + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true with: path: | ~/.cargo/registry @@ -32,39 +31,21 @@ jobs: key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }} restore-keys: | ${{ runner.os }}-cargo- - - name: Check all examples compile run: | echo "🔍 Checking all examples..." - EXAMPLES=( - "hello-world" - "crud-api" - "auth-api" - "cors-test" - "sqlx-crud" - "event-sourcing" - "graphql-api" - "mcp-server" - "microservices" - "microservices-advanced" - "middleware-chain" - "phase11-demo" - "rate-limit-demo" - "templates" - "toon-api" - "websocket" - "proof-of-concept" + "01-hello-world" + "02-crud-api" + "03-jwt-auth" + "04-sse-stream" ) - FAILED=() - for example in "${EXAMPLES[@]}"; do echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "📦 Checking: $example" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - if cd "$example" && cargo check --quiet 2>&1; then echo "✅ $example: OK" else @@ -73,12 +54,10 @@ jobs: fi cd .. done - echo "" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "📊 Summary" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - if [ ${#FAILED[@]} -eq 0 ]; then echo "✅ All ${#EXAMPLES[@]} examples passed!" exit 0 @@ -89,70 +68,46 @@ jobs: done exit 1 fi - - # Serverless Lambda uses different runtime, check separately - - name: Check serverless-lambda - run: | - echo "📦 Checking: serverless-lambda (AWS Lambda runtime)" - cd serverless-lambda && cargo check --quiet - echo "✅ serverless-lambda: OK" - fmt: name: Format Check runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable with: components: rustfmt - - name: Check formatting run: | echo "🎨 Checking code formatting..." - EXAMPLES=( - "hello-world" - "crud-api" - "auth-api" - "cors-test" - "sqlx-crud" - "event-sourcing" - "graphql-api" - "mcp-server" - "microservices" - "microservices-advanced" - "middleware-chain" - "phase11-demo" - "rate-limit-demo" - "serverless-lambda" - "templates" - "toon-api" - "websocket" - "proof-of-concept" + "01-hello-world" + "02-crud-api" + "03-jwt-auth" + "04-sse-stream" ) - for example in "${EXAMPLES[@]}"; do echo "Checking format: $example" cd "$example" && cargo fmt -- --check && cd .. done - echo "✅ All formatting checks passed!" - clippy: name: Clippy Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable with: components: clippy - - name: Cache cargo registry uses: actions/cache@v4 + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true with: path: | ~/.cargo/registry @@ -161,15 +116,12 @@ jobs: key: ${{ runner.os }}-cargo-clippy-${{ hashFiles('**/Cargo.toml') }} restore-keys: | ${{ runner.os }}-cargo-clippy- - - name: Run Clippy on examples run: | echo "🔎 Running Clippy lints..." - # Quick clippy check on a few key examples - for example in hello-world crud-api auth-api middleware-chain; do + for example in 01-hello-world 02-crud-api 03-jwt-auth 04-sse-stream ; do echo "Linting: $example" cd "$example" && cargo clippy --quiet -- -D warnings && cd .. done - echo "✅ Clippy checks passed!" From 2857eece0bb1a9609ec8b6f9ca409757ceb0a708 Mon Sep 17 00:00:00 2001 From: Tuntii <121901995+Tuntii@users.noreply.github.com> Date: Wed, 20 May 2026 03:06:24 +0000 Subject: [PATCH 3/3] Fix CI compilation and clippy errors --- 02-crud-api/src/main.rs | 1 + 03-jwt-auth/src/main.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/02-crud-api/src/main.rs b/02-crud-api/src/main.rs index 55653fc..d58c95a 100644 --- a/02-crud-api/src/main.rs +++ b/02-crud-api/src/main.rs @@ -58,6 +58,7 @@ struct UpdateNote { // Handler return types must use ApiError directly (it implements ResponseModifier). // NoteError is kept here to show the derive pattern; use ApiError in handlers. #[derive(ApiError)] +#[allow(dead_code)] enum NoteError { #[error(status = 404, code = "NOT_FOUND", message = "Note not found")] NotFound, diff --git a/03-jwt-auth/src/main.rs b/03-jwt-auth/src/main.rs index 5a1d632..f50901a 100644 --- a/03-jwt-auth/src/main.rs +++ b/03-jwt-auth/src/main.rs @@ -67,6 +67,7 @@ struct ProfileResponse { // NOTE: #[derive(ApiError)] generates IntoResponse for custom error enums. // Handler return types must use ApiError directly (it implements ResponseModifier). #[derive(ApiError)] +#[allow(dead_code)] enum AuthError { #[error(status = 401, code = "UNAUTHORIZED", message = "Invalid credentials")] InvalidCredentials, @@ -101,7 +102,7 @@ async fn login(Json(payload): Json) -> Result, exp: now_plus_secs(ttl), }; - let token = create_token(&claims, JWT_SECRET).map_err(|_| ApiError::unauthorized("Invalid credentials"))?;; + let token = create_token(&claims, JWT_SECRET).map_err(|_| ApiError::unauthorized("Invalid credentials"))?; Ok(Json(TokenResponse { token, expires_in: ttl,