use super::{Arguments, I18nError, Localizer};
use std::fmt;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct MessageKey<'a>(&'a str);
impl<'a> MessageKey<'a> {
#[must_use]
pub const fn new(value: &'a str) -> Self {
Self(value)
}
}
impl<'a> AsRef<str> for MessageKey<'a> {
fn as_ref(&self) -> &str {
self.0
}
}
impl fmt::Display for MessageKey<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.0)
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct AttrKey<'a>(&'a str);
impl<'a> AttrKey<'a> {
#[must_use]
pub const fn new(value: &'a str) -> Self {
Self(value)
}
}
impl<'a> AsRef<str> for AttrKey<'a> {
fn as_ref(&self) -> &str {
self.0
}
}
impl fmt::Display for AttrKey<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.0)
}
}
pub trait BundleLookup {
fn message(&self, key: MessageKey<'_>, args: &Arguments<'_>) -> Result<String, I18nError>;
fn attribute(
&self,
key: MessageKey<'_>,
attribute: AttrKey<'_>,
args: &Arguments<'_>,
) -> Result<String, I18nError>;
}
impl BundleLookup for Localizer {
fn message(&self, key: MessageKey<'_>, args: &Arguments<'_>) -> Result<String, I18nError> {
self.message_with_args(key.as_ref(), args)
}
fn attribute(
&self,
key: MessageKey<'_>,
attribute: AttrKey<'_>,
args: &Arguments<'_>,
) -> Result<String, I18nError> {
self.attribute_with_args(key.as_ref(), attribute.as_ref(), args)
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct DiagnosticMessageSet {
primary: String,
note: String,
help: String,
}
impl DiagnosticMessageSet {
#[must_use]
pub fn new(primary: String, note: String, help: String) -> Self {
Self {
primary,
note,
help,
}
}
#[must_use]
pub fn primary(&self) -> &str {
&self.primary
}
#[must_use]
pub fn note(&self) -> &str {
&self.note
}
#[must_use]
pub fn help(&self) -> &str {
&self.help
}
pub(crate) fn strip_isolating_marks(self) -> Self {
fn strip(mut text: String) -> String {
const ISOLATING_MARKS: [char; 2] = ['\u{2068}', '\u{2069}'];
text.retain(|ch| !ISOLATING_MARKS.contains(&ch));
text
}
Self {
primary: strip(self.primary),
note: strip(self.note),
help: strip(self.help),
}
}
}
const NOTE_ATTR: AttrKey<'static> = AttrKey::new("note");
const HELP_ATTR: AttrKey<'static> = AttrKey::new("help");
#[must_use = "Use the resolved localization messages when emitting diagnostics"]
pub fn resolve_message_set(
lookup: &impl BundleLookup,
key: MessageKey<'_>,
args: &Arguments<'_>,
) -> Result<DiagnosticMessageSet, I18nError> {
let primary = lookup.message(key, args)?;
let note = lookup.attribute(key, NOTE_ATTR, args)?;
let help = lookup.attribute(key, HELP_ATTR, args)?;
Ok(DiagnosticMessageSet::new(primary, note, help))
}