Files
rdbms-playground/src/friendly/mod.rs
T
claude@clouddev1 41b7e9a049 style: format the whole tree with cargo fmt (stock defaults, #35)
One-time, mechanical reformat — no functional changes. The tree was not
rustfmt-clean (~1800 hunks across ~100 files); this brings it to stock
`cargo fmt` defaults so a `cargo fmt --check` CI gate can follow.
Behaviour-preserving: 2509 pass / 0 fail / 1 ignored (unchanged baseline),
clippy clean. A .git-blame-ignore-revs entry follows so `git blame`
skips this commit.
2026-06-17 21:39:19 +00:00

64 lines
2.3 KiB
Rust

//! Friendly error layer and i18n message catalog (ADR-0019).
//!
//! Single chokepoint for user-visible message text. Engine
//! errors flow through `translate()` into a structured
//! [`FriendlyError`] payload that the renderer (in
//! `output_render`) composes into final output. Every other
//! user-visible string in the codebase migrates to this
//! catalog over time via the [`t!`] macro (ADR-0019 §9).
//!
//! ## Catalog
//!
//! The catalog lives in `strings/<locale>.yaml`, embedded at
//! compile time and parsed once on first access. Today the only
//! locale is `en-US`; runtime selection is deferred (ADR-0019
//! §8.2). Hierarchical YAML keys flatten to dot-paths
//! internally — `error.unique.insert.verbose` is the path the
//! `t!()` macro and the translator look up.
//!
//! ## The `t!()` macro
//!
//! ```ignore
//! use rdbms_playground::t;
//! let s = t!("error.unique.insert.verbose",
//! table = "Customers", column = "id");
//! ```
//!
//! Placeholder values implement `Display`. Format specifiers
//! (`{name:08.2}`, `{name:>10}`, …) are explicitly rejected at
//! substitution time — see ADR-0019 §8.4.
pub mod error;
pub mod format;
pub mod keys;
pub mod translate;
pub use error::{DiagnosticTable, FriendlyError};
pub use format::{Catalog, catalog};
pub use translate::{FailureContext, Operation, TranslateContext, Verbosity, error_hint_class};
// `translate::translate` and `format::translate` are different
// callables — the former is the structured DbError → FriendlyError
// classifier (the H1 entry point); the latter is the lower-level
// catalog lookup the `t!()` macro expands to. Re-export both
// under non-conflicting names.
pub use format::translate;
pub use translate::translate as translate_error;
/// Look up `key` in the catalog and substitute named arguments.
///
/// Panics if the key is missing, if the template has malformed
/// placeholders, or if the args don't supply every name the
/// template references. The catalog validator unit test (Step 7,
/// ADR-0019 §8.6) catches these at build time so they should
/// never fire at runtime.
#[macro_export]
macro_rules! t {
($key:literal $(, $name:ident = $value:expr)* $(,)?) => {{
$crate::friendly::translate(
$key,
&[$( (stringify!($name), &$value as &dyn ::std::fmt::Display) ),*],
)
}};
}