has_env_flag/
lib.rs

1pub fn has_flag(flag: &str) -> bool {
2    _has_flag(std::env::args(), flag)
3}
4
5fn _has_flag<I: Iterator<Item = String>>(args: I, flag: &str) -> bool {
6    let prefix = if flag.starts_with('-') {
7        ""
8    } else {
9        if flag.len() == 1 {
10            "-"
11        } else {
12            "--"
13        }
14    };
15
16    let formatted_flag = format!("{}{}", prefix, flag);
17    args.take_while(|arg| arg != "--").any(|arg| arg == formatted_flag)
18}
19
20#[cfg(test)]
21mod tests {
22    use super::*;
23    #[test]
24    fn args_with_value_not_matching_double_dash() {
25        let args = vec!["--foo", "--unicorn=rainbow", "--bar"];
26        let expected_value = "unicorn=rainbow";
27
28        assert!(_has_flag(
29            args.into_iter().map(ToString::to_string),
30            expected_value
31        ))
32    }
33
34    #[test]
35    fn args_matching_value_before_terminator() {
36        let args = vec!["--unicorn", "--", "--foo"];
37        let expected_value = "unicorn";
38
39        assert!(_has_flag(
40            args.into_iter().map(ToString::to_string),
41            expected_value
42        ))
43    }
44
45    #[test]
46    fn args_not_matching_value_after_terminator() {
47        let args = vec!["--foo", "--", "--unicorn"];
48        let expected_value = "unicorn";
49
50        assert!(!_has_flag(
51            args.into_iter().map(ToString::to_string),
52            expected_value
53        ))
54    }
55
56    #[test]
57    fn args_not_matching_value_not_in_args() {
58        let args = vec!["--foo"];
59        let expected_value = "unicorn";
60
61        assert!(!_has_flag(
62            args.into_iter().map(ToString::to_string),
63            expected_value
64        ))
65    }
66
67    #[test]
68    fn args_with_sequential_single_dash_input() {
69        let args = vec!["-f", "-u", "-b"];
70        let expected_value = "-u";
71
72        assert!(_has_flag(
73            args.into_iter().map(ToString::to_string),
74            expected_value
75        ))
76    }
77
78    #[test]
79    fn args_with_sequential_single_dash_and_match_before_terminator() {
80        let args = vec!["-u", "--", "-f"];
81        let expected_value = "-u";
82
83        assert!(_has_flag(
84            args.into_iter().map(ToString::to_string),
85            expected_value
86        ))
87    }
88
89    #[test]
90    fn args_with_sequential_single_dash_and_no_match_after_terminator() {
91        let args = vec!["-u", "--", "-f"];
92        let expected_value = "-f";
93
94        assert!(!_has_flag(
95            args.into_iter().map(ToString::to_string),
96            expected_value
97        ))
98    }
99
100    #[test]
101    fn args_without_double_dash_input() {
102        assert!(_has_flag(
103            vec!["--unicorn", "--foo", "-f"]
104                .into_iter()
105                .map(ToString::to_string),
106            "unicorn"
107        ));
108    }
109
110    #[test]
111    fn args_with_double_dash_input() {
112        assert!(_has_flag(
113            vec!["--unicorn", "--foo", "-f"]
114                .into_iter()
115                .map(ToString::to_string),
116            "--unicorn"
117        ));
118    }
119
120    #[test]
121    fn args_with_single_dash_input() {
122        assert!(_has_flag(
123            vec!["--unicorn", "--foo", "-f"]
124                .into_iter()
125                .map(ToString::to_string),
126            "-f"
127        ));
128    }
129
130    #[test]
131    fn args_without_single_dash_input() {
132        assert!(_has_flag(
133            vec!["--unicorn", "--foo", "-f"]
134                .into_iter()
135                .map(ToString::to_string),
136            "f"
137        ));
138    }
139
140    #[test]
141    fn args_that_doesnt_exist() {
142        assert!(!_has_flag(
143            vec!["--unicorn", "--foo", "-f"]
144                .into_iter()
145                .map(ToString::to_string),
146            "rainbow"
147        ));
148    }
149}