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

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

            
10
pub struct PlChangesPosId;
11

            
12
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13
pub struct PlChangesPosIdRequest {
14
    pub version: PlaylistVersion,
15
    pub window: Option<WindowRange>,
16
}
17

            
18
impl PlChangesPosIdRequest {
19
    pub fn new(version: PlaylistVersion, window: Option<WindowRange>) -> Self {
20
        Self { version, window }
21
    }
22
}
23

            
24
impl CommandRequest for PlChangesPosIdRequest {
25
    const COMMAND: &'static str = "plchangesposid";
26
    const MIN_ARGS: u32 = 1;
27
    const MAX_ARGS: Option<u32> = Some(2);
28

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

            
36
    fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
37
        let version = parts.next().ok_or(Self::missing_arguments_error(0))?;
38
        let version = version
39
            .parse()
40
            .map_err(|_| RequestParserError::SubtypeParserError {
41
                argument_index: 0,
42
                expected_type: "PlaylistVersion",
43
                raw_input: version.to_string(),
44
            })?;
45

            
46
        let window = parts
47
            .next()
48
            .map(|w| {
49
                w.parse()
50
                    .map_err(|_| RequestParserError::SubtypeParserError {
51
                        argument_index: 1,
52
                        expected_type: "WindowRange",
53
                        raw_input: w.to_string(),
54
                    })
55
            })
56
            .transpose()?;
57

            
58
        Self::throw_if_too_many_arguments(parts)?;
59

            
60
        Ok(PlChangesPosIdRequest { version, window })
61
    }
62
}
63

            
64
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
65
pub struct PlChangesPosIdResponse(Vec<PlChangesPosIdResponseEntry>);
66

            
67
impl PlChangesPosIdResponse {
68
    pub fn new(items: Vec<PlChangesPosIdResponseEntry>) -> Self {
69
        PlChangesPosIdResponse(items)
70
    }
71
}
72

            
73
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
74
pub struct PlChangesPosIdResponseEntry {
75
    // 'cpos'
76
    pub position: SongPosition,
77
    pub id: SongId,
78
}
79

            
80
impl PlChangesPosIdResponseEntry {
81
    pub fn new(position: SongPosition, id: SongId) -> Self {
82
        PlChangesPosIdResponseEntry { position, id }
83
    }
84
}
85

            
86
impl CommandResponse for PlChangesPosIdResponse {
87
    fn parse(_parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
88
        unimplemented!()
89
    }
90
}
91

            
92
impl Command for PlChangesPosId {
93
    type Request = PlChangesPosIdRequest;
94
    type Response = PlChangesPosIdResponse;
95
}