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

            
3
use crate::{
4
    commands::{Command, 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
pub struct AddId;
11

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

            
18
impl CommandRequest for AddIdRequest {
19
    const COMMAND: &'static str = "addid";
20
    const MIN_ARGS: u32 = 1;
21
    const MAX_ARGS: Option<u32> = Some(2);
22

            
23
    fn into_request_enum(self) -> crate::Request {
24
        crate::Request::AddId(self.uri, self.position)
25
    }
26

            
27
    fn from_request_enum(request: crate::Request) -> Option<Self> {
28
        match request {
29
            crate::Request::AddId(uri, position) => Some(AddIdRequest { uri, position }),
30
            _ => None,
31
        }
32
    }
33

            
34
    fn serialize(&self) -> String {
35
        match self.position {
36
            Some(pos) => format!("{} {} {}\n", Self::COMMAND, self.uri, pos),
37
            None => format!("{} {}\n", Self::COMMAND, self.uri),
38
        }
39
    }
40

            
41
    fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
42
        let uri = match parts.next() {
43
            Some(s) => s,
44
            None => return Err(Self::missing_arguments_error(0)),
45
        };
46

            
47
        let position = match parts.next() {
48
            Some(s) => Some(s.parse::<SongPosition>().map_err(|_| {
49
                RequestParserError::SubtypeParserError {
50
                    argument_index: 1,
51
                    expected_type: "SongPosition",
52
                    raw_input: s.to_owned(),
53
                }
54
            })?),
55
            None => None,
56
        };
57

            
58
        Self::throw_if_too_many_arguments(parts)?;
59

            
60
        Ok(AddIdRequest {
61
            uri: uri.to_string(),
62
            position,
63
        })
64
    }
65
}
66

            
67
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
68
pub struct AddIdResponse {
69
    pub id: SongId,
70
}
71

            
72
impl CommandResponse for AddIdResponse {
73
    fn into_response_enum(self) -> crate::Response {
74
        todo!()
75
    }
76

            
77
    fn from_response_enum(response: crate::Response) -> Option<Self> {
78
        todo!()
79
    }
80

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

            
92
impl Command for AddId {
93
    type Request = AddIdRequest;
94
    type Response = AddIdResponse;
95
}