#[cfg(feature = "native")]
use alloc::string::String;
#[cfg(feature = "compile")]
use alloc::vec::Vec;
#[cfg(feature = "native")]
use std::path::PathBuf;
#[cfg(feature = "compile")]
use mf2_model::{Diagnostic, ErrorKind};
#[cfg(feature = "compile")]
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum CompileError {
#[error("the message has {} syntax or data-model error(s)", .0.len())]
Invalid(Vec<Diagnostic>),
#[error("catalog writer: {0}")]
Write(#[from] mf2_catalog::WriteError),
#[error("catalog reader: {0}")]
Load(#[from] mf2_catalog::CatalogError),
#[error("locale data: {0}")]
LocaleData(#[from] mf2_locale_data::Error),
}
#[cfg(feature = "compile")]
impl CompileError {
pub fn kinds(&self) -> Vec<ErrorKind> {
match self {
CompileError::Invalid(d) => d.iter().map(|d| d.kind).collect(),
_ => Vec::new(),
}
}
}
#[cfg(all(
any(feature = "ssr", feature = "hydrate", feature = "csr"),
any(feature = "leptos", feature = "leptos-0-8")
))]
#[derive(Clone, PartialEq, Eq, Debug, thiserror::Error)]
#[non_exhaustive]
pub enum LoadError {
#[error("mf2: install() has not run")]
NotInstalled,
#[error("mf2: the catalog was compiled against a different manifest")]
ManifestMismatch,
#[error("mf2: {0}")]
Malformed(#[from] mf2_catalog::CatalogError),
#[error("mf2: no such locale")]
UnknownLocale,
#[error("mf2: the catalog could not be fetched")]
Fetch,
}
#[cfg(all(
any(feature = "ssr", feature = "hydrate", feature = "csr"),
any(feature = "leptos", feature = "leptos-0-8")
))]
impl LoadError {
pub(crate) fn from_reader(error: mf2_catalog::CatalogError) -> LoadError {
match error {
mf2_catalog::CatalogError::ManifestMismatch => LoadError::ManifestMismatch,
other => LoadError::Malformed(other),
}
}
}
#[cfg(feature = "native")]
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum NativeError {
#[error("locale {0:?} is not supported")]
UnknownLocale(String),
#[error("no catalog was built for locale {0:?}")]
MissingCatalog(String),
#[error(
"the catalog for locale {0:?} is not embedded: the build wrote it beside the executable, to load from a directory"
)]
NotEmbedded(String),
#[error(
"another corpus is already installed: the store holds one message set per process (format another with mf2::native::Catalogs)"
)]
AnotherCorpus,
#[error("catalog for locale {expected:?} contains locale {actual:?}")]
LocaleMismatch {
expected: String,
actual: String,
},
#[error("invalid catalog for locale {locale:?}: {source}")]
Catalog {
locale: String,
source: mf2_catalog::CatalogError,
},
#[error(
"catalog {path:?} is not the one its name promises (its content hashes to {actual}): it is from another build"
)]
ContentMismatch {
path: PathBuf,
actual: String,
},
#[error("could not read catalog {path:?}: {source}")]
Io {
path: PathBuf,
source: std::io::Error,
},
}
#[derive(Clone, Copy, PartialEq, Eq, Debug, thiserror::Error)]
#[error("no language of this application matches; it has {}", Tags(self.supported))]
pub struct UnknownLocale {
supported: &'static [(&'static str, mf2_catalog::Dir)],
}
impl UnknownLocale {
#[doc(hidden)]
#[must_use]
pub const fn new(supported: &'static [(&'static str, mf2_catalog::Dir)]) -> UnknownLocale {
UnknownLocale { supported }
}
pub fn supported(&self) -> impl ExactSizeIterator<Item = &'static str> + use<> {
let supported = self.supported;
supported.iter().map(|(tag, _)| *tag)
}
}
struct Tags(&'static [(&'static str, mf2_catalog::Dir)]);
impl core::fmt::Display for Tags {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
for (i, (tag, _)) in self.0.iter().enumerate() {
if i > 0 {
f.write_str(", ")?;
}
f.write_str(tag)?;
}
Ok(())
}
}