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 AddIdRequest {
19
    pub fn new(uri: Uri, position: Option<SongPosition>) -> Self {
20
        Self { uri, position }
21
    }
22
}
23

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

            
85
impl Command for AddId {
86
    type Request = AddIdRequest;
87
    type Response = AddIdResponse;
88
}