Commit Graph
104 Commits
Author SHA1 Message Date
vicrodh 25f9a15f90 i18n: register dynamic msgid literals via mark() and fix double-translation
Adds qbz_i18n::mark() (identity, extraction-only) and applies it at the
definition sites of literals later translated through t(variable):
release-type classifier, discover section labels, artist release-section
titles + month names, label jump tabs, and audio settings dropdown tables.
Fixes the discover_prefs double-t() (label_for now returns the marked
literal, translated once at the consumer).

cc
2026-06-23 21:31:42 -06:00
vicrodh 7142435211 i18n: honor LC_ALL precedence in resolve_auto
POSIX locale precedence is LC_ALL > LC_MESSAGES > LANG. resolve_auto
previously only checked LC_MESSAGES and LANG; add LC_ALL as the
highest-priority env var, skipping it when empty. Extend the
resolve_auto test (env-mutation serialized via the existing Mutex).

cc
2026-06-23 13:49:10 -06:00
vicrodh 57244ac0c1 feat(qbz-i18n): gettext .po catalog, plural rules, and t/tn/t_args/tf API
Implement the frontend-agnostic translation layer test-first:

- plural.rs: PluralRule parsing nplurals + the two expressions our
  locales use ((n != 1), (n > 1)); index(n) selects the form, with a
  safe English default for anything unrecognized.
- po.rs: Catalog::parse handles the header entry, msgid/msgid_plural/
  msgstr/msgstr[N], multi-line continuations, and \n \t \" \\
  escapes; empty msgstr means no translation (get returns None so
  callers fall back to English). Reads Plural-Forms from the header.
- lib.rs: 5 catalogs embedded via include_str! and lazily parsed
  (OnceLock); AtomicU8 language state; set_language/current_language/
  resolve_auto (LC_MESSAGES then LANG -> 2-letter prefix); t/tn/t_args/
  tf with left-to-right {} substitution and English fallback.

17 unit tests, all green via cargo test -p qbz-i18n. Content tests use
inline fixtures since the bundled .po files are header-only for now.

cc
2026-06-23 13:45:58 -06:00
vicrodh f92c95ee21 build(qbz-i18n): scaffold pure-Rust i18n crate
Add new no-dependency qbz-i18n crate to the workspace members.
Frontend-agnostic translation catalog per ADR-006 (reusable by
Slint/TUI/headless; no slint or tauri deps).

cc
2026-06-23 13:45:29 -06:00