Skip to main content

yogurt/argument/
parser.rs

1use crate::{Error, InvalidCommandReason, Result};
2use std::fmt::Debug;
3
4pub trait ArgumentParser: Debug + Clone {
5    type Output;
6
7    fn parse(&self, token: &str) -> Result<Self::Output>;
8
9    fn validator(&self) -> fn(&str) -> bool;
10}
11
12#[derive(Debug, Clone)]
13pub struct StringArgument;
14
15impl ArgumentParser for StringArgument {
16    type Output = String;
17
18    fn parse(&self, token: &str) -> Result<Self::Output> {
19        Ok(token.to_string())
20    }
21
22    fn validator(&self) -> fn(&str) -> bool {
23        |_| true
24    }
25}
26
27#[derive(Debug, Clone)]
28pub struct IntArgument;
29
30impl ArgumentParser for IntArgument {
31    type Output = i32;
32
33    fn parse(&self, token: &str) -> Result<Self::Output> {
34        token
35            .parse()
36            .map_err(|_| Error::InvalidCommand(InvalidCommandReason::InvalidArgument))
37    }
38
39    fn validator(&self) -> fn(&str) -> bool {
40        |str| str.parse::<i32>().is_ok()
41    }
42}
43
44#[derive(Debug, Clone)]
45pub struct BoundedIntArgument {
46    min: i32,
47    max: i32,
48}
49
50impl ArgumentParser for BoundedIntArgument {
51    type Output = i32;
52
53    fn parse(&self, token: &str) -> Result<Self::Output> {
54        let int: i32 = token
55            .parse()
56            .map_err(|_| Error::InvalidCommand(InvalidCommandReason::InvalidArgument))?;
57        if int <= self.max && int >= self.min {
58            Ok(int)
59        } else {
60            Err(Error::InvalidCommand(InvalidCommandReason::InvalidArgument))
61        }
62    }
63
64    fn validator(&self) -> fn(&str) -> bool {
65        |str| str.parse::<i32>().is_ok()
66    }
67}
68
69#[derive(Debug, Clone)]
70pub struct ChoiceArgument(Vec<String>);
71
72impl ArgumentParser for ChoiceArgument {
73    type Output = String;
74
75    fn parse(&self, token: &str) -> Result<Self::Output> {
76        let token = token.to_string();
77        if self.0.contains(&token) {
78            Ok(token)
79        } else {
80            Err(Error::InvalidCommand(InvalidCommandReason::InvalidArgument))
81        }
82    }
83
84    fn validator(&self) -> fn(&str) -> bool {
85        |_| true
86    }
87}