diff --git a/Cargo.toml b/Cargo.toml index dcc489c..787cecf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,9 +10,9 @@ keywords = ["bot", "chatbot", "ai", "conversational", "library"] categories = ["api-bindings", "web-programming"] [features] -default = [] +default = ["database", "i18n"] full = ["database", "http-client", "validation", "resilience", "i18n"] -database = [] +database = ["i18n"] http-client = ["dep:reqwest"] validation = [] resilience = [] diff --git a/src/i18n/bundle.rs b/src/i18n/bundle.rs index da17c61..bdcda6f 100644 --- a/src/i18n/bundle.rs +++ b/src/i18n/bundle.rs @@ -173,55 +173,59 @@ pub struct I18nBundle { impl I18nBundle { pub fn load(base_path: &str) -> BotResult { - let base = Path::new(base_path); - - if !base.exists() { - #[cfg(feature = "i18n")] - { - log::info!( - "Locales directory not found at {}, trying embedded assets", - base_path - ); - return Self::load_embedded(); - } - #[cfg(not(feature = "i18n"))] - return Err(BotError::config(format!( - "locales directory not found: {base_path}" - ))); + // When i18n feature is enabled, locales are ALWAYS embedded via rust-embed + // Filesystem loading is deprecated - use embedded assets only + #[cfg(feature = "i18n")] + { + log::info!("Loading embedded locale translations (rust-embed)"); + return Self::load_embedded(); } - let mut bundles = HashMap::new(); - let mut available = Vec::new(); + #[cfg(not(feature = "i18n"))] + { + let _base_path = base_path; // Suppress unused warning when i18n is enabled - let entries = fs::read_dir(base) - .map_err(|e| BotError::config(format!("failed to read locales directory: {e}")))?; + let base = Path::new(base_path); - for entry in entries { - let entry = entry - .map_err(|e| BotError::config(format!("failed to read directory entry: {e}")))?; + if !base.exists() { + return Err(BotError::config(format!( + "locales directory not found: {base_path}" + ))); + } - let path = entry.path(); + let mut bundles = HashMap::new(); + let mut available = Vec::new(); - if path.is_dir() { - match LocaleBundle::load(&path) { - Ok(bundle) => { - available.push(bundle.locale.clone()); - bundles.insert(bundle.locale.to_string(), bundle); - } - Err(e) => { - log::warn!("failed to load locale bundle: {e}"); + let entries = fs::read_dir(base) + .map_err(|e| BotError::config(format!("failed to read locales directory: {e}")))?; + + for entry in entries { + let entry = entry + .map_err(|e| BotError::config(format!("failed to read directory entry: {e}")))?; + + let path = entry.path(); + + if path.is_dir() { + match LocaleBundle::load(&path) { + Ok(bundle) => { + available.push(bundle.locale.clone()); + bundles.insert(bundle.locale.to_string(), bundle); + } + Err(e) => { + log::warn!("failed to load locale bundle: {e}"); + } } } } + + let fallback = Locale::default(); + + Ok(Self { + bundles, + available, + fallback, + }) } - - let fallback = Locale::default(); - - Ok(Self { - bundles, - available, - fallback, - }) } #[cfg(feature = "i18n")]