use std::path::PathBuf;
use thiserror::Error;
use unic_langid::LanguageIdentifier;
#[derive(Debug, Error)]
pub enum EsFluentError {
#[error("Configuration file not found: {path}")]
ConfigNotFound { path: PathBuf },
#[error("Failed to parse configuration file: {0}")]
ConfigParseError(#[from] toml::de::Error),
#[error("Assets directory not found: {path}")]
AssetsNotFound { path: PathBuf },
#[error("Fallback language directory not found: {language}")]
FallbackLanguageNotFound { language: String },
#[error("Invalid language identifier '{identifier}': {reason}")]
InvalidLanguageIdentifier { identifier: String, reason: String },
#[error("Language '{0}' is not supported")]
LanguageNotSupported(LanguageIdentifier),
#[error("Fluent parsing error: {0:?}")]
FluentParseError(Vec<fluent_syntax::parser::ParserError>),
#[error("Fluent serialization error: {0}")]
FluentSerializeError(#[from] std::fmt::Error),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Environment variable error: {0}")]
EnvVarError(#[from] std::env::VarError),
#[error("Backend error: {0}")]
BackendError(#[from] anyhow::Error),
#[error("Missing package name")]
MissingPackageName,
}
impl EsFluentError {
pub fn config_not_found(path: impl Into<PathBuf>) -> Self {
Self::ConfigNotFound { path: path.into() }
}
pub fn assets_not_found(path: impl Into<PathBuf>) -> Self {
Self::AssetsNotFound { path: path.into() }
}
pub fn invalid_language_identifier(
identifier: impl Into<String>,
reason: impl Into<String>,
) -> Self {
Self::InvalidLanguageIdentifier {
identifier: identifier.into(),
reason: reason.into(),
}
}
pub fn fallback_language_not_found(language: impl Into<String>) -> Self {
Self::FallbackLanguageNotFound {
language: language.into(),
}
}
}
pub type EsFluentResult<T> = Result<T, EsFluentError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn helper_constructors_build_expected_variants() {
let config = EsFluentError::config_not_found("/tmp/i18n.toml");
assert!(matches!(config, EsFluentError::ConfigNotFound { .. }));
let assets = EsFluentError::assets_not_found("/tmp/i18n");
assert!(matches!(assets, EsFluentError::AssetsNotFound { .. }));
let invalid = EsFluentError::invalid_language_identifier("bad", "parse failure");
assert!(matches!(
invalid,
EsFluentError::InvalidLanguageIdentifier { .. }
));
let fallback = EsFluentError::fallback_language_not_found("en-US");
assert!(matches!(
fallback,
EsFluentError::FallbackLanguageNotFound { .. }
));
}
}