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
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

extern crate json;

use std::fs::File;
use std::io::Read;
use std::io::BufReader;
use std::collections::HashMap;

use json::JsonValue;

/// I18n configuration
/// # Example
/// ```no-run
/// extern crate i18n;
/// use i18n::I18nConfig;
///
/// fn main() {
///     let config: I18nConfig =  I18nConfig{locales: &["en", "fr", "es"], directory: "translations"};
/// }
/// ```
pub struct I18nConfig<'a> {
    pub locales: &'a [&'a str],
    pub directory: &'a str
}


pub struct I18n<'b> {
    pub config: &'b I18nConfig<'b>,
    pub current_lang: &'b str,
    pub translations: HashMap<String, JsonValue>
}

impl<'b> I18n<'b> {
    /// Configures the library
    ///
    /// # Example
    /// ```no-run
    /// extern crate i18n;
    /// use i18n::I18n;
    /// use i18n::I18nConfig;
    /// 
    /// extern crate r_i18n;
    /// use r_i18n::I18n;
    /// use r_i18n::I18nConfig;
    ///
    /// fn main() {
    ///     let config: I18nConfig =  I18nConfig{locales: &["en", "fr", "es"], directory: "translations"};
    ///     let i18n: I18n = I18n::configure(&config);
    /// }
    /// ```
    pub fn configure(config: &'b I18nConfig<'b>) -> I18n<'b> {
        if let Some(current_lang) = config.locales.get(0) {
            let mut translations = HashMap::new();
            let mut i18n: I18n = I18n{config: config, current_lang: current_lang, translations: HashMap::new()};
            let buffers: HashMap<String, String> = i18n.read_files();
            for (lang, json) in buffers {
                let parsed_json = json::parse(json.as_str()).unwrap();
                translations.insert(lang, parsed_json);
            }
            i18n.translations = translations;
            i18n
        } else {
            panic!("You must add one language");
        }
    }


    /// Sets the current language
    ///
    /// # Example
    /// ```no-run
    /// extern crate r_i18n;
    /// use r_i18n::I18n;
    /// use r_i18n::I18nConfig;
    ///
    /// fn main() {
    ///     let config: I18nConfig =  I18nConfig{locales: &["en", "fr", "es"], directory: "translations"};
    ///     let mut r_i18n: I18n = I18n::configure(&config);
    ///     r_i18n.set_current_lang("fr");
    /// }
    /// ```
    pub fn set_current_lang(&mut self, lang: &'b str) {
        match self.config.locales.contains(&lang) {
            true => self.current_lang = lang,
            false => panic!("Please add {} to the list.", lang)
        }
    }

    fn read_files(&self) -> HashMap<String, String> {
        let mut buffers = HashMap::new();
        for filename in self.config.locales {
            let path = &format!("{}/{}.json", self.config.directory, filename);
            let file = File::open(path).expect("Failed to open the file");
            let mut reader = BufReader::new(file);
            let mut contents = String::new();
            reader.read_to_string(&mut contents).expect("Failed to read the file");
            buffers.insert(filename.to_string(), contents);
        }
        buffers
    }

    /// Translates by the keyword
    ///
    /// # Example
    /// ```no-run
    /// extern crate i18n;
    /// use i18n::I18n;
    /// use i18n::I18nConfig;
    /// 
    /// extern crate r_i18n;
    /// use r_i18n::I18n;
    /// use r_i18n::I18nConfig;
    ///
    /// fn main() {
    ///     let config: I18nConfig =  I18nConfig{locales: &["en", "fr", "es"], directory: "translations"};
    ///     let mut i18n: I18n = I18n::configure(&config);
    ///     i18n.set_current_lang("fr");
    ///     i18n.t("introduction"); // output should be "Bonjour, mon nom est WebD
    /// }
    /// ```
    pub fn t(&self, key: &'b str) -> &JsonValue {
        match self.translations.get(self.current_lang) {
            Some(language_json) => {
                if language_json.has_key(key) {
                    &language_json[key]
                } else {
                    panic!("Unable to find the key {}", key);
                }
            },
            None => panic!("Unable to get the language")
        }
    }

}