Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,45 @@

All notable changes to this project will be documented in this file.

## [0.3.0] - 2025-10-16

### Added

- Introduced the `tabled` crate (`v0.20.0`) for tabular output.
- New `--short` flag for `librius list` showing only key columns (ID, Title, Author, Editor, Year).
- New utility `build_table()` in `utils/table.rs` to render tables with consistent style and alignment.
- CLI option `--delimiter` / `-d` for `import` command.
Allows specifying a custom CSV field separator (default: `,`).

### Changed

- Refactored `list` command to use `BookFull` and `BookShort` wrappers implementing `Tabled`.
- Standardized module structure across the project:
- Each main directory (`commands`, `db`, `config`, `i18n`, `models`, `utils`) now includes a `mod.rs`.
- Unified import/export logic in `lib.rs` for cleaner module access.
- Improved code readability, organization, and adherence to Rust idioms.

### Refactored

- Extracted duplicated import logic into reusable helper functions:
- `utils::open_import_file()` now handles file opening with localized error reporting.
- `utils::handle_import_result()` manages database insert results and counters.
- Unified behavior between `handle_import_csv()` and `handle_import_json()`.
- Simplified error handling and improved localization consistency across import operations.
- Reduced code duplication and improved maintainability throughout the import module.

### Fixed

- **CSV/JSON import deserialization error**:
The `id` field in the `Book` struct is now optional (`Option<i32>`),
preventing missing-field errors during import when the ID column is not present.

### Removed

- Legacy manual `println!` formatting for book listings.

---

## [0.2.5] - 2025-10-15

### Added
Expand Down
81 changes: 80 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "librius"
version = "0.2.5"
version = "0.3.0"
edition = "2024"
authors = ["Alessandro Maestri <umpire274@github.com>"]
authors = ["Alessandro Maestri <umpire274@gmail.com>"]
description = "A personal library manager CLI written in Rust."
license = "MIT"
readme = "README.md"
Expand Down Expand Up @@ -35,6 +35,7 @@ tar = { version = "0.4.44", optional = true }
dirs = "6.0.0"
umya-spreadsheet = "2.3.3"
csv = "1.3.1"
tabled = "0.20.0"

[target.'cfg(windows)'.dependencies]
zip = "6.0.0"
Expand Down
144 changes: 111 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,28 @@ and import/export support.

---

## ✨ New in v0.2.5

- **Backup command** (`librius backup`)
- Creates plain `.sqlite` backups in the `backups/` directory
- Optional `--compress` flag for compressed backups
- `.zip` format on Windows
- `.tar.gz` format on macOS and Linux
- Localized help and messages via i18n (English and Italian)
- Timestamp-based file naming for safe sequential backups

- **Export command** (`librius export`)
- Added support for exporting library data in multiple formats:
- `--csv` (default): plain text export with semicolon delimiter
- `--json`: structured JSON array output
- `--xlsx`: formatted Excel file using umya-spreadsheet
- Localized CLI help and status messages (English/Italian)
- Automatic export directory and timestamped filenames
- Uses `dirs` crate for cross-platform export path handling

- **Import command** (`librius import`)
- Supports importing book data from external sources
- Available formats:
- `--csv` (default): semicolon-delimited CSV
- `--json`: JSON array of objects
- Unified parsing via `serde` and shared `BookRecord` struct
- Duplicate detection through unique index on `isbn`
- Uses `INSERT OR IGNORE` for idempotent imports (no duplication)
- Verbose mode logs skipped records (e.g., “Skipped duplicate ISBN: …”)
- Non-blocking import completion logging
## ✨ New in v0.3.0

**🆕 Modern tabular output**

- Replaced the old `println!` list format with the [`tabled`](https://crates.io/crates/tabled) crate.
- Tables now feature aligned, styled columns for improved readability.
- Added a `--short` flag for compact view (`ID`, `Title`, `Author`, `Editor`, `Year`).
- Added `--id` and `--details` options to view a single record:
- `--id <ID>` shows a specific book by its ID.
- `--details` displays all fields of the selected record in a vertical table.

**🧩 Modular architecture**

- Standardized all modules using the `mod.rs` structure.
- Each subsystem (`commands`, `models`, `utils`, `db`, `config`, `i18n`) now has a clean, isolated namespace.
- Simplified imports using `pub use` re-exports in `lib.rs`.

**🧱 Utility improvements**

- Added a reusable `build_table()` helper in `utils/table.rs` for consistent table rendering.
- Introduced a dynamic `build_vertical_table()` helper for full record details using `serde_json` + `tabled`.
- Implemented `BookFull` and `BookShort` structs implementing `Tabled` for both full and compact listings.

---

Expand Down Expand Up @@ -94,12 +87,36 @@ cargo install rtimelogger
| ✅ | **Import** | Import data from CSV or JSON files (duplicate-safe via ISBN) |
| ✅ | **Database migrations** | Automatic schema upgrades at startup |
| ✅ | **Logging system** | Records operations and migrations in log table |
| ✅ | **Verbose mode** | Optional `--verbose` flag for detailed debug output |
| ✅ | **Safe patch system** | Each migration is idempotent and logged for traceability |
| ✅ | **Multilanguage (i18n)** | Localized CLI (commands, help); embedded JSON; `--lang` + YAML `language` |
| 🚧 | **Add / Remove** | Add or delete books via CLI commands |
| 🚧 | **Search** | Search by title, author, or ISBN |
| 🚧 | **Export / Import** | Export and import data (JSON, CSV) |

---

## 💻 Usage

```bash
librius list # Full detailed list
librius list --short # Compact list (ID, Title, Author, Editor, Year)
```

---

## 🧱 Example output

```bash
$ librius list --short

📚 Personal Library
════════════════════════════════════════════════════════════════════════════════

┌────┬──────────────────────────────┬────────────────────┬──────────────┬──────┐
│ ID │ Title │ Author │ Editor │ Year │
├────┼──────────────────────────────┼────────────────────┼──────────────┼──────┤
│ 1 │ The Rust Programming Language│ Steve Klabnik │ No Starch │ 2018 │
│ 2 │ Clean Code │ Robert C. Martin │ Pearson │ 2008 │
└────┴──────────────────────────────┴────────────────────┴──────────────┴──────┘
```

---

Expand All @@ -122,7 +139,7 @@ Librius now supports a multilingual interface.
- All user-visible messages (print_info, print_err, etc.) are translated dynamically.
- Missing keys automatically fall back to their key name or English equivalent.

### Example usage
### Example Usage

```bash
# Default (English)
Expand Down Expand Up @@ -171,6 +188,51 @@ tr_with("db.path.open_existing", & [("path", & db_path)]);

---

## 🧱 Project structure

```
src/
├─ main.rs
├─ lib.rs
├─ cli.rs
├─ commands/
│ ├─ mod.rs
│ ├─ list.rs
│ ├─ backup.rs
│ ├─ config.rs
│ ├─ export.rs
│ └─ import.rs
├─ config/
│ ├─ mod.rs
│ ├─ load_config.rs
│ └─ migrate_config.rs
├─ db/
│ ├─ mod.rs
│ ├─ load_db.rs
│ └─ migrate_db.rs
├─ i18n/
│ ├─ mod.rs
│ ├─ loader.rs
│ └─ locales/
│ ├─ en.json
│ ├─ it.json
│ └─ README.md
├─ models/
│ ├─ mod.rs
│ └─ book.rs
└─ utils/
├─ mod.rs
└─ table.rs
```

---

## 🧾 Changelog reference

See [CHANGELOG.md](CHANGELOG.md) for a detailed list of changes and updates.
Expand Down Expand Up @@ -269,6 +331,22 @@ language: "en"

---

## 🧩 Development notes

Librius now follows a standard Rust modular structure:

- Each domain (commands, db, config, models, utils, i18n) exposes its API via mod.rs.
- Common utilities like build_table() are reused across commands for consistent output.
- The lib.rs re-exports all major modules for cleaner imports in main.rs.

### Example import

```rust
use librius::{build_cli, handle_list; tr};
```

---

## 📚 Documentation

The API and user-facing documentation for Librius is available on docs.rs:
Expand Down
Loading