1
use serde::{Deserialize, Serialize};
2

            
3
use crate::commands::{
4
    Command, GenericResponseValue, Request, RequestParserResult, ResponseAttributes,
5
    ResponseParserError,
6
};
7

            
8
pub struct ReadMessages;
9

            
10
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11
pub struct ReadMessagesResponse {
12
    pub messages: Vec<(String, String)>,
13
}
14

            
15
impl Command for ReadMessages {
16
    type Response = ReadMessagesResponse;
17
    const COMMAND: &'static str = "readmessages";
18

            
19
    fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
20
        debug_assert!(parts.next().is_none());
21

            
22
        Ok((Request::ReadMessages, ""))
23
    }
24

            
25
1
    fn parse_response(
26
1
        parts: ResponseAttributes<'_>,
27
1
    ) -> Result<Self::Response, ResponseParserError> {
28
1
        let parts: Vec<_> = parts.into();
29
1
        debug_assert!(parts.len() % 2 == 0);
30

            
31
1
        let mut messages = Vec::with_capacity(parts.len() / 2);
32

            
33
2
        for channel_message_pair in parts.chunks_exact(2) {
34
2
            let (ckey, cvalue) = channel_message_pair[0];
35
2
            let (mkey, mvalue) = channel_message_pair[1];
36
2
            debug_assert!(ckey == "channel");
37
2
            debug_assert!(mkey == "message");
38

            
39
2
            let channel = match cvalue {
40
2
                GenericResponseValue::Text(s) => s.to_string(),
41
                GenericResponseValue::Binary(_) => {
42
                    return Err(ResponseParserError::UnexpectedPropertyType(
43
                        "channel", "Binary",
44
                    ))
45
                }
46
            };
47

            
48
2
            let message = match mvalue {
49
2
                GenericResponseValue::Text(s) => s.to_string(),
50
                GenericResponseValue::Binary(_) => {
51
                    return Err(ResponseParserError::UnexpectedPropertyType(
52
                        "message", "Binary",
53
                    ))
54
                }
55
            };
56

            
57
2
            messages.push((channel, message));
58
        }
59

            
60
1
        Ok(ReadMessagesResponse { messages })
61
1
    }
62
}
63

            
64
#[cfg(test)]
65
mod tests {
66
    use indoc::indoc;
67

            
68
    use super::*;
69

            
70
    #[test]
71
1
    fn test_parse_response() {
72
1
        let input = indoc! {"
73
1
            channel: channel1
74
1
            message: message1
75
1
            channel: channel2
76
1
            message: message2
77
1
            OK
78
1
        "};
79
1
        let result = ReadMessages::parse_raw_response(input);
80
1
        assert_eq!(
81
1
            result,
82
1
            Ok(ReadMessagesResponse {
83
1
                messages: vec![
84
1
                    ("channel1".to_string(), "message1".to_string()),
85
1
                    ("channel2".to_string(), "message2".to_string()),
86
1
                ]
87
1
            })
88
1
        );
89
1
    }
90
}