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

            
3
use crate::{
4
    commands::{CommandRequest, CommandResponse, RequestParserError, ResponseParserError},
5
    request_tokenizer::RequestTokenizer,
6
    response_tokenizer::{ResponseAttributes, get_next_and_parse_property},
7
    types::{SongId, SongPosition, Uri},
8
};
9

            
10
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
11
pub struct AddIdRequest {
12
    pub uri: Uri,
13
    pub position: Option<SongPosition>,
14
}
15

            
16
impl AddIdRequest {
17
    pub fn new(uri: Uri, position: Option<SongPosition>) -> Self {
18
        Self { uri, position }
19
    }
20
}
21

            
22
impl CommandRequest for AddIdRequest {
23
    type Response = AddIdResponse;
24

            
25
    const COMMAND: &'static str = "addid";
26
    const MIN_ARGS: u32 = 1;
27
    const MAX_ARGS: Option<u32> = Some(2);
28

            
29
    fn serialize(&self) -> String {
30
        match self.position {
31
            Some(pos) => format!("{} {} {}\n", Self::COMMAND, self.uri, pos),
32
            None => format!("{} {}\n", Self::COMMAND, self.uri),
33
        }
34
    }
35

            
36
    fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
37
        let uri = match parts.next() {
38
            Some(s) => s,
39
            None => return Err(Self::missing_arguments_error(0)),
40
        };
41

            
42
        let position = match parts.next() {
43
            Some(s) => Some(s.parse::<SongPosition>().map_err(|_| {
44
                RequestParserError::SubtypeParserError {
45
                    argument_index: 1,
46
                    expected_type: "SongPosition",
47
                    raw_input: s.to_owned(),
48
                }
49
            })?),
50
            None => None,
51
        };
52

            
53
        Self::throw_if_too_many_arguments(parts)?;
54

            
55
        Ok(AddIdRequest {
56
            uri: uri.to_string(),
57
            position,
58
        })
59
    }
60
}
61

            
62
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
63
pub struct AddIdResponse {
64
    pub id: SongId,
65
}
66

            
67
impl AddIdResponse {
68
    pub fn new(id: SongId) -> Self {
69
        Self { id }
70
    }
71
}
72

            
73
impl CommandResponse for AddIdResponse {
74
    type Request = AddIdRequest;
75

            
76
    fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
77
        let parts: Vec<_> = parts.into();
78
        let mut iter = parts.into_iter();
79
        let (key, id) = get_next_and_parse_property!(iter, Text);
80
        if key != "Id" {
81
            return Err(ResponseParserError::UnexpectedProperty(key.to_string()));
82
        }
83
        Ok(AddIdResponse { id })
84
    }
85

            
86
    fn serialize(&self) -> Vec<u8> {
87
        unimplemented!("response serialization is not yet implemented for AddIdResponse")
88
    }
89
}