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::{DbSongInfo, PlaylistVersion, Priority, SongId, SongPosition, WindowRange},
8
};
9

            
10
pub struct PlChanges;
11

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

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

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

            
29
    fn into_request_enum(self) -> crate::Request {
30
        crate::Request::PlChanges(self.version, self.window)
31
    }
32

            
33
    fn from_request_enum(request: crate::Request) -> Option<Self> {
34
        match request {
35
            crate::Request::PlChanges(version, window) => {
36
                Some(PlChangesRequest { version, window })
37
            }
38
            _ => None,
39
        }
40
    }
41

            
42
    fn serialize(&self) -> String {
43
        match self.window.as_ref() {
44
            Some(window) => format!("{} {} {}\n", Self::COMMAND, self.version, window),
45
            None => format!("{} {}\n", Self::COMMAND, self.version),
46
        }
47
    }
48

            
49
    fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
50
        let version = parts.next().ok_or(Self::missing_arguments_error(0))?;
51
        let version = version
52
            .parse()
53
            .map_err(|_| RequestParserError::SubtypeParserError {
54
                argument_index: 0,
55
                expected_type: "PlaylistVersion",
56
                raw_input: version.to_string(),
57
            })?;
58

            
59
        let window = parts
60
            .next()
61
            .map(|w| {
62
                w.parse()
63
                    .map_err(|_| RequestParserError::SubtypeParserError {
64
                        argument_index: 1,
65
                        expected_type: "WindowRange",
66
                        raw_input: w.to_string(),
67
                    })
68
            })
69
            .transpose()?;
70

            
71
        Self::throw_if_too_many_arguments(parts)?;
72

            
73
        Ok(PlChangesRequest { version, window })
74
    }
75
}
76

            
77
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
78
pub struct PlChangesResponse(Vec<PlChangesResponseEntry>);
79

            
80
impl PlChangesResponse {
81
    pub fn new(items: Vec<PlChangesResponseEntry>) -> Self {
82
        PlChangesResponse(items)
83
    }
84
}
85

            
86
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
87
pub struct PlChangesResponseEntry {
88
    pub position: SongPosition,
89
    pub id: SongId,
90
    pub priority: Option<Priority>,
91
    pub song_info: DbSongInfo,
92
}
93

            
94
impl PlChangesResponseEntry {
95
    pub fn new(
96
        position: SongPosition,
97
        id: SongId,
98
        priority: Option<Priority>,
99
        song_info: DbSongInfo,
100
    ) -> Self {
101
        PlChangesResponseEntry {
102
            position,
103
            id,
104
            priority,
105
            song_info,
106
        }
107
    }
108
}
109

            
110
impl CommandResponse for PlChangesResponse {
111
    fn from_response_enum(response: crate::Response) -> Option<Self> {
112
        todo!()
113
    }
114

            
115
    fn into_response_enum(self) -> crate::Response {
116
        todo!()
117
    }
118

            
119
    fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
120
        unimplemented!()
121
    }
122
}
123

            
124
impl Command for PlChanges {
125
    type Request = PlChangesRequest;
126
    type Response = PlChangesResponse;
127
}