flagon-io/hello

public

Greets people from the command line. The sample repository for g1t.

Commit

Extract argument parsing into parse_args in lib.rs

g1t agentcommitted Parentae52036Browse files
2 files+41−30/2 viewed
+38−0
11 //! Greetings.
22
3+/// Parsed command-line options.
4+#[derive(Debug, Default, PartialEq, Eq)]
5+pub struct Options {
6+ /// The name to greet, if one was given.
7+ pub name: Option<String>,
8+}
9+
10+/// Parses command-line arguments (excluding the program name).
11+///
12+/// Arguments starting with `--` are treated as flags and skipped; the name is
13+/// the first remaining argument.
14+pub fn parse_args<I: IntoIterator<Item = String>>(args: I) -> Options {
15+ let name = args.into_iter().find(|arg| !arg.starts_with("--"));
16+ Options { name }
17+}
18+
319 /// The greeting for `name`.
420 pub fn greeting(name: &str) -> String {
521 let trimmed = name.trim();
1834 mod tests {
1935 use super::*;
2036
37+ fn args(list: &[&str]) -> Vec<String> {
38+ list.iter().map(|s| s.to_string()).collect()
39+ }
40+
41+ #[test]
42+ fn parse_args_no_args() {
43+ assert_eq!(parse_args(args(&[])).name, None);
44+ }
45+
46+ #[test]
47+ fn parse_args_name() {
48+ assert_eq!(parse_args(args(&["Ada"])).name.as_deref(), Some("Ada"));
49+ }
50+
51+ #[test]
52+ fn parse_args_skips_leading_flag() {
53+ assert_eq!(
54+ parse_args(args(&["--unknown", "Ada"])).name.as_deref(),
55+ Some("Ada")
56+ );
57+ }
58+
2159 #[test]
2260 fn greets_by_name() {
2361 assert_eq!(greeting("Ada"), "Hello, Ada!");
+3−3
11 use std::env;
22
3−use hello::greeting;
3+use hello::{greeting, parse_args};
44
55 fn main() {
66 // The name given, or whoever is signed in.
7− let name = env::args()
8− .nth(1)
7+ let name = parse_args(env::args().skip(1))
8+ .name
99 .or_else(|| env::var("USER").ok())
1010 .unwrap_or_else(|| "world".to_owned());
1111 println!("{}", greeting(&name));