use std::fs;
use std::path::{Component, Path};
use rustc_hash::FxHashMap;
use crate::error::LangError;
use crate::intern::intern;
fn validate_locale(locale: &str) -> Result<(), LangError> {
let mut components = Path::new(locale).components();
match (components.next(), components.next()) {
(Some(Component::Normal(_)), None) => Ok(()),
_ => Err(LangError::InvalidLocale {
locale: locale.to_string(),
}),
}
}
pub(crate) fn load_file(
path: &str,
locale: &str,
) -> Result<FxHashMap<&'static str, &'static str>, LangError> {
validate_locale(locale)?;
let file_path = Path::new(path).join(format!("{locale}.toml"));
let raw = fs::read_to_string(&file_path).map_err(|e| LangError::Io {
locale: locale.to_string(),
cause: e.to_string(),
})?;
parse_toml(locale, &raw)
}
pub(crate) fn parse_toml(
locale: &str,
raw: &str,
) -> Result<FxHashMap<&'static str, &'static str>, LangError> {
let table: toml::Table = raw.parse().map_err(|e: toml::de::Error| LangError::Parse {
locale: locale.to_string(),
cause: e.to_string(),
})?;
let mut map: FxHashMap<&'static str, &'static str> =
FxHashMap::with_capacity_and_hasher(table.len(), rustc_hash::FxBuildHasher);
for (key, value) in table {
if let toml::Value::String(s) = value {
let _ = map.insert(intern(&key), intern(&s));
}
}
Ok(map)
}