refactor: split the four most-edited modules into directories - #57
Merged
Conversation
update.rs was the most-edited file in the project (24 commits in six months) and held all 70 match arms in one 1836-line function, so every feature landed in the same place and every diff read the same. mod.rs now keeps the dispatch table alone - one line per message, the whole protocol visible at a glance - and the bodies live next to their domain: store.rs install, update, uninstall, release notes, favorites github_auth.rs device-flow login and catalog fetching launcher.rs self-update: check, download, apply, relaunch preferences.rs settings panel and every user toggle keyboard.rs global key handling onboarding.rs first-launch welcome and tutorial Pure move: no behaviour change. Arm bodies became methods returning Task<Message>, so a `return` inside one still yields the same value from update(); the arms are distinct variants, so order was never significant. rustc's exhaustiveness check plus a clean clippy -D warnings prove the table still covers all 70 variants with no redundant arm.
main.rs was the second most-edited file (20 commits in six months) because it doubled as the crate root and the App shell: boot, view, subscription and theme all lived there, so every feature touching startup or the root layout landed in the entry point. main.rs is now 47 lines - the crate attribute, the module list and main(). The shell moved to app.rs unchanged; boot/title/view/subscription/theme became pub(crate) since main() now calls them across a module boundary, and ui/github_panel.rs now names crate::state::GitHubState directly instead of relying on a private import that happened to sit at the crate root.
i18n.rs held both locale tables in one 1523-line file, so adding a single string produced a diff straddling two languages ~350 lines apart. One file per locale now: fr.rs, en.rs, and a mod.rs that keeps the Locale type and the lookup. The key-set parity test still guards the pair - verified by breaking parity on purpose and watching it fail. github.rs mixed three concerns at 1432 lines: the HTTP client and its conditional-request cache, the wire types, and the catalog and release logic built on top. Split by layer into http/types/catalog/releases, with mod.rs re-exporting everything so no call site outside the module changed - the rest of the crate still names crate::github::X whatever file X now lives in. A handful of helpers that were private to the old single file (cached_get, GITHUB_API, build_client, the GithubRepo/Content/Readme wire structs) are now pub(crate), which is the visibility the split requires and nothing wider.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Organizes
src/by splitting the files that actually hurt, chosen from data rather than from size alone.Why these four
Size is the wrong metric on its own. Measured over six months:
ui/theme.rsupdate.rsui/settings.rsi18n.rsgithub.rsmain.rsui/theme.rsis the biggest file in the project and the least touched, because it is a palette table read by lookup rather than top to bottom; splitting it would be churn for nothing.main.rsis small but the second most-edited file, because it doubled as crate root andAppshell.settings.rsis one long view function that nobody fights with.What moved
update.rs→update/(the one that pays). All 70 match arms lived in one function.mod.rsnow holds the dispatch table alone, one line per message, so the whole protocol is visible at a glance, and the bodies sit next to their domain:store.rs(install/update/uninstall/release notes/favorites),github_auth.rs(device flow + catalog fetch),launcher.rs(self-update),preferences.rs(settings + toggles),keyboard.rs(global key handling, 141 lines of it),onboarding.rs(welcome + tutorial). 1836 lines → 820 + six focused files.main.rs→main.rs+app.rs. The crate root is now 46 lines: the crate attribute, the module list,main().boot/view/subscription/thememoved toapp.rsand becamepub(crate)sincemain()now calls them across a module boundary.i18n.rs→i18n/{mod,fr,en}.rs. Both locale tables shared one file, so adding a string produced a diff straddling two languages ~350 lines apart.github.rs→github/{mod,http,types,catalog,releases}.rs, split by layer.mod.rsre-exports everything, so no call site outside the module changed: the rest of the crate still namescrate::github::Xwhatever file X now lives in.Behaviour is unchanged, and here is why that is checkable
These are pure moves. Two specific hazards, both addressed:
returninside a moved match arm. An arm body became a method returningTask<Message>, soreturn Xyields the same value fromupdate()as before. Verified across all extracted methods.rustc's exhaustiveness check plus a cleanclippy --all-targets -D warnings(which would flag an unreachable pattern) prove the table still covers all 70 variants with no redundant arm.Visibility grew only where the split demands it:
github_tokenanddispatch_next_queued_updatetopub(super), and ingithub/a few helpers that were private to the old single file (cached_get,GITHUB_API,build_client, the three wire structs) topub(crate).Verification
clippy --all-targets -D warningsclean,fmtclean, cross-compiled for Windows with--all-targets.cargo buildof the binary, not justcheck.fr_and_en_have_identical_key_setsfail, then restoring.Blame
This is one squashed pure-move commit, so
git blamewill point here for ~2000 moved lines. A follow-up adds.git-blame-ignore-revswith this commit's SHA (which cannot be known before the squash), so blame keeps pointing at whatever change actually wrote each line.Left deliberately
ui/theme.rsandui/settings.rs, per the table above. Grouping the remaining root files (download.rs,scan.rs,persistence.rs,signing.rs,oauth.rs…) into domain directories is possible but is cosmetic churn: they are all under 700 lines and none is a hotspot.