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 serialize(&self) -> String {
30
        let songids = self
31
            .songids
32
            .iter()
33
            .map(|id| id.to_string())
34
            .collect::<Vec<String>>()
35
            .join(",");
36
        format!("{} {} {}\n", Self::COMMAND, self.prio, songids)
37
    }
38

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

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

            
59
        Self::throw_if_too_many_arguments(parts)?;
60

            
61
        Ok(PrioIdRequest { prio, songids })
62
    }
63
}
64

            
65
empty_command_response!(PrioId);
66

            
67
impl Command for PrioId {
68
    type Request = PrioIdRequest;
69
    type Response = PrioIdResponse;
70
}