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

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

            
9
pub struct Move;
10

            
11
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12
pub struct MoveRequest {
13
    pub from_or_range: OneOrRange,
14
    pub to: AbsouluteRelativeSongPosition,
15
}
16

            
17
impl MoveRequest {
18
    pub fn new(from_or_range: OneOrRange, to: AbsouluteRelativeSongPosition) -> Self {
19
        Self { from_or_range, to }
20
    }
21
}
22

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

            
28
    fn into_request_enum(self) -> crate::Request {
29
        crate::Request::Move(self.from_or_range, self.to)
30
    }
31

            
32
    fn from_request_enum(request: crate::Request) -> Option<Self> {
33
        match request {
34
            crate::Request::Move(from_or_range, to) => Some(MoveRequest { from_or_range, to }),
35
            _ => None,
36
        }
37
    }
38

            
39
    fn serialize(&self) -> String {
40
        format!("{} {} {}\n", Self::COMMAND, self.from_or_range, self.to)
41
    }
42

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

            
54
        let to = parts.next().ok_or(Self::missing_arguments_error(1))?;
55
        let to = to
56
            .parse()
57
            .map_err(|_| RequestParserError::SubtypeParserError {
58
                argument_index: 1,
59
                expected_type: "AbsoluteRelativeSongPosition",
60
                raw_input: to.to_string(),
61
            })?;
62

            
63
        Self::throw_if_too_many_arguments(parts)?;
64

            
65
        Ok(MoveRequest { from_or_range, to })
66
    }
67
}
68

            
69
empty_command_response!(Move);
70

            
71
impl Command for Move {
72
    type Request = MoveRequest;
73
    type Response = MoveResponse;
74
}