vornix-core 0.1.0

Librería de utilidades para microservicios en Rust, incluyendo conexión asincrónica a bases de datos, manejo de respuestas y más.
Documentation
use fluent_bundle::{FluentArgs, FluentValue};
use fluent_langneg::{negotiate_languages, LanguageIdentifier, NegotiationStrategy};
use fluent_resmgr::resource_manager::ResourceManager;
use std::collections::HashMap;
use std::fs;
use std::sync::Arc;
use std::path::{Path, PathBuf};

pub struct I18n {
    resource_manager: ResourceManager,
    bundles: HashMap<String, Arc<FluentBundle<FluentResource>>>,
}

impl I18n {
    pub fn new(locales_path: &str, service_locales_path: Option<&str>) -> Self {
        let resource_manager = ResourceManager::new(locales_path);
        let mut bundles = HashMap::new();

        for lang in &["en", "es"] {
            let mut resources = resource_manager
                .get_resources(lang, &["messages.ftl"])
                .expect("Failed to load general resources.");

            if let Some(service_path) = service_locales_path {
                let service_resources = ResourceManager::new(service_path)
                    .get_resources(lang, &["messages.ftl"])
                    .expect("Failed to load service-specific resources.");
                resources.extend(service_resources);
            }

            let mut bundle = FluentBundle::new(vec![lang.to_string()]);
            for resource in resources {
                bundle.add_resource(resource).expect("Failed to add resource.");
            }
            bundles.insert(lang.to_string(), Arc::new(bundle));
        }

        I18n {
            resource_manager,
            bundles,
        }
    }
    fn get_available_locales() -> Result<Vec<LanguageIdentifier>, io::Error> {
        let mut locales = vec![];
    
        let res_path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR"))
            .join("examples")
            .join("resources");
        let res_dir = fs::read_dir(res_path)?;
        for entry in res_dir.flatten() {
            let path = entry.path();
            if path.is_dir() {
                if let Some(name) = path.file_name() {
                    if let Some(name) = name.to_str() {
                        let langid: LanguageIdentifier = name.parse().expect("Parsing failed.");
                        locales.push(langid);
                    }
                }
            }
        }
        Ok(locales)
    }

    pub fn translate(&self, lang: &str, key: &str, args: Option<&HashMap<&str, &str>>) -> String {
        let lang = negotiate_languages(
            &[lang],
            &self.bundles.keys().map(|k| k.as_str()).collect::<Vec<_>>(),
            None,
            fluent_langneg::NegotiationStrategy::Filtering,
        )[0];

        let bundle = self.bundles.get(lang).expect("Bundle not found.");
        let msg = bundle.get_message(key).expect("Message not found.");
        let pattern = msg.value().expect("Message has no value.");

        let mut errors = vec![];
        let value = bundle.format_pattern(pattern, args, &mut errors);

        value.to_string()
    }
}