1
use crate::{
2
    commands::{
3
        Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
4
        ResponseParserError, expect_property_type,
5
    },
6
    filter::parse_filter,
7
};
8

            
9
pub struct List;
10

            
11
pub type ListResponse = Vec<String>;
12

            
13
impl Command for List {
14
    type Response = ListResponse;
15
    const COMMAND: &'static str = "list";
16

            
17
    fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
18
        let tagtype = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
19
        let tagtype = tagtype
20
            .parse()
21
            .map_err(|_| RequestParserError::SyntaxError(1, tagtype.to_owned()))?;
22

            
23
        // TODO: This should be optional
24
        let filter = parse_filter(&mut parts)?;
25

            
26
        let group = if let Some("group") = parts.next() {
27
            let group = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
28
            Some(
29
                group
30
                    .parse()
31
                    .map_err(|_| RequestParserError::SyntaxError(1, group.to_owned()))?,
32
            )
33
        } else {
34
            None
35
        };
36

            
37
        debug_assert!(parts.next().is_none());
38

            
39
        Ok((Request::List(tagtype, filter, group), ""))
40
    }
41

            
42
    fn parse_response(
43
        parts: ResponseAttributes<'_>,
44
    ) -> Result<Self::Response, ResponseParserError> {
45
        debug_assert!({
46
            let key = parts.0.first().map(|(k, _)| k);
47
            parts.0.iter().all(|(k, _)| k == key.unwrap())
48
        });
49

            
50
        let list = parts
51
            .0
52
            .into_iter()
53
            .map(|(k, v)| Ok(expect_property_type!(Some(v), k, Text).to_string()))
54
            .collect::<Result<Vec<_>, ResponseParserError>>()?;
55

            
56
        Ok(list)
57
    }
58
}