1
use crate::{
2
    commands::{
3
        Command, GenericResponseValue, Request, RequestParserError, RequestParserResult,
4
        ResponseAttributes, ResponseParserError,
5
    },
6
    common::{SongId, SongPosition},
7
};
8

            
9
pub struct AddId;
10

            
11
pub struct AddIdResponse {
12
    pub id: SongId,
13
}
14

            
15
impl Command for AddId {
16
    type Response = AddIdResponse;
17
    const COMMAND: &'static str = "addid";
18

            
19
    fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
20
        let uri = match parts.next() {
21
            Some(s) => s,
22
            None => return Err(RequestParserError::UnexpectedEOF),
23
        };
24

            
25
        let position = match parts.next() {
26
            Some(s) => Some(
27
                s.parse::<SongPosition>()
28
                    .map_err(|_| RequestParserError::SyntaxError(1, s.to_owned()))?,
29
            ),
30
            None => None,
31
        };
32

            
33
        debug_assert!(parts.next().is_none());
34

            
35
        Ok((Request::AddId(uri.to_string(), position), ""))
36
    }
37

            
38
    fn parse_response(
39
        parts: ResponseAttributes<'_>,
40
    ) -> Result<Self::Response, ResponseParserError> {
41
        let parts: Vec<_> = parts.into();
42
        let (key, value) = parts.first().ok_or(ResponseParserError::UnexpectedEOF)?;
43
        debug_assert!(key == &"Id");
44
        let value = match value {
45
            GenericResponseValue::Text(value) => value,
46
            GenericResponseValue::Binary(_) => {
47
                return Err(ResponseParserError::UnexpectedPropertyType("Id", "Binary"))
48
            }
49
        };
50
        let id = value
51
            .parse()
52
            .map_err(|_| ResponseParserError::InvalidProperty("Id", value.to_owned()))?;
53
        Ok(AddIdResponse { id })
54
    }
55
}