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}