Files
rdbms-playground/src/friendly/mod.rs
T
claude@clouddev1 050b36391e feat(hint): H2 Phase A — hint command + F1 keybinding skeleton (ADR-0053)
The mechanism for the contextual hint, with tier-2 fallback; the
tier-3 corpus lands in later phases.

- new CommandNode `hint_id` field (all None for now)
- AppCommand::Hint + HINT grammar node + REGISTRY + dispatch
- F1 read-only overlay in handle_key (buffer/cursor/memo untouched)
- note_hint* renderers; hint_id_for_input_in_mode (shared selection
  helper refactored out of usage_keys_for_input_in_mode)
- last_error_hint_key + friendly::error_hint_class classifier
- catalogue: help.app.hint / parse.usage.hint / hint.getting_started
- +12 tests; 2483 pass / 1 ignored, clippy clean
2026-06-15 10:36:51 +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::{error_hint_class, FailureContext, Operation, TranslateContext, Verbosity};
// `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) ),*],
)
}};
}