# MODERNIZE.md A list of dependency reductions and idiom cleanups for the current codebase. Nothing here is applied yet. Review it, then decide which items to do and when (most fit in ROADMAP Phase 0). Status notes: - Every "unused" claim below was verified with a grep: 0 references in `src/`. - Toolchain decision: stay on nightly (channel = "nightly"). The stable-Rust item is listed for awareness only. - The item 3.2 note about the double `foundry.json` load stays true. ## 1. Delete unused dependencies Remove these from `Cargo.toml`. None are referenced in `src/`: | dependency | note | |---|---| | `itertools` | no usage | | `seq-macro` | no usage | | `leptos-use` | no usage | | `dotenvy` | no usage. Never wired into `main` | | `pretty_env_logger` | no usage. Logging uses the `log` macros | | `thiserror` | no usage. No error types yet | | `http` | optional, enabled by no feature. Code uses `actix_web::http::StatusCode` | | `console_log` | no usage. Only `console_error_panic_hook` is called | | `anyhow` | only `#[macro_use] extern crate anyhow` and prelude aliases. The `Result` alias and `bail!`/`anyhow!` are used nowhere | | `js-sys` | no direct usage. Resolves transitively. Keep the `wasm-bindgen =0.2.126` pin: `hydrate()` uses `#[wasm_bindgen(...)]` | ## 2. Replace crates with std or small local code 1. **`lazy_static` → `std::sync::LazyLock`** (stable since 1.80). Rewrite `src/statics/mod.rs`: ```rust use std::sync::LazyLock; static ITEMS_REFS: LazyLock = LazyLock::new(|| { let mut map = HashMap::with_capacity(5_000); utils::read_items(include_str!("../../data/items.json"), &mut map); // base.json, foundry.json (twice — duplication bug), magic.json info!("Loaded {} items", map.len()); ItemReferenceMap(map) }); static ITEMS_NAMES: LazyLock> = LazyLock::new(|| ITEMS_REFS.0.keys().map(String::as_str).collect()); ``` Notes: - `include_str!` needs literal paths, so keep the five explicit calls. - The current `HashMap::from_iter(map.into_iter())` roundtrip is a no-op. Wrap the map directly. - `ITEMS_NAMES` changes from `Vec<&'static String>` to `Vec<&'static str>`. The matcher accepts both. 2. **`num-format` → local `group_thousands` helper** in `src/utils/mod.rs`. It exists only for the `ToFormattedString` bound in `Numput`. Drop the bound and render `f.to_string()` grouped. About 6 lines. 3. **`num-traits` → local saturating trait** in `src/components/numput.rs`. It exists only for the `SaturatingAdd`/`SaturatingSub` bounds on `Numput`. Define a small local trait and impl it for `u8`, `u16`, `u32`, `u64`, `usize`. `Numput` keeps its generics. 4. **`serde` (direct) → remove now, re-add in ROADMAP phase 1.** No derives exist today; `serde_json::Value` works without naming `serde` in `Cargo.toml`. Phase 1 (persistence) re-adds `serde = { version = "1", features = ["derive"] }`. Result: `[dependencies]` drops from 27 entries to about 13. ## 3. Idiomatic cleanups (no dependency changes) 1. Delete `#![feature(type_alias_impl_trait)]` in `src/lib.rs:6`. It is unused and warns. 2. Stay on nightly. The code uses only stable features (let-chains, let-else, edition 2024, `LazyLock`). If the toolchain is ever revisited: drop the `nightly` features from `leptos`/`leptos_router`, install stable, and run the three checks. The original build breakage was a nightly regression (`min_adt_const_params` re-gating in nightly 1.99); stable does not have that class of failure. 3. Prelude (`src/prelude.rs`): - Remove the blanket `#![allow(unused_imports)]` and `#![allow(dead_code)]`. They hide real warnings. - Remove the single-letter `log` aliases (`warn as w, log as l, info as i, ...`). They are unused. - Remove the `anyhow` re-exports and typealiases. - Replace legacy `#[macro_use] extern crate log;` in `src/lib.rs` with `use log::{info, error};` at the two call sites. 4. `read_items` (`src/utils/mod.rs`): use the `Entry` API instead of `contains_key` → `get_mut().unwrap()`. Removes the unwrap and the double lookup. 5. Mock data (`src/entities/mock.rs`): `HashSet::from_iter(vec![...])` → `HashSet::from([...])`. The date `unwrap`s are fine: the data is static. 6. Minor: `adjust_checked` drops `-> ()`; `numput.rs` drops the unused `leptos::{ logging, ... }` import. ## 4. Opinionated (do only on request) 1. `chrono` → `jiff`. Nicer API, actively maintained. Not worth the churn for this model. If kept: `chrono`'s `serde` feature is unused today — trim it now, re-add in phase 1. 2. `cargo fmt` normalization. The repo uses `fn foo (` spacing; it may be deliberate. Ask before running. 3. Clippy pass over the result. ## Verification After applying items 1-3, run: ``` cargo check --no-default-features --features hydrate --lib cargo check --no-default-features --features ssr --bin aex cargo check --target wasm32-unknown-unknown --no-default-features --features hydrate --lib ```