The codebase has grown significantly through v0.3–v0.8 and several files have accumulated multiple responsibilities. I think some of the functionality from files (specifically App.rs which is over 1k lines) should be removed and thoughtfully placed in a core section to make the code more reusable and readable for maintainability.
src/
├── main.rs Event loop only (slim)
├── core/
│ ├── mod.rs
│ ├── app.rs App struct, construction, core methods
│ ├── types.rs InputMode, ActivePanel, Overlay, QueryKind, NowPlaying, SongLogEntry
│ ├── radio.rs FetchResult, fetch_blended_by_tag/name, fetch_more, filter_spam
│ └── perf.rs PerfStats, FrameTiming, PerfSummary
├── audio/
│ ├── mod.rs
│ ├── player.rs (unchanged)
│ ├── pipe.rs FIFO reader + PCM pipeline only
│ ├── fft.rs fft_in_place, compute_band_edges, group_into_bands, compute_band_energies
│ ├── seqlock.rs Generic SeqLock<T> (reusable)
│ └── visualizer.rs (unchanged)
├── input/
│ ├── mod.rs
│ └── handler.rs Keybinding dispatch extracted from main.rs
├── storage/ (unchanged)
└── ui/ (unchanged)
The codebase has grown significantly through v0.3–v0.8 and several files have accumulated multiple responsibilities. I think some of the functionality from files (specifically
App.rswhich is over 1k lines) should be removed and thoughtfully placed in a core section to make the code more reusable and readable for maintainability.Current pain points I can see
app.rs(1068 lines): holds the App struct, all enums, PerfStats/FrameTiming (~100 lines), three async RadioBrowser fetch functions and FetchResult (~180 lines), NowPlaying, SongLogEntry, and every App method. Too many concerns in one file.main.rs(455 lines): the event loop is ~350 lines of inline keybinding dispatch across overlays (theme picker, genre picker, settings, normal mode). Makes it rough to navigate.pipe.rs(570 lines): mixes a reusable generic (SeqLock), the FFT implementation, and the FIFO reader/PCM pipeline.core/module: domain types, perf tracking, and radio API logic live alongside UI state inapp.rs.The Proposed Structure
Breakdown
Extract
core/module fromapp.rscore/types.rs: moveInputMode,ActivePanel,Overlay,QueryKind,NowPlaying,SongLogEntrycore/radio.rs: moveFetchResult,fetch_blended_by_tag,fetch_blended_by_name,fetch_more,filter_spamcore/perf.rs: movePerfStats,FrameTiming,PerfSummaryand their implscore/app.rs: what remains: App struct and its methodsSplit
pipe.rsaudio/seqlock.rs: The genericSeqLock<T: Copy>with its safety docsaudio/fft.rs:fft_in_place,compute_band_edges,group_into_bands,compute_band_energies, and the test suiteaudio/pipe.rs:AudioAnalysis,SharedAnalysis, FIFO creation,spawn_reader,reader_loopExtract input handling from
main.rsinput/handler.rs: keybinding dispatch for each overlay and normal modemain.rs: event loop skeleton, terminal setup/teardown, tick timing