ltl_args/
matches.rs

1use crate::error::ValueError;
2use std::{collections::HashMap, str::FromStr};
3
4#[derive(Clone, Debug, PartialEq)]
5pub enum Value {
6    Single(String),
7    Multi(Vec<String>),
8    Flag(bool),
9}
10
11#[derive(Debug, PartialEq)]
12pub struct Matches {
13    exec_name: String,
14    positional: Vec<String>,
15    named: HashMap<String, Value>,
16}
17
18impl Matches {
19    pub fn new(exec_name: String, positional: Vec<String>, named: HashMap<String, Value>) -> Self {
20        Self {
21            exec_name,
22            positional,
23            named,
24        }
25    }
26
27    pub fn flag(&self, name: &str) -> Result<Option<bool>, ValueError> {
28        match self.named.get(name) {
29            Some(Value::Flag(b)) => Ok(Some(*b)),
30            Some(_) => Err(ValueError::WrongOptionType),
31            None => Ok(None),
32        }
33    }
34
35    pub fn one<T: FromStr>(&self, name: &str) -> Result<Option<T>, ValueError> {
36        match self.named.get(name) {
37            Some(Value::Single(val)) => {
38                let v = T::from_str(val.as_str())
39                    .map_err(|_| ValueError::ConversionError(val.clone()))?;
40                Ok(Some(v))
41            }
42            Some(_) => Err(ValueError::WrongOptionType),
43            None => Ok(None),
44        }
45    }
46
47    pub fn all<T: FromStr>(&self, name: &str) -> Result<Vec<T>, ValueError> {
48        match self.named.get(name) {
49            Some(Value::Multi(val)) => {
50                let r: Result<Vec<T>, _> = val.iter().map(|v| T::from_str(v.as_str())).collect();
51                r.map_err(|_| ValueError::ConversionError(format!("{:?}", val)))
52            }
53            Some(_) => Err(ValueError::WrongOptionType),
54            None => Ok(vec![]),
55        }
56    }
57
58    pub fn positional(&self) -> &[String] {
59        &self.positional
60    }
61}