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 PrioIdRequest {
18
    pub fn new(prio: Priority, songids: Vec<SongId>) -> Self {
19
        Self { prio, songids }
20
    }
21
}
22

            
23
impl CommandRequest for PrioIdRequest {
24
    const COMMAND: &'static str = "prioid";
25
    const MIN_ARGS: u32 = 2;
26
    // TODO: should this be 2?
27
    const MAX_ARGS: Option<u32> = None;
28

            
29
    fn into_request_enum(self) -> crate::Request {
30
        crate::Request::PrioId(self.prio, self.songids)
31
    }
32

            
33
    fn from_request_enum(request: crate::Request) -> Option<Self> {
34
        match request {
35
            crate::Request::PrioId(prio, songids) => Some(PrioIdRequest { prio, songids }),
36
            _ => None,
37
        }
38
    }
39

            
40
    fn serialize(&self) -> String {
41
        let songids = self
42
            .songids
43
            .iter()
44
            .map(|id| id.to_string())
45
            .collect::<Vec<String>>()
46
            .join(",");
47
        format!("{} {} {}\n", Self::COMMAND, self.prio, songids)
48
    }
49

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

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

            
70
        Self::throw_if_too_many_arguments(parts)?;
71

            
72
        Ok(PrioIdRequest { prio, songids })
73
    }
74
}
75

            
76
empty_command_response!(PrioId);
77

            
78
impl Command for PrioId {
79
    type Request = PrioIdRequest;
80
    type Response = PrioIdResponse;
81
}