use std::sync::OnceLock;
pub use vla_lang::messages::{Catalogue, Refusal};
const CATALOGUE_TEXT: &str = include_str!("../data/messages.vla");
fn own() -> &'static Catalogue {
static CATALOGUE: OnceLock<Catalogue> = OnceLock::new();
CATALOGUE.get_or_init(|| Catalogue::parse(CATALOGUE_TEXT))
}
pub fn count() -> usize {
vla_lang::messages::count() + own().count()
}
pub fn template(id: &str) -> Option<&'static str> {
own()
.template(id)
.or_else(|| vla_lang::messages::template(id))
}
pub fn ids() -> Vec<&'static str> {
let mut all = vla_lang::messages::ids();
all.extend(own().ids());
all
}
pub fn raise(id: &str, slots: &[(&str, &str)]) -> Refusal {
own()
.raise(id, slots)
.or_else(|| vla_lang::messages::catalogue().raise(id, slots))
.unwrap_or_else(|| vla_lang::messages::unknown(id))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_catalogue_is_read_whole() {
assert!(count() >= 574, "{} entries read", count());
assert_eq!(ids()[0], "vla-source-not-found");
assert_eq!(
template("vla-unbalanced-parens").unwrap(),
"unbalanced parentheses: missing ')'{loc}"
);
assert!(template("english-test-failed")
.unwrap()
.contains("test FAILED\n sentence: {sentence}"));
let r = raise(
"vla-interpreter-only-handler",
&[("name", "on:sheet-change")],
);
assert_eq!(r.number, -2147221504 + 7001);
assert_eq!(r.source, "VLA");
let language = vla_lang::messages::ids();
for id in own().ids() {
assert!(!language.contains(&id), "{id} is in both halves");
let family = id.split('-').next().unwrap();
assert!(
!["vla", "interp", "lint", "view", "calc", "grid"].contains(&family),
"{id} belongs to the language's half"
);
}
}
#[test]
fn raise_fills_slots_as_raisemsg_does() {
let r = raise("vla-form-missing-element", &[("n", "3")]);
assert_eq!(r.id, "vla-form-missing-element");
assert_eq!(r.number, 5);
assert_eq!(r.source, "VLA");
assert_eq!(r.text, "form is missing required element 3");
let r = raise("vla-unbalanced-parens", &[("loc", "")]);
assert_eq!(r.text, "unbalanced parentheses: missing ')'");
let r = raise("build-output-exists", &[("path", "x.xlsx")]);
assert_eq!(r.source, "VLA-Build");
assert!(r.text.contains("x.xlsx"), "{}", r.text);
}
#[test]
fn the_two_internal_errors_are_refusals_too() {
let r = raise("no-such-id", &[]);
assert_eq!(r.number, 5);
assert_eq!(r.source, "VLA-Messages");
assert_eq!(r.text, "RaiseMsg: unknown message id 'no-such-id'");
let r = raise("vla-form-missing-element", &[]);
assert_eq!(r.text, "RaiseMsg: no value supplied for slot '{n}'");
let r = raise("english-test-failed", &[]);
assert!(r.text.starts_with("RaiseMsg: no value supplied for slot"));
}
}