Add --lang option to greet in Spanish and French
3 files+65−70/3 viewed
| 9 | 9 | ||
| 10 | 10 | With no name it greets whoever is signed in. | |
| 11 | 11 | ||
| 12 | + | Use `--lang` to pick a language: `en` (default), `es` or `fr`. | |
| 13 | + | ||
| 14 | + | ```sh | |
| 15 | + | $ cargo run -- --lang es Ana | |
| 16 | + | ¡Hola, Ana! | |
| 17 | + | ``` | |
| 18 | + | ||
| 12 | 19 | ## Develop | |
| 13 | 20 | ||
| 14 | 21 | ```sh |
| 1 | 1 | //! Greetings. | |
| 2 | 2 | ||
| 3 | − | /// The greeting for `name`. | |
| 4 | − | pub fn greeting(name: &str) -> String { | |
| 5 | − | format!("Hello, {name}!") | |
| 3 | + | /// Languages that can be greeted in, as accepted by `--lang`. | |
| 4 | + | pub const LANGUAGES: [&str; 3] = ["en", "es", "fr"]; | |
| 5 | + | ||
| 6 | + | /// The greeting for `name` in the language `lang`. | |
| 7 | + | /// | |
| 8 | + | /// Returns an error naming the supported languages if `lang` is unknown. | |
| 9 | + | pub fn greeting(name: &str, lang: &str) -> Result<String, String> { | |
| 10 | + | match lang { | |
| 11 | + | "en" => Ok(format!("Hello, {name}!")), | |
| 12 | + | "es" => Ok(format!("¡Hola, {name}!")), | |
| 13 | + | "fr" => Ok(format!("Bonjour, {name} !")), | |
| 14 | + | _ => Err(format!( | |
| 15 | + | "unsupported language '{lang}' (supported: {})", | |
| 16 | + | LANGUAGES.join(", ") | |
| 17 | + | )), | |
| 18 | + | } | |
| 6 | 19 | } | |
| 7 | 20 | ||
| 8 | 21 | #[cfg(test)] | |
| 11 | 24 | ||
| 12 | 25 | #[test] | |
| 13 | 26 | fn greets_by_name() { | |
| 14 | − | assert_eq!(greeting("Ada"), "Hello, Ada!"); | |
| 27 | + | assert_eq!(greeting("Ada", "en").unwrap(), "Hello, Ada!"); | |
| 28 | + | } | |
| 29 | + | ||
| 30 | + | #[test] | |
| 31 | + | fn greets_in_spanish() { | |
| 32 | + | assert_eq!(greeting("Ana", "es").unwrap(), "¡Hola, Ana!"); | |
| 33 | + | } | |
| 34 | + | ||
| 35 | + | #[test] | |
| 36 | + | fn greets_in_french() { | |
| 37 | + | assert_eq!(greeting("Luc", "fr").unwrap(), "Bonjour, Luc !"); | |
| 38 | + | } | |
| 39 | + | ||
| 40 | + | #[test] | |
| 41 | + | fn rejects_unknown_language() { | |
| 42 | + | let err = greeting("Ada", "de").unwrap_err(); | |
| 43 | + | assert!(err.contains("en, es, fr")); | |
| 15 | 44 | } | |
| 16 | 45 | } |
| 1 | 1 | use std::env; | |
| 2 | + | use std::process; | |
| 2 | 3 | ||
| 3 | 4 | use hello::greeting; | |
| 4 | 5 | ||
| 5 | 6 | fn main() { | |
| 7 | + | let mut lang = "en".to_owned(); | |
| 8 | + | let mut name = None; | |
| 9 | + | let mut args = env::args().skip(1); | |
| 10 | + | while let Some(arg) = args.next() { | |
| 11 | + | if arg == "--lang" { | |
| 12 | + | lang = args.next().unwrap_or_else(|| { | |
| 13 | + | eprintln!("error: --lang requires a value"); | |
| 14 | + | process::exit(2); | |
| 15 | + | }); | |
| 16 | + | } else if let Some(value) = arg.strip_prefix("--lang=") { | |
| 17 | + | lang = value.to_owned(); | |
| 18 | + | } else if name.is_none() { | |
| 19 | + | name = Some(arg); | |
| 20 | + | } | |
| 21 | + | } | |
| 22 | + | ||
| 6 | 23 | // The name given, or whoever is signed in. | |
| 7 | − | let name = env::args() | |
| 8 | − | .nth(1) | |
| 24 | + | let name = name | |
| 9 | 25 | .or_else(|| env::var("USER").ok()) | |
| 10 | 26 | .unwrap_or_else(|| "world".to_owned()); | |
| 11 | − | println!("{}", greeting(&name)); | |
| 27 | + | match greeting(&name, &lang) { | |
| 28 | + | Ok(text) => println!("{text}"), | |
| 29 | + | Err(err) => { | |
| 30 | + | eprintln!("error: {err}"); | |
| 31 | + | process::exit(2); | |
| 32 | + | } | |
| 33 | + | } | |
| 12 | 34 | } |