1#[derive(Debug)]
2pub enum CliParamsError {
3 TooManyValues,
4 KeyRequiresValue,
5}
6
7pub struct CliParams<'a> {
8 params: Vec<&'a str>,
9}
10
11impl<'a> CliParams<'a> {
12 pub fn new(params: Vec<&'a str>) -> Self {
13 Self { params }
14 }
15
16 pub fn pop_bool_flag(
17 &mut self,
18 short: Option<&str>,
19 long: Option<&str>,
20 ) -> Result<bool, CliParamsError> {
21 let indexes = self.get_key_indexes(short, long);
22 match indexes.len() {
23 0 => Ok(false),
24 1 => {
25 self.params.remove(indexes[0]);
26 Ok(true)
27 }
28 _ => Err(CliParamsError::TooManyValues),
29 }
30 }
31
32 pub fn pop_key_value(
33 &mut self,
34 short: Option<&str>,
35 long: Option<&str>,
36 ) -> Result<Option<&'a str>, CliParamsError> {
37 let indexes = self.get_key_indexes(short, long);
38 match indexes.len() {
39 0 => Ok(None),
40 1 if indexes[0] == self.params.len() - 1 => Err(CliParamsError::KeyRequiresValue),
41 1 => {
42 let index = indexes[0];
43 let val = self.params.remove(index + 1);
44 self.params.remove(index);
45 Ok(Some(val))
46 }
47 _ => Err(CliParamsError::TooManyValues),
48 }
49 }
50
51 pub fn pop_key_values(
52 &mut self,
53 short: Option<&str>,
54 long: Option<&str>,
55 ) -> Result<Vec<&'a str>, CliParamsError> {
56 let indexes = self.get_key_indexes(short, long);
57 if indexes.is_empty() {
58 return Ok(Vec::new());
59 }
60 if indexes.last().unwrap() + 1 == self.params.len() {
61 return Err(CliParamsError::KeyRequiresValue);
62 }
63 let mut result = Vec::new();
64 for index in indexes.into_iter().rev() {
65 result.push(self.params.remove(index + 1));
66 self.params.remove(index);
67 }
68 result.reverse();
69 Ok(result)
70 }
71
72 pub fn pop_position_value(&mut self) -> Option<&'a str> {
73 if self.params.is_empty() {
74 return None;
75 }
76 Some(self.params.remove(0))
77 }
78
79 pub fn pop_position_values(&mut self) -> Vec<&'a str> {
80 std::mem::take(&mut self.params)
81 }
82
83 fn get_key_indexes(&self, short: Option<&str>, long: Option<&str>) -> Vec<usize> {
84 let mut result = Vec::new();
85 for (i, key) in self.params.iter().enumerate() {
86 if short == Some(key) || long == Some(key) {
87 result.push(i);
88 }
89 }
90 result
91 }
92}