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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
//! # rtr //! //! rtr is a crate that return strings from translation files <br/> //! _Thoses files need to be manually created with the [rtrTranslator](https://github.com/ProbablyClem/rtrTranslator) software_ //! source code at : #[macro_use] extern crate lazy_static; #[macro_use] extern crate string_format; use string_format::*; use std::io; use std::fs::File; use std::io::prelude::*; use std::io::BufReader; use std::sync::Mutex; use std::sync::atomic::{AtomicBool, Ordering}; lazy_static! { static ref ORIGIN_VEC : Vec<String> = load_vec("origin"); //The vector that containt every line of the origin langage static ref DEST_VEC : Vec<String> = load_vec("fr"); //The vector that containt every line of the destination language (e.g fr, it, de...) static ref STATE : Mutex<AtomicBool> = Mutex::new(AtomicBool::new(true)); } fn create_path(source: String) -> String { let mut new_path = String::from("./lang/.txt"); new_path.insert_str(7, source.as_str()); return new_path; } fn load_vec(lang : &str) -> Vec<String>{ let f = File::open(create_path(lang.to_string())).unwrap(); let mut vec = Vec::new(); let f = BufReader::new(f); for line in f.lines() { vec.push(line.unwrap()); } vec } ///Set the language for the program /// # Examples /// /// To set the program in french /// /// ``` /// extern crate rtr; /// /// match rtr::init("fr"){ /// Ok(_) => (), /// Err(e) => panic!("couldn't load the fr translation file, error {}", e), /// }; /// ``` ///Don't forget that it will need the ./lang/fr.txt file /// /// # Errors ///Will return an std::io:Error in case of trouble loading the translation file pub fn init(new_lang: &str) -> Result<(), io::Error> { // let f = File::open(create_path("origin".to_string()))?; // let f = BufReader::new(f); // for line in f.lines() { // ORIGIN_VEC.lock().unwrap().push(line.unwrap()); // } // let g = File::open(create_path(new_lang.to_string()))?; // let g = BufReader::new(g); // for line in g.lines() { // DEST_VEC.lock().unwrap().push(line.unwrap()); // } Ok(()) } ///Disable the translation <br/> /// [rtr](./fn.rtr.html) will returns the argument /// /// # Examples /// /// disable() is mostly useful for error handling /// ``` /// extern crate rtr; /// use rtr::rtr; /// /// match rtr::init("fr") { /// Ok(_) => (), /// Err(e) => { /// println!("couldn't load fr translation file"); /// rtr::disable(); /// } /// } /// ``` /// /// use [enable](./fn.enable.html) to enable it again pub fn disable() { &STATE.lock().unwrap().store(false, Ordering::Relaxed); } ///Enable the translation<br/> ///[rtr](./fn.rtr.html) will now try to read strings from the translation file <br/> ///*_The translation then need to be loaded with [init](./fn.init.html)!_*<br/> ///Only useful after using [disable](./fn.disable.html) pub fn enable() { &STATE.lock().unwrap().store(true, Ordering::Relaxed); } ///Return the state of the translation<br/> ///If *false* [rtr](./fn.rtr.html) will return the argument<br/> ///If *true* [rtr](./fn.rtr.html) will act normaly<br/> ///True by default /// # Examples /// ``` ///extern crate rtr; ///use rtr::rtr; ///rtr::init("fr").unwrap(); /// ///assert_eq!(rtr::is_enabled(), true); /// //assuming that "hello" correspond to "bonjour" in the fr.txt file ///assert_eq!(rtr("hello"), "salut".to_string()); /// ///rtr::disable(); ///assert_eq!(rtr("hello"), "hello".to_string()); pub fn is_enabled() -> bool{ return STATE.lock().unwrap().load(Ordering::Relaxed); } ///Use with every str that you need to translate /// # Examples /// /// ``` /// extern crate rtr; /// use rtr::rtr; /// /// rtr::init("fr"); /// println!("{}", rtr("hello world")); /// ``` /// Will return the sentence that correspond to "hello world" in the ./lang/fr.txt file pub fn rtr(text: &str) -> String { if &STATE.lock().unwrap().load(Ordering::Relaxed) == &true { match ORIGIN_VEC.binary_search(&text.to_string()) { Ok(index) => { return DEST_VEC[index].clone(); } Err(_) => return text.to_string(), } } else { return text.to_string(); } } ///Same as rtr but will format the text. /// Will translate the first argument and then format with the others. /// /// # Example /// ``` /// #[macro_use] /// extern crate rtr; /// use rtr::*; /// /// init("fr"); /// /// assert_eq!(rtr!("hello {} {}", "cruel".to_string(), "monde".to_string()), String::from("salut cruel monde")); /// ``` #[macro_export] macro_rules! rtr { ($($x:expr)?, $($arg:tt)*) => { string_format!(rtr($($x)?), $($arg)*); }; } #[test] fn format(){ init("fr"); //assert_eq!(rtr("hello {}"), String::from("salut {}")); assert_eq!(rtr!("hello {} {}", "cruel".to_string(), "monde".to_string()), String::from("salut cruel monde")); }