crowbook_localize/
localizer.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with
3// this file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5use lang::Lang;
6use error::{Result, Error};
7use macrogen;
8use extractor::Extractor;
9
10use std::fs::File;
11use std::path::Path;
12use std::io::Write;
13
14/// Main struct for initiating localization for a project.
15///
16/// # Example
17///
18/// ```rust
19/// use crowbook_intl::{Localizer, Extractor};
20/// let fr = r#"
21/// msgid "Hello, {}"
22/// msgstr "Bonjour, {}"
23/// "#;
24/// let es = r#"
25/// msgid "Hello, {}"
26/// msgstr "Hola, {}"
27/// "#;
28/// let extractor = Extractor::new();
29/// let mut localizer = Localizer::new(&extractor);
30/// localizer.add_lang("fr", fr).unwrap();
31/// localizer.add_lang("es", es).unwrap();
32/// println!("{}", localizer.generate_macro_file());
33/// ```
34pub struct Localizer<'a> {
35    langs: Vec<Lang>,
36    extractor: &'a Extractor,
37}
38
39impl<'a> Localizer<'a> {
40    /// Create a new, empty Localizer
41    pub fn new(extractor: &'a Extractor) -> Localizer<'a> {
42        Localizer {
43            langs: vec!(),
44            extractor: extractor,
45        }
46    }
47
48    /// Add a lang to the localizer
49    ///
50    /// # Arguments
51    ///
52    /// * `lang`: the code of the language (e.g. "fr", "en", ...);
53    /// * `s`: a string containing localization information. It should be foramtted
54    /// similarly to gettext `mo` files.
55    pub fn add_lang<S: Into<String>>(&mut self, lang: S, s: &str) -> Result<()> {
56        let lang = Lang::new_from_str(lang, s)?;
57        self.langs.push(lang);
58        Ok(())
59    }
60
61    /// Generate the `localization_macros.rs` file.
62    pub fn generate_macro_file(mut self) -> String {
63        macrogen::generate_macro_file(&mut self.langs, self.extractor)
64    }
65
66    /// Write the `localization_macros.rs` file to a file.
67    pub fn write_macro_file<P:AsRef<Path>>(self, file: P) -> Result<()> {
68        let mut f = File::create(file.as_ref())
69            .map_err(|e| Error::new(format!("Could not create file {file}: {error}",
70                                            file = file.as_ref().display(),
71                                            error = e)))?;
72        let content = self.generate_macro_file();
73        f.write_all(content.as_bytes())
74             .map_err(|e| Error::new(format!("Could not write to file {file}: {error}",
75                                             file = file.as_ref().display(),
76                                             error = e)))?;
77        Ok(())
78    }
79}