Release/v0.6.0#20
Merged
Merged
Conversation
Extract verbose, print, log and import_helpers into dedicated files. Update mod.rs to declare all submodules and re-export symbols explicitly (no more blanket glob re-exports inside utils). - utils/verbose.rs: VERBOSE static, set_verbose(), is_verbose() - utils/print.rs: icons module, print_ok/err/warn/info() - utils/log.rs: now_str(), write_log() - utils/import_helpers.rs: open_import_file(), handle_import_result() - utils/mod.rs: aggregator with explicit pub use only All callers unchanged; public API surface identical.
…mands enum - Create cli/fields.rs: EDITABLE_FIELDS is a CLI concern, not a generic utility - Update cli/mod.rs: declare fields submodule, remove dead Commands enum (only 3 of 8 commands were represented, never used by dispatch) - Update cli/args.rs, commands/edit_book.rs: import from crate::cli::fields - Refactor commands/config.rs: replace Commands enum parameter with explicit bool args (init, print, edit, editor) - cleaner API, no enum dependency - Update cli/dispatch.rs: call handle_config with direct bool params - Remove utils/fields.rs (deleted)
- models/book.rs: pure data model only (Book struct + from_row + Serde)
Remove tabled/i18n dependencies
- models/display.rs: new file with BookFull, BookShort and their Tabled
implementations (presentation concern, depends on i18n)
- models/mod.rs: declare display submodule, re-export Book/BookFull/BookShort
- commands/list.rs: update imports to explicit paths
(models::book::Book, models::display::{BookFull, BookShort})
- load_db.rs → connection.rs (clearer name for DB connection management) - migrate_db.rs → migrations.rs (clearer name for migration logic) - search.rs absorbed into books.rs: search_books() belongs with book operations - db/mod.rs: update pub mod/use to new names, expose search_books from books - main.rs: update direct reference db::migrate_db → db::migrations - Old files removed: load_db.rs, migrate_db.rs, search.rs
… mapping - Remove commands/add.rs: 18-line wrapper that just called handle_add_book(). dispatch.rs already invokes handle_add_book() directly (dead code) - commands/mod.rs: drop pub mod/use for removed add module - commands/list.rs: simplify row_to_book() to delegate to Book::from_row() and only apply ISBN hyphen formatting on top; remove unused chrono imports - commands/db.rs: replace inline create_schema() duplicate (tripled) with a call to db::connection::ensure_schema() - single source of truth for schema
…all internal imports
- lib.rs: remove pub use commands/config/db/i18n/models/utils::*
Replace with explicit re-exports (AppConfig, load_or_init, init_db,
start_db, Book, load_language, tr, tr_s, tr_with) - clear public API
- main.rs: remove duplicate run_migrations() call (already run in start_db)
- All internal modules now use explicit crate paths instead of crate root shortcuts:
* utils/isbn.rs: crate::tr_with -> crate::i18n::tr_with
* utils/table.rs: crate::{print_warn,tr} -> crate::utils/i18n explicit paths
* commands/add_book.rs: normalize_isbn, is_verbose, print_* via explicit paths
* commands/del_book.rs: print_*, write_log, tr_with via explicit paths
* commands/edit_book.rs: lang_code_to_name, print_*, tr/tr_with explicit
* commands/import.rs: Book from models, print_err from utils
* commands/search_book.rs: print_warn from utils
* commands/list.rs: normalize_isbn from utils::isbn
* commands/db.rs: AppConfig, tr/tr_with, print_* all explicit
* cli/dispatch.rs: AppConfig, commands, i18n all explicit
- tests/isbn_tests.rs: update import path to librius::utils::isbn
- utils/isbn.rs doctest: update example path to utils::isbn::normalize_isbn
Documents the full src/ tree after the 6-phase refactor: - one-line description per file - key design rules table - explicit public API surface from lib.rs
CHANGELOG.md: - Add [0.6.0] entry documenting all 6 refactor phases: utils/ split, cli/fields.rs, models/display.rs, db renames, commands cleanup, lib.rs explicit API, main.rs dedup README.md: - Replace 'New in v0.5.1' section with 'New in v0.6.0' refactor summary - Update Project structure tree (connection.rs, migrations.rs, display.rs, utils submodules, etc.) - Update Development notes: correct public API examples, remove stale glob-import example, add single-responsibility design rules - Remove already-implemented items from Future roadmap STRUCTURE.md: - Amend table formatting for GitHub Markdown rendering Cargo.toml: - Bump version 0.5.1 -> 0.6.0 Cargo.lock: - Regenerated after version bump
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 81b573a77e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Closes #21 SQLite CURRENT_TIMESTAMP writes 'YYYY-MM-DD HH:MM:SS' (no timezone), but rusqlite's built-in DateTime<Utc> deserialization expects RFC3339. This caused a row conversion error on any database populated via the default schema, making 'librius list' fail instead of rendering results. Fix: read added_at as Option<String> and parse with a multi-format fallback function (parse_sqlite_datetime), gracefully degrading to None if no format matches — identical behaviour to the pre-refactor mapper. Formats handled: 1. RFC3339 with timezone (2025-10-13T21:32:07+02:00) 2. SQLite CURRENT_TIMESTAMP (2025-10-13 21:32:07) 3. SQLite CURRENT_TIMESTAMP with sub-seconds (2025-10-13 21:32:07.123) Tests added (tests/db_tests.rs): - test_from_row_parses_sqlite_current_timestamp (regression case) - test_from_row_parses_rfc3339_timestamp
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.
🧱 Full internal refactor — v0.6.0
Summary
Complete restructuring of the source tree into single-responsibility modules.
No user-facing behaviour changes — all commands, flags and output are identical to v0.5.1.
Motivation
The codebase had grown organically with several design issues:
utils/mod.rswas a 155-line monolith mixing verbose flags, print helpers, log and import utilitiesmodels/book.rsmixed pure data withtabled/i18npresentation logiccommands/add.rswas an 18-line dead wrapper overhandle_add_book()create_schema()was duplicated in three separate fileslib.rsused blanketpub use module::*glob re-exports, making the public API opaquerun_migrations()was called twice at startupCommandsenum incli/mod.rscovered only 3 of 8 commands and was never used by dispatchChanges by phase
Phase 1 —
utils/monolith → focused submodulesutils/verbose.rsVERBOSEstatic,set_verbose(),is_verbose()utils/print.rsiconsmodule +print_ok/err/warn/info()utils/log.rsnow_str(),write_log()utils/import_helpers.rsopen_import_file(),handle_import_result()utils/mod.rspub useonlyPhase 2 — CLI concerns separated
cli/fields.rs—EDITABLE_FIELDSmoved fromutils/(it is a CLI concern, not a generic utility)cli/mod.rs— deadCommandsenum removedcommands/config.rs—handle_config(&Commands)→handle_config(init, print, edit, editor)(explicit params, no enum dependency)Phase 3 — Data model separated from presentation
models/book.rs— pureBookstruct +from_row()+ Serde; notabled/i18ndependencymodels/display.rs(new) —BookFull,BookShortwithTabledimplementations and localised column headersPhase 4 —
db/module consolidationdb/load_db.rsdb/connection.rsdb/migrate_db.rsdb/migrations.rsdb/search.rsdb/books.rssearch_books()belongs with book operationsPhase 5 —
commands/dead code removalcommands/add.rsdeleted — dispatch already callshandle_add_book()directly (dead wrapper)commands/list.rs—row_to_book()simplified to delegate toBook::from_row()+ ISBN hyphen formatting onlycommands/db.rs— localcreate_schema()removed; replaced bydb::connection::ensure_schema()(single source of truth)Phase 6 —
lib.rsexplicit public APIRemoved all glob
pub use module::*re-exports. Replaced with a minimal, explicit surface:All internal modules updated to use full
crate::x::yimport paths.main.rs: removed duplicaterun_migrations()call (already run insidestart_db()).Documentation
STRUCTURE.mdadded — full map of every source file with single-responsibility description, design rules table and explicit public API surfaceCHANGELOG.md—[0.6.0]entry addedREADME.md— "New in v0.6.0" section, updated project structure tree, corrected development notes and public API examplesCargo.toml— version bumped0.5.1→0.6.0Testing
All existing integration tests pass unchanged.
Commits