connpass_rs/query/
types.rs

1use std::convert::TryFrom;
2
3use crate::errors::{ConnpassCliError, ConnpassResult, ValidationError};
4
5use super::validator::Validator;
6
7/// A data type that represents the range of `count` value.
8pub(crate) struct FetchCountRange(pub u8);
9
10impl Validator for FetchCountRange {
11    fn validate(self) -> ConnpassResult<Self> {
12        match self.0 {
13            1..=100 => Ok(self),
14            _ => Err(ConnpassCliError::Validation(ValidationError::OutOfRange {
15                msg: "`count` should be greater than or equal to 1 or less than or equals to 100. See more details: https://connpass.com/about/api/"
16                    .to_string(),
17            })),
18        }
19    }
20}
21
22/// A data type that represents the `format` value.
23pub(crate) struct FormatJson(pub String);
24
25impl Validator for FormatJson {
26    fn validate(self) -> ConnpassResult<Self> {
27        if self.0 == "json" {
28            Ok(self)
29        } else {
30            Err(ConnpassCliError::Validation(ValidationError::InvalidToken {
31                msg: "`format` can just accept the string \"json\". See more details: https://connpass.com/about/api/".to_string(),
32            }))
33        }
34    }
35}
36
37/// The order of search result.
38/// See more details in https://connpass.com/about/api/.
39#[derive(PartialEq, Debug)]
40pub enum OrderOption {
41    /// 「更新日時順」
42    LastModifiedDate = 1,
43    /// 「開催日順」
44    EventDate = 2,
45    /// 「新着順」
46    Newer = 3,
47}
48
49impl OrderOption {
50    pub fn new(id: u8) -> ConnpassResult<Self> {
51        Self::try_from(id)
52    }
53
54    pub fn to_u8(self) -> u8 {
55        self.into()
56    }
57}
58
59impl From<OrderOption> for u8 {
60    fn from(opt: OrderOption) -> Self {
61        match opt {
62            OrderOption::LastModifiedDate => 1,
63            OrderOption::EventDate => 2,
64            OrderOption::Newer => 3,
65        }
66    }
67}
68
69impl TryFrom<u8> for OrderOption {
70    type Error = ConnpassCliError;
71
72    fn try_from(value: u8) -> ConnpassResult<Self> {
73        match value {
74            1 => Ok(OrderOption::LastModifiedDate),
75            2 => Ok(OrderOption::EventDate),
76            3 => Ok(OrderOption::Newer),
77            _ => Err(ConnpassCliError::Validation(
78                ValidationError::InvalidToken {
79                    msg: format!("Invalid id came here: {}", &value),
80                },
81            )),
82        }
83    }
84}
85
86#[cfg(test)]
87mod test {
88    use crate::{
89        errors::{ConnpassCliError, ValidationError},
90        query::validator::Validator,
91    };
92
93    use super::{FetchCountRange, FormatJson};
94
95    #[test]
96    fn test_validate_fetch_count_range() {
97        let value = FetchCountRange(1);
98        let r = value.validate();
99        assert!(r.is_ok());
100
101        let value = FetchCountRange(100);
102        let r = value.validate();
103        assert!(r.is_ok());
104
105        let value = FetchCountRange(0);
106        let r = value.validate();
107        assert!(matches!(
108            r,
109            Err(ConnpassCliError::Validation(ValidationError::OutOfRange {
110                msg: _
111            }))
112        ));
113
114        let value = FetchCountRange(101);
115        let r = value.validate();
116        assert!(matches!(
117            r,
118            Err(ConnpassCliError::Validation(ValidationError::OutOfRange {
119                msg: _
120            }))
121        ));
122    }
123
124    #[test]
125    fn test_validate_format_token() {
126        let value = FormatJson("json".to_string());
127        let r = value.validate();
128        assert!(r.is_ok());
129
130        let value = FormatJson("yaml".to_string());
131        let r = value.validate();
132        assert!(matches!(
133            r,
134            Err(ConnpassCliError::Validation(
135                ValidationError::InvalidToken { msg: _ }
136            ))
137        ));
138    }
139}