1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
mod error; mod po; pub use error::Result; use error::TextError; use std::collections::HashMap; use std::path::{Path, PathBuf}; pub struct Locale { path: PathBuf, domains: HashMap<String, po::Po>, } impl Locale { pub fn new<P: AsRef<Path>, S: AsRef<str>>(dir: P, locale: S) -> Result<Self> { let locale = locale.as_ref(); let path = dir.as_ref().join(locale); match std::fs::metadata(&path) { Ok(metadata) if metadata.is_dir() => Ok(Self { path, domains: HashMap::new(), }), Err(..) if locale.len() > 2 => Self::new(dir, &locale[..2]), _ => Err(TextError::LocaleNotFound), } } pub fn load<S: AsRef<str>>(&mut self, domain: S) -> Result<&po::Po> { let domain = domain.as_ref(); let path = self.path.join(domain.to_owned() + ".po"); let file = std::fs::File::open(&path)?; let po = po::Po::parse(file)?; self.domains.insert(domain.to_owned(), po); Ok(self.domain(domain).unwrap()) } pub fn domain<S: AsRef<str>>(&self, domain: S) -> Option<&po::Po> { self.domains.get(domain.as_ref()) } pub fn getd<S: AsRef<str>, S2: AsRef<str>>(&self, domain: S, id: S2) -> Option<&str> { self.domain(domain).and_then(|d| d.get(id.as_ref())) } pub fn code(&self) -> &std::ffi::OsStr { self.path.file_name().unwrap() } }