The dominant risk in sunface/rust-course is structural debt, not active churn: the two highest-risk functions — watch and main in assets/rustlings-zh/src/main.rs — have sat untouched for 1,158 days while carrying cyclomatic complexity scores of 22 and 23 respectively. rust-course is a comprehensive Rust learning resource with 167 analyzed functions, of which 3 score in the top risk band and all 14 structurally complex functions have zero recent activity. No functions are both highly complex and actively changing right now, which means the immediate concern is not live regression risk but the blast radius that awaits the next developer who needs to modify these entry points.
The table below ranks functions by activity-weighted risk — a score that multiplies structural complexity by recent commit frequency. A function that is both hard to understand (high cyclomatic complexity) and actively changing is a higher priority than one that is complex but untouched. CC = cyclomatic complexity (independent execution paths); ND = max nesting depth; FO = fan-out (distinct callees).
Top 5 Hotspots
| Function | File | Risk | CC | ND | FO |
|---|---|---|---|---|---|
watch | assets/rustlings-zh/src/main.rs | 14.9 | 22 | 5 | 10 |
main | assets/rustlings-zh/src/main.rs | 10.3 | 23 | 2 | 9 |
q | assets/bigPicture.js | 9.4 | 12 | 3 | 7 |
state | assets/rustlings-zh/src/exercise.rs | 8.4 | 5 | 1 | 5 |
all_exercises_require_confirmation | assets/rustlings-zh/tests/integration_tests.rs | 7.8 | 4 | 1 | 3 |
Codemod / Tooling Files in Results
Both top-ranked functions — watch and main — are located under assets/rustlings-zh/src/main.rs, which is a vendored or bundled copy of the rustlings exercise runner adapted for Chinese learners rather than first-party application logic. Because this is embedded tooling rather than the course content itself, teams may reasonably choose to exclude it from routine hotspot tracking. To suppress these results, add the following to .hotspotsrc.json: { "exclude": ["assets/rustlings-zh/"] }. That said, if the project maintains and ships this tooling, the structural debt findings remain valid and actionable.
Hotspot Analysis
watch — assets/rustlings-zh/src/main.rs
Based on its name and location in the rustlings-zh exercise runner, watch almost certainly implements the file-watching event loop that monitors exercise files for changes and re-runs verifications — the kind of function that branches on file events, exercise states, and user input simultaneously. Its cyclomatic complexity of 22 means there are 22 independent execution paths through it, each a required test case; a max nesting depth of 5 confirms that some of those paths involve deeply nested conditionals that are hard to reason about in isolation. With a fan-out of 10 and three exit-heavy paths, this function carries significant structural debt and hasn’t been touched in 1,158 days — high blast radius when next changed.
Recommendation: Add characterization tests that cover the observable exit behaviors before touching this function, then extract the distinct responsibilities (event detection, state transitions, user feedback) into smaller focused functions to bring CC below 10.
main — assets/rustlings-zh/src/main.rs
As the top-level entry point for the rustlings-zh CLI, main likely handles argument parsing, subcommand dispatch, and initialization — a classic long-function accumulation point. Its cyclomatic complexity of 23 is the highest in the dataset, meaning there are at least 23 paths through the startup logic alone; the long_function and stale_complex patterns both flagged here suggest this function has grown to absorb responsibilities over time and has not been refactored in 1,158 days. Fan-out of 9 means changes here reach broadly into the codebase, compounding the blast radius.
Recommendation: Apply extract-method refactoring to separate argument parsing, subcommand routing, and initialization into distinct functions; the goal is to reduce CC to under 10 per extracted unit, making each independently testable.
Patterns Found
Antipatterns detected across the top functions in this snapshot:
| Pattern | Occurrences |
|---|---|
exit_heavy | 3 |
complex_branching | 1 |
deeply_nested | 1 |
long_function | 1 |
stale_complex | 1 |
These labels belong to two tiers — Tier 1 (structural): complex_branching, deeply_nested, exit_heavy, long_function, god_function. Tier 2 (relational/temporal): hub_function, cyclic_hub, middle_man, neighbor_risk, stale_complex, churn_magnet, shotgun_target, volatile_god.
Key Takeaways
- Both critical-band functions live in assets/rustlings-zh/src/main.rs and have been untouched for 1,158 days — before any new development push on this tooling, add characterization tests to document current behavior and reduce blast-radius risk.
- The
mainfunction’s cyclomatic complexity of 23 combined with the long_function and stale_complex patterns is a strong signal to apply extract-method refactoring: break subcommand dispatch, argument parsing, and initialization into separate functions each with CC under 10. - The
watchfunction’s three exit-heavy paths and nesting depth of 5 mean test coverage is the critical gap — enumerate and test each exit condition explicitly before any structural changes to avoid silent regressions.
Reproduce This Analysis
git clone https://github.com/sunface/rust-course
cd rust-course
git checkout b89a0a41a70be13df49cc94cd739b97084af3f00
hotspots analyze . --mode snapshot --explain-patterns --force
To run the same analysis on your own codebase, run hotspots analyze . --mode snapshot in any local git repo — no configuration required.
Hotspots highlights structural and activity risk — not “bad code.” Findings are a prioritization aid, not a bug predictor. Editorial policy →