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

            
3
use crate::{
4
    commands::{Command, CommandRequest, RequestParserError, empty_command_response},
5
    request_tokenizer::RequestTokenizer,
6
    types::{Priority, SongId},
7
};
8

            
9
pub struct PrioId;
10

            
11
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12
pub struct PrioIdRequest {
13
    pub prio: Priority,
14
    pub songids: Vec<SongId>,
15
}
16

            
17
impl CommandRequest for PrioIdRequest {
18
    const COMMAND: &'static str = "prioid";
19
    const MIN_ARGS: u32 = 2;
20
    // TODO: should this be 2?
21
    const MAX_ARGS: Option<u32> = None;
22

            
23
    fn into_request_enum(self) -> crate::Request {
24
        crate::Request::PrioId(self.prio, self.songids)
25
    }
26

            
27
    fn from_request_enum(request: crate::Request) -> Option<Self> {
28
        match request {
29
            crate::Request::PrioId(prio, songids) => Some(PrioIdRequest { prio, songids }),
30
            _ => None,
31
        }
32
    }
33

            
34
    fn serialize(&self) -> String {
35
        let songids = self
36
            .songids
37
            .iter()
38
            .map(|id| id.to_string())
39
            .collect::<Vec<String>>()
40
            .join(",");
41
        format!("{} {} {}\n", Self::COMMAND, self.prio, songids)
42
    }
43

            
44
    fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
45
        let prio = parts.next().ok_or(Self::missing_arguments_error(0))?;
46
        let prio = prio
47
            .parse()
48
            .map_err(|_| RequestParserError::SubtypeParserError {
49
                argument_index: 0,
50
                expected_type: "Priority",
51
                raw_input: prio.to_string(),
52
            })?;
53

            
54
        // TODO: determine how to count arguments here...
55
        let songids = parts.next().ok_or(Self::missing_arguments_error(1))?;
56
        let songids = songids
57
            .split(',')
58
            .map(|s| {
59
                s.parse()
60
                    .map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))
61
            })
62
            .collect::<Result<Vec<SongId>, RequestParserError>>()?;
63

            
64
        Self::throw_if_too_many_arguments(parts)?;
65

            
66
        Ok(PrioIdRequest { prio, songids })
67
    }
68
}
69

            
70
empty_command_response!(PrioId);
71

            
72
impl Command for PrioId {
73
    type Request = PrioIdRequest;
74
    type Response = PrioIdResponse;
75
}