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 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(PlChangesRequest { version, window })
61
    }
62
}
63

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

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

            
73
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
74
pub struct PlChangesResponseEntry {
75
    pub position: SongPosition,
76
    pub id: SongId,
77
    pub priority: Option<Priority>,
78
    pub song_info: DbSongInfo,
79
}
80

            
81
impl PlChangesResponseEntry {
82
    pub fn new(
83
        position: SongPosition,
84
        id: SongId,
85
        priority: Option<Priority>,
86
        song_info: DbSongInfo,
87
    ) -> Self {
88
        PlChangesResponseEntry {
89
            position,
90
            id,
91
            priority,
92
            song_info,
93
        }
94
    }
95
}
96

            
97
impl CommandResponse for PlChangesResponse {
98
    fn parse(_parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
99
        unimplemented!()
100
    }
101
}
102

            
103
impl Command for PlChanges {
104
    type Request = PlChangesRequest;
105
    type Response = PlChangesResponse;
106
}