commands: use new error variants for various commands
This commit is contained in:
117
src/commands.rs
117
src/commands.rs
@@ -57,11 +57,40 @@ where
|
||||
const COMMAND: &'static str;
|
||||
|
||||
// TODO: add these for ease of throwing parsing errors
|
||||
// /// The minimum number of arguments this command takes
|
||||
// const MIN_ARGS: u32;
|
||||
/// The minimum number of arguments this command takes
|
||||
const MIN_ARGS: u32;
|
||||
|
||||
// /// The maximum number of arguments this command takes
|
||||
// const MAX_ARGS: Option<u32>;
|
||||
/// The maximum number of arguments this command takes
|
||||
const MAX_ARGS: Option<u32>;
|
||||
|
||||
/// Helper function to create a [`RequestParserError::TooManyArguments`] error
|
||||
fn too_many_arguments_error(found: u32) -> RequestParserError {
|
||||
RequestParserError::TooManyArguments {
|
||||
expected_min: Self::MIN_ARGS,
|
||||
expected_max: Self::MAX_ARGS,
|
||||
found,
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to throw a [`RequestParserError::TooManyArguments`] error
|
||||
fn throw_if_too_many_arguments(parts: RequestTokenizer<'_>) -> Result<(), RequestParserError> {
|
||||
let remaining_args = parts.count().try_into().unwrap_or(u32::MAX);
|
||||
if remaining_args != 0 {
|
||||
return Err(Self::too_many_arguments_error(
|
||||
remaining_args.saturating_add(Self::MAX_ARGS.unwrap()),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Helper function to create a [`RequestParserError::MissingArguments`] error
|
||||
fn missing_arguments_error(found: u32) -> RequestParserError {
|
||||
RequestParserError::MissingArguments {
|
||||
expected_min: Self::MIN_ARGS,
|
||||
expected_max: Self::MAX_ARGS,
|
||||
found,
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts this specific request type to it's corresponding variant in the generic Request enum.
|
||||
fn into_request_enum(self) -> crate::Request;
|
||||
@@ -85,9 +114,11 @@ where
|
||||
fn parse_raw(raw: &str) -> Result<Self, RequestParserError> {
|
||||
let (line, rest) = raw
|
||||
.split_once('\n')
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
.ok_or(RequestParserError::MissingNewline)?;
|
||||
|
||||
debug_assert!(rest.is_empty());
|
||||
if line.is_empty() {
|
||||
return Err(RequestParserError::EmptyLine);
|
||||
}
|
||||
|
||||
let mut tokenized = RequestTokenizer::new(line);
|
||||
|
||||
@@ -239,6 +270,8 @@ macro_rules! empty_command_request {
|
||||
|
||||
impl crate::commands::CommandRequest for paste::paste! { [<$name Request>] } {
|
||||
const COMMAND: &'static str = $command_name;
|
||||
const MIN_ARGS: u32 = 0;
|
||||
const MAX_ARGS: Option<u32> = Some(0);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
match Self::COMMAND {
|
||||
@@ -261,19 +294,9 @@ macro_rules! empty_command_request {
|
||||
}
|
||||
|
||||
fn parse(
|
||||
mut parts: crate::commands::RequestTokenizer<'_>,
|
||||
parts: crate::commands::RequestTokenizer<'_>,
|
||||
) -> Result<Self, crate::commands::RequestParserError> {
|
||||
if parts.next().is_some() {
|
||||
return Err(crate::commands::RequestParserError::TooManyArguments {
|
||||
expected_min: 0,
|
||||
expected_max: 0,
|
||||
found: parts
|
||||
.count()
|
||||
.try_into()
|
||||
.unwrap_or(u32::MAX)
|
||||
.saturating_add(1),
|
||||
});
|
||||
}
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(paste::paste! { [<$name Request>] })
|
||||
}
|
||||
@@ -316,6 +339,8 @@ macro_rules! single_item_command_request {
|
||||
|
||||
impl crate::commands::CommandRequest for paste::paste! { [<$name Request>] } {
|
||||
const COMMAND: &'static str = $command_name;
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(1);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
match Self::COMMAND {
|
||||
@@ -340,14 +365,7 @@ macro_rules! single_item_command_request {
|
||||
fn parse(
|
||||
mut parts: crate::commands::RequestTokenizer<'_>,
|
||||
) -> Result<Self, crate::commands::RequestParserError> {
|
||||
let item_token =
|
||||
parts
|
||||
.next()
|
||||
.ok_or(crate::commands::RequestParserError::MissingArguments {
|
||||
expected_min: 1,
|
||||
expected_max: 1,
|
||||
found: 0,
|
||||
})?;
|
||||
let item_token = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
|
||||
let item = item_token.parse::<$item_type>().map_err(|_| {
|
||||
crate::commands::RequestParserError::SubtypeParserError {
|
||||
@@ -357,17 +375,7 @@ macro_rules! single_item_command_request {
|
||||
}
|
||||
})?;
|
||||
|
||||
if parts.next().is_some() {
|
||||
return Err(crate::commands::RequestParserError::TooManyArguments {
|
||||
expected_min: 1,
|
||||
expected_max: 1,
|
||||
found: parts
|
||||
.count()
|
||||
.try_into()
|
||||
.unwrap_or(u32::MAX)
|
||||
.saturating_add(2),
|
||||
});
|
||||
}
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(paste::paste! { [<$name Request>] ( item ) })
|
||||
}
|
||||
@@ -384,6 +392,8 @@ macro_rules! single_optional_item_command_request {
|
||||
|
||||
impl crate::commands::CommandRequest for paste::paste! { [<$name Request>] } {
|
||||
const COMMAND: &'static str = $command_name;
|
||||
const MIN_ARGS: u32 = 0;
|
||||
const MAX_ARGS: Option<u32> = Some(1);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
match Self::COMMAND {
|
||||
@@ -424,18 +434,7 @@ macro_rules! single_optional_item_command_request {
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
if parts.next().is_some() {
|
||||
let item_count = if item.is_some() { 1 } else { 0 };
|
||||
return Err(crate::commands::RequestParserError::TooManyArguments {
|
||||
expected_min: 0,
|
||||
expected_max: 1,
|
||||
found: parts
|
||||
.count()
|
||||
.try_into()
|
||||
.unwrap_or(u32::MAX)
|
||||
.saturating_add(item_count),
|
||||
});
|
||||
}
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(paste::paste! { [<$name Request>] ( item ) })
|
||||
}
|
||||
@@ -550,6 +549,7 @@ pub enum RequestParserError {
|
||||
#[error("Could not parse the request due to a syntax error at position {0}: {1}")]
|
||||
SyntaxError(u64, String),
|
||||
|
||||
// TODO: can we store the parser error as well?
|
||||
#[error(
|
||||
"Could not parse argument {argument_index} of the request (expected type: {expected_type}, raw input: '{raw_input}')"
|
||||
)]
|
||||
@@ -565,28 +565,32 @@ pub enum RequestParserError {
|
||||
},
|
||||
|
||||
#[error(
|
||||
"Too many arguments were provided in the request (expected between {expected_min} and {expected_max}, found {found})"
|
||||
"Too many arguments were provided in the request (expected between {expected_min} and {expected_max:?}, found {found})"
|
||||
)]
|
||||
TooManyArguments {
|
||||
/// The minimum number of arguments that were expected
|
||||
expected_min: u32,
|
||||
|
||||
/// The maximum number of arguments that were expected
|
||||
expected_max: u32,
|
||||
///
|
||||
/// This is `None` if the amount of arguments is unbounded.
|
||||
expected_max: Option<u32>,
|
||||
|
||||
/// The number of arguments that were found
|
||||
found: u32,
|
||||
},
|
||||
|
||||
#[error(
|
||||
"Not enough arguments were provided in the request (expected between {expected_min} and {expected_max}, found {found})"
|
||||
"Not enough arguments were provided in the request (expected between {expected_min} and {expected_max:?}, found {found})"
|
||||
)]
|
||||
MissingArguments {
|
||||
/// The minimum number of arguments that were expected
|
||||
expected_min: u32,
|
||||
|
||||
/// The maximum number of arguments that were expected
|
||||
expected_max: u32,
|
||||
/// The maximum number of arguments that were expected.
|
||||
///
|
||||
/// This is `None` if the amount of arguments is unbounded.
|
||||
expected_max: Option<u32>,
|
||||
|
||||
/// The number of arguments that were found
|
||||
found: u32,
|
||||
@@ -607,8 +611,9 @@ pub enum RequestParserError {
|
||||
// TODO: remove this, replaced by EmptyLine + MissingArguments
|
||||
#[error("Request ended early, while more arguments were expected")]
|
||||
UnexpectedEOF,
|
||||
// #[error("Request is missing terminating newline")]
|
||||
// MissingNewline,
|
||||
|
||||
#[error("Request is missing terminating newline")]
|
||||
MissingNewline,
|
||||
}
|
||||
|
||||
// TODO: should these be renamed to fit the mpd docs?
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct OutputSetRequest {
|
||||
|
||||
impl CommandRequest for OutputSetRequest {
|
||||
const COMMAND: &'static str = "outputset";
|
||||
const MIN_ARGS: u32 = 3;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::OutputSet(self.output_id, self.attribute_name, self.attribute_value)
|
||||
@@ -46,14 +48,18 @@ impl CommandRequest for OutputSetRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let output_id = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let output_id = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let output_id = output_id
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, output_id.to_owned()))?;
|
||||
let attribute_name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let attribute_value = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "AudioOutputId".to_string(),
|
||||
raw_input: output_id.to_string(),
|
||||
})?;
|
||||
let attribute_name = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
let attribute_value = parts.next().ok_or(Self::missing_arguments_error(2))?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(OutputSetRequest {
|
||||
output_id,
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct SendMessageRequest {
|
||||
|
||||
impl CommandRequest for SendMessageRequest {
|
||||
const COMMAND: &'static str = "sendmessage";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = None;
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::SendMessage(self.channel, self.message)
|
||||
@@ -35,16 +37,18 @@ impl CommandRequest for SendMessageRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let channel = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let channel = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let channel = channel
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, channel.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "ChannelName".to_string(),
|
||||
raw_input: channel.to_string(),
|
||||
})?;
|
||||
|
||||
// TODO: SplitWhitespace::remainder() is unstable, use when stable
|
||||
let message = parts.collect::<Vec<_>>().join(" ");
|
||||
|
||||
debug_assert!(!message.is_empty());
|
||||
|
||||
Ok(SendMessageRequest { channel, message })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ pub struct ProtocolDisableRequest(Vec<Feature>);
|
||||
|
||||
impl CommandRequest for ProtocolDisableRequest {
|
||||
const COMMAND: &'static str = "protocol disable";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = None;
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::ProtocolDisable(self.0)
|
||||
@@ -35,16 +37,20 @@ impl CommandRequest for ProtocolDisableRequest {
|
||||
fn parse(parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let mut parts = parts.peekable();
|
||||
if parts.peek().is_none() {
|
||||
return Err(RequestParserError::UnexpectedEOF);
|
||||
return Err(Self::missing_arguments_error(0));
|
||||
}
|
||||
|
||||
let mut features = Vec::with_capacity(parts.size_hint().0);
|
||||
for part in parts {
|
||||
let feature = part
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, part.to_owned()))?;
|
||||
features.push(feature);
|
||||
}
|
||||
let features = parts
|
||||
.enumerate()
|
||||
.map(|(i, f)| {
|
||||
f.parse()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: i.try_into().unwrap_or(u32::MAX),
|
||||
expected_type: "Feature".to_owned(),
|
||||
raw_input: f.to_owned(),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<Feature>, RequestParserError>>()?;
|
||||
|
||||
Ok(ProtocolDisableRequest(features))
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ pub struct ProtocolEnableRequest(Vec<Feature>);
|
||||
|
||||
impl CommandRequest for ProtocolEnableRequest {
|
||||
const COMMAND: &'static str = "protocol enable";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = None;
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::ProtocolEnable(self.0)
|
||||
@@ -35,16 +37,20 @@ impl CommandRequest for ProtocolEnableRequest {
|
||||
fn parse(parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let mut parts = parts.peekable();
|
||||
if parts.peek().is_none() {
|
||||
return Err(RequestParserError::UnexpectedEOF);
|
||||
return Err(Self::missing_arguments_error(0));
|
||||
}
|
||||
|
||||
let mut features = Vec::with_capacity(parts.size_hint().0);
|
||||
for part in parts {
|
||||
let feature = part
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, part.to_owned()))?;
|
||||
features.push(feature);
|
||||
}
|
||||
let features = parts
|
||||
.enumerate()
|
||||
.map(|(i, f)| {
|
||||
f.parse()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: i.try_into().unwrap_or(u32::MAX),
|
||||
expected_type: "Feature".to_owned(),
|
||||
raw_input: f.to_owned(),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<Feature>, RequestParserError>>()?;
|
||||
|
||||
Ok(ProtocolEnableRequest(features))
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::u32;
|
||||
|
||||
use crate::{
|
||||
commands::{Command, CommandRequest, RequestParserError, empty_command_response},
|
||||
request_tokenizer::RequestTokenizer,
|
||||
@@ -10,6 +12,8 @@ pub struct TagTypesDisableRequest(Vec<TagName>);
|
||||
|
||||
impl CommandRequest for TagTypesDisableRequest {
|
||||
const COMMAND: &'static str = "tagtypes disable";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = None;
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::TagTypesDisable(self.0)
|
||||
@@ -37,13 +41,18 @@ impl CommandRequest for TagTypesDisableRequest {
|
||||
fn parse(parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let mut parts = parts.peekable();
|
||||
if parts.peek().is_none() {
|
||||
return Err(RequestParserError::UnexpectedEOF);
|
||||
return Err(Self::missing_arguments_error(0));
|
||||
}
|
||||
|
||||
let tag_types = parts
|
||||
.map(|s| {
|
||||
.enumerate()
|
||||
.map(|(i, s)| {
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, s.to_owned()))
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: i.try_into().unwrap_or(u32::MAX),
|
||||
expected_type: "TagName".to_owned(),
|
||||
raw_input: s.to_owned(),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<TagName>, RequestParserError>>()?;
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ pub struct TagTypesEnableRequest(Vec<TagName>);
|
||||
|
||||
impl CommandRequest for TagTypesEnableRequest {
|
||||
const COMMAND: &'static str = "tagtypes enable";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = None;
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::TagTypesEnable(self.0)
|
||||
@@ -37,13 +39,18 @@ impl CommandRequest for TagTypesEnableRequest {
|
||||
fn parse(parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let mut parts = parts.peekable();
|
||||
if parts.peek().is_none() {
|
||||
return Err(RequestParserError::UnexpectedEOF);
|
||||
return Err(Self::missing_arguments_error(0));
|
||||
}
|
||||
|
||||
let tag_types = parts
|
||||
.map(|s| {
|
||||
.enumerate()
|
||||
.map(|(i, s)| {
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, s.to_owned()))
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: i.try_into().unwrap_or(u32::MAX),
|
||||
expected_type: "TagName".to_owned(),
|
||||
raw_input: s.to_owned(),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<TagName>, RequestParserError>>()?;
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ pub struct TagTypesResetRequest(Vec<TagName>);
|
||||
|
||||
impl CommandRequest for TagTypesResetRequest {
|
||||
const COMMAND: &'static str = "tagtypes reset";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = None;
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::TagTypesReset(self.0)
|
||||
@@ -37,13 +39,18 @@ impl CommandRequest for TagTypesResetRequest {
|
||||
fn parse(parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let mut parts = parts.peekable();
|
||||
if parts.peek().is_none() {
|
||||
return Err(RequestParserError::UnexpectedEOF);
|
||||
return Err(Self::missing_arguments_error(0));
|
||||
}
|
||||
|
||||
let tag_types = parts
|
||||
.map(|s| {
|
||||
.enumerate()
|
||||
.map(|(i, s)| {
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, s.to_owned()))
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: i.try_into().unwrap_or(u32::MAX),
|
||||
expected_type: "TagName".to_owned(),
|
||||
raw_input: s.to_owned(),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<TagName>, RequestParserError>>()?;
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ pub struct PauseRequest(Option<bool>);
|
||||
|
||||
impl CommandRequest for PauseRequest {
|
||||
const COMMAND: &'static str = "pause";
|
||||
const MIN_ARGS: u32 = 0;
|
||||
const MAX_ARGS: Option<u32> = Some(1);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Pause(self.0)
|
||||
@@ -33,11 +35,15 @@ impl CommandRequest for PauseRequest {
|
||||
let result = match parts.next() {
|
||||
Some("0") => Ok(Some(false)),
|
||||
Some("1") => Ok(Some(true)),
|
||||
Some(s) => Err(RequestParserError::SyntaxError(0, s.to_string())),
|
||||
Some(s) => Err(RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "Option<bool>".to_owned(),
|
||||
raw_input: s.to_owned(),
|
||||
}),
|
||||
None => Ok(None),
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
result.map(PauseRequest)
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct SeekRequest {
|
||||
|
||||
impl CommandRequest for SeekRequest {
|
||||
const COMMAND: &'static str = "seek";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Seek(self.songpos, self.time)
|
||||
@@ -34,20 +36,30 @@ impl CommandRequest for SeekRequest {
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let songpos = match parts.next() {
|
||||
Some(s) => s
|
||||
.parse::<SongPosition>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_owned()))?,
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
Some(s) => {
|
||||
s.parse::<SongPosition>()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "SongPosition".to_string(),
|
||||
raw_input: s.to_owned(),
|
||||
})?
|
||||
}
|
||||
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let time = match parts.next() {
|
||||
Some(t) => t
|
||||
.parse::<TimeWithFractions>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, t.to_owned()))?,
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
Some(t) => t.parse::<TimeWithFractions>().map_err(|_| {
|
||||
RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "TimeWithFractions".to_string(),
|
||||
raw_input: t.to_owned(),
|
||||
}
|
||||
})?,
|
||||
None => return Err(Self::missing_arguments_error(1)),
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(SeekRequest { songpos, time })
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct SeekCurRequest {
|
||||
|
||||
impl CommandRequest for SeekCurRequest {
|
||||
const COMMAND: &'static str = "seekcur";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(1);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::SeekCur(self.mode, self.time)
|
||||
@@ -41,29 +43,42 @@ impl CommandRequest for SeekCurRequest {
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let time_raw = match parts.next() {
|
||||
Some(t) => t,
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
// TODO: DRY
|
||||
let (mode, time) = match time_raw {
|
||||
t if t.starts_with('+') => (
|
||||
SeekMode::Relative,
|
||||
t[1..]
|
||||
.parse::<TimeWithFractions>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, t.to_owned()))?,
|
||||
t[1..].parse::<TimeWithFractions>().map_err(|_| {
|
||||
RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "TimeWithFractions".to_string(),
|
||||
raw_input: t[1..].to_owned(),
|
||||
}
|
||||
})?,
|
||||
),
|
||||
t if t.starts_with('-') => (
|
||||
SeekMode::RelativeReverse,
|
||||
t[1..]
|
||||
.parse::<TimeWithFractions>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, t.to_owned()))?,
|
||||
t[1..].parse::<TimeWithFractions>().map_err(|_| {
|
||||
RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "TimeWithFractions".to_string(),
|
||||
raw_input: t[1..].to_owned(),
|
||||
}
|
||||
})?,
|
||||
),
|
||||
t => (
|
||||
SeekMode::Absolute,
|
||||
t.parse::<TimeWithFractions>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, t.to_owned()))?,
|
||||
t.parse::<TimeWithFractions>().map_err(|_| {
|
||||
RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "TimeWithFractions".to_string(),
|
||||
raw_input: t.to_owned(),
|
||||
}
|
||||
})?,
|
||||
),
|
||||
};
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct SeekIdRequest {
|
||||
|
||||
impl CommandRequest for SeekIdRequest {
|
||||
const COMMAND: &'static str = "seekid";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::SeekId(self.songid, self.time)
|
||||
@@ -36,18 +38,26 @@ impl CommandRequest for SeekIdRequest {
|
||||
let songid = match parts.next() {
|
||||
Some(s) => s
|
||||
.parse::<SongId>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_owned()))?,
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "SongId".to_string(),
|
||||
raw_input: s.to_owned(),
|
||||
})?,
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let time = match parts.next() {
|
||||
Some(t) => t
|
||||
.parse::<TimeWithFractions>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, t.to_owned()))?,
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
Some(t) => t.parse::<TimeWithFractions>().map_err(|_| {
|
||||
RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "TimeWithFractions".to_string(),
|
||||
raw_input: t.to_owned(),
|
||||
}
|
||||
})?,
|
||||
None => return Err(Self::missing_arguments_error(1)),
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(SeekIdRequest { songid, time })
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct MountRequest {
|
||||
|
||||
impl CommandRequest for MountRequest {
|
||||
const COMMAND: &'static str = "mount";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Mount(self.path, self.uri)
|
||||
@@ -39,17 +41,21 @@ impl CommandRequest for MountRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let path = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let path = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let path = path
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, path.to_string()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "MountPath".to_string(),
|
||||
raw_input: path.to_string(),
|
||||
})?;
|
||||
|
||||
let uri = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.ok_or(Self::missing_arguments_error(1))?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(MountRequest { path, uri })
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ pub struct UnmountRequest(MountPath);
|
||||
|
||||
impl CommandRequest for UnmountRequest {
|
||||
const COMMAND: &'static str = "unmount";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(1);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Unmount(self.0)
|
||||
@@ -34,14 +36,18 @@ impl CommandRequest for UnmountRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let item_token = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let item = item_token
|
||||
.parse::<MountPath>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, item_token.to_owned()))?;
|
||||
let path = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let path =
|
||||
path.parse::<MountPath>()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "MountPath".to_string(),
|
||||
raw_input: path.to_string(),
|
||||
})?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(UnmountRequest(item))
|
||||
Ok(UnmountRequest(path))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ pub struct AlbumArtRequest {
|
||||
|
||||
impl CommandRequest for AlbumArtRequest {
|
||||
const COMMAND: &'static str = "albumart";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::AlbumArt(self.uri, self.offset)
|
||||
@@ -38,17 +40,21 @@ impl CommandRequest for AlbumArtRequest {
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let uri = match parts.next() {
|
||||
Some(s) => s,
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let offset = match parts.next() {
|
||||
Some(s) => s
|
||||
.parse::<Offset>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, s.to_owned()))?,
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "Offset".to_string(),
|
||||
raw_input: s.to_string(),
|
||||
})?,
|
||||
None => return Err(Self::missing_arguments_error(1)),
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(AlbumArtRequest {
|
||||
uri: uri.to_string(),
|
||||
|
||||
@@ -20,6 +20,8 @@ pub struct CountRequest {
|
||||
|
||||
impl CommandRequest for CountRequest {
|
||||
const COMMAND: &'static str = "count";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Count(self.filter, self.group)
|
||||
@@ -46,22 +48,26 @@ impl CommandRequest for CountRequest {
|
||||
Some(f) => {
|
||||
Filter::parse(f).map_err(|_| RequestParserError::SyntaxError(1, f.to_owned()))?
|
||||
}
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let group = if let Some("group") = parts.next() {
|
||||
let group = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let group = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
|
||||
Some(
|
||||
group
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, group.to_owned()))?,
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "GroupType".to_string(),
|
||||
raw_input: group.to_owned(),
|
||||
})?,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(CountRequest { filter, group })
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ pub struct FindRequest {
|
||||
|
||||
impl CommandRequest for FindRequest {
|
||||
const COMMAND: &'static str = "find";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Find(self.filter, self.sort, self.window)
|
||||
@@ -52,13 +54,13 @@ impl CommandRequest for FindRequest {
|
||||
Some(f) => {
|
||||
Filter::parse(f).map_err(|_| RequestParserError::SyntaxError(1, f.to_owned()))?
|
||||
}
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let mut sort_or_window = parts.next();
|
||||
let mut sort = None;
|
||||
if let Some("sort") = sort_or_window {
|
||||
let s = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let s = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
sort = Some(
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))?,
|
||||
@@ -68,14 +70,14 @@ impl CommandRequest for FindRequest {
|
||||
|
||||
let mut window = None;
|
||||
if let Some("window") = sort_or_window {
|
||||
let w = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let w = parts.next().ok_or(Self::missing_arguments_error(2))?;
|
||||
window = Some(
|
||||
w.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, w.to_string()))?,
|
||||
);
|
||||
}
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(FindRequest {
|
||||
filter,
|
||||
|
||||
@@ -19,6 +19,8 @@ pub struct FindAddRequest {
|
||||
|
||||
impl CommandRequest for FindAddRequest {
|
||||
const COMMAND: &'static str = "findadd";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(4);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::FindAdd(self.filter, self.sort, self.window, self.position)
|
||||
@@ -56,40 +58,52 @@ impl CommandRequest for FindAddRequest {
|
||||
Some(f) => {
|
||||
Filter::parse(f).map_err(|_| RequestParserError::SyntaxError(1, f.to_owned()))?
|
||||
}
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let mut sort_or_window_or_position = parts.next();
|
||||
let mut sort = None;
|
||||
if let Some("sort") = sort_or_window_or_position {
|
||||
let s = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let s = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
sort = Some(
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))?,
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "Sort".to_string(),
|
||||
raw_input: s.to_owned(),
|
||||
})?,
|
||||
);
|
||||
sort_or_window_or_position = parts.next();
|
||||
}
|
||||
|
||||
let mut window = None;
|
||||
if let Some("window") = sort_or_window_or_position {
|
||||
let w = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let w = parts.next().ok_or(Self::missing_arguments_error(2))?;
|
||||
window = Some(
|
||||
w.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, w.to_string()))?,
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 2,
|
||||
expected_type: "WindowRange".to_string(),
|
||||
raw_input: w.to_owned(),
|
||||
})?,
|
||||
);
|
||||
sort_or_window_or_position = parts.next();
|
||||
}
|
||||
|
||||
let mut position = None;
|
||||
if let Some("position") = sort_or_window_or_position {
|
||||
let p = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let p = parts.next().ok_or(Self::missing_arguments_error(3))?;
|
||||
position = Some(
|
||||
p.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, p.to_string()))?,
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 3,
|
||||
expected_type: "SongPosition".to_string(),
|
||||
raw_input: p.to_owned(),
|
||||
})?,
|
||||
);
|
||||
}
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(FindAddRequest {
|
||||
filter,
|
||||
|
||||
@@ -20,6 +20,8 @@ pub struct ListRequest {
|
||||
|
||||
impl CommandRequest for ListRequest {
|
||||
const COMMAND: &'static str = "list";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = None;
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::List(self.tagname, self.filter, self.groups, self.window)
|
||||
@@ -53,10 +55,14 @@ impl CommandRequest for ListRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let tagname = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let tagname = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let tagname = tagname
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, tagname.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "TagName".to_string(),
|
||||
raw_input: tagname.to_owned(),
|
||||
})?;
|
||||
|
||||
let mut filter = None;
|
||||
let mut groups = Vec::new();
|
||||
@@ -77,10 +83,15 @@ impl CommandRequest for ListRequest {
|
||||
while let Some(g) = next
|
||||
&& g == "group"
|
||||
{
|
||||
let group = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let parsed_group = group
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, group.to_owned()))?;
|
||||
let group = parts.next().ok_or(Self::missing_arguments_error(2))?;
|
||||
let parsed_group =
|
||||
group
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 2,
|
||||
expected_type: "GroupType".to_string(),
|
||||
raw_input: group.to_owned(),
|
||||
})?;
|
||||
groups.push(parsed_group);
|
||||
next = parts.next();
|
||||
}
|
||||
@@ -88,14 +99,19 @@ impl CommandRequest for ListRequest {
|
||||
if let Some(w) = next
|
||||
&& w == "window"
|
||||
{
|
||||
let window_str = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let parsed_window = window_str
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, window_str.to_owned()))?;
|
||||
let window_str = parts.next().ok_or(Self::missing_arguments_error(3))?;
|
||||
let parsed_window =
|
||||
window_str
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 3,
|
||||
expected_type: "WindowRange".to_string(),
|
||||
raw_input: window_str.to_owned(),
|
||||
})?;
|
||||
window = Some(parsed_window);
|
||||
}
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(ListRequest {
|
||||
tagname,
|
||||
|
||||
@@ -21,6 +21,8 @@ pub struct ReadPictureRequest {
|
||||
|
||||
impl CommandRequest for ReadPictureRequest {
|
||||
const COMMAND: &'static str = "readpicture";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::ReadPicture(self.uri, self.offset)
|
||||
@@ -40,17 +42,21 @@ impl CommandRequest for ReadPictureRequest {
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let uri = match parts.next() {
|
||||
Some(s) => s,
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let offset = match parts.next() {
|
||||
Some(s) => s
|
||||
.parse::<Offset>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, s.to_owned()))?,
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "Offset".to_string(),
|
||||
raw_input: s.to_owned(),
|
||||
})?,
|
||||
None => return Err(Self::missing_arguments_error(1)),
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(ReadPictureRequest {
|
||||
uri: uri.to_string(),
|
||||
|
||||
@@ -19,6 +19,8 @@ pub struct SearchRequest {
|
||||
|
||||
impl CommandRequest for SearchRequest {
|
||||
const COMMAND: &'static str = "search";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Search(self.filter, self.sort, self.window)
|
||||
@@ -52,13 +54,13 @@ impl CommandRequest for SearchRequest {
|
||||
Some(f) => {
|
||||
Filter::parse(f).map_err(|_| RequestParserError::SyntaxError(1, f.to_owned()))?
|
||||
}
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let mut sort_or_window = parts.next();
|
||||
let mut sort = None;
|
||||
if let Some("sort") = sort_or_window {
|
||||
let s = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let s = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
sort = Some(
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))?,
|
||||
@@ -75,7 +77,7 @@ impl CommandRequest for SearchRequest {
|
||||
);
|
||||
}
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(SearchRequest {
|
||||
filter,
|
||||
|
||||
@@ -19,6 +19,8 @@ pub struct SearchAddRequest {
|
||||
|
||||
impl CommandRequest for SearchAddRequest {
|
||||
const COMMAND: &'static str = "searchadd";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(4);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::SearchAdd(self.filter, self.sort, self.window, self.position)
|
||||
@@ -56,7 +58,7 @@ impl CommandRequest for SearchAddRequest {
|
||||
Some(f) => {
|
||||
Filter::parse(f).map_err(|_| RequestParserError::SyntaxError(1, f.to_owned()))?
|
||||
}
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let mut sort_or_window_or_position = parts.next();
|
||||
@@ -89,7 +91,7 @@ impl CommandRequest for SearchAddRequest {
|
||||
);
|
||||
}
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(SearchAddRequest {
|
||||
filter,
|
||||
|
||||
@@ -20,6 +20,8 @@ pub struct SearchAddPlRequest {
|
||||
|
||||
impl CommandRequest for SearchAddPlRequest {
|
||||
const COMMAND: &'static str = "searchaddpl";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(5);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::SearchAddPl(
|
||||
@@ -104,7 +106,7 @@ impl CommandRequest for SearchAddPlRequest {
|
||||
);
|
||||
}
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(SearchAddPlRequest {
|
||||
playlist_name,
|
||||
|
||||
@@ -20,6 +20,8 @@ pub struct SearchCountRequest {
|
||||
|
||||
impl CommandRequest for SearchCountRequest {
|
||||
const COMMAND: &'static str = "searchcount";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::SearchCount(self.filter, self.group)
|
||||
@@ -48,7 +50,7 @@ impl CommandRequest for SearchCountRequest {
|
||||
Some(f) => {
|
||||
Filter::parse(f).map_err(|_| RequestParserError::SyntaxError(1, f.to_owned()))?
|
||||
}
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let group = if let Some("group") = parts.next() {
|
||||
@@ -62,7 +64,7 @@ impl CommandRequest for SearchCountRequest {
|
||||
None
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(SearchCountRequest { filter, group })
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ pub struct RandomRequest(bool);
|
||||
|
||||
impl CommandRequest for RandomRequest {
|
||||
const COMMAND: &'static str = "random";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(1);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Random(self.0)
|
||||
@@ -30,11 +32,17 @@ impl CommandRequest for RandomRequest {
|
||||
let state = match parts.next() {
|
||||
Some("0") => false,
|
||||
Some("1") => true,
|
||||
Some(s) => return Err(RequestParserError::SyntaxError(0, s.to_owned())),
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
Some(s) => {
|
||||
return Err(RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "bool".to_owned(),
|
||||
raw_input: s.to_owned(),
|
||||
});
|
||||
}
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(RandomRequest(state))
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ pub struct RepeatRequest(bool);
|
||||
|
||||
impl CommandRequest for RepeatRequest {
|
||||
const COMMAND: &'static str = "repeat";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(1);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Repeat(self.0)
|
||||
@@ -30,11 +32,17 @@ impl CommandRequest for RepeatRequest {
|
||||
let state = match parts.next() {
|
||||
Some("0") => false,
|
||||
Some("1") => true,
|
||||
Some(s) => return Err(RequestParserError::SyntaxError(0, s.to_owned())),
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
Some(s) => {
|
||||
return Err(RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "bool".to_owned(),
|
||||
raw_input: s.to_owned(),
|
||||
});
|
||||
}
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(RepeatRequest(state))
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ pub struct IdleRequest(Option<Vec<SubSystem>>);
|
||||
|
||||
impl CommandRequest for IdleRequest {
|
||||
const COMMAND: &'static str = "idle";
|
||||
const MIN_ARGS: u32 = 0;
|
||||
const MAX_ARGS: Option<u32> = None;
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Idle(self.0)
|
||||
@@ -48,8 +50,6 @@ impl CommandRequest for IdleRequest {
|
||||
Ok(Some(subsystems))
|
||||
});
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
result.map(IdleRequest)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct AddRequest {
|
||||
|
||||
impl CommandRequest for AddRequest {
|
||||
const COMMAND: &'static str = "add";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Add(self.uri, self.position)
|
||||
@@ -38,18 +40,21 @@ impl CommandRequest for AddRequest {
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let uri = match parts.next() {
|
||||
Some(s) => s,
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let position = match parts.next() {
|
||||
Some(s) => Some(
|
||||
s.parse::<SongPosition>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, s.to_owned()))?,
|
||||
),
|
||||
Some(s) => Some(s.parse::<SongPosition>().map_err(|_| {
|
||||
RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "SongPosition".to_string(),
|
||||
raw_input: s.to_owned(),
|
||||
}
|
||||
})?),
|
||||
None => None,
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(AddRequest {
|
||||
uri: uri.to_string(),
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct AddIdRequest {
|
||||
|
||||
impl CommandRequest for AddIdRequest {
|
||||
const COMMAND: &'static str = "addid";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::AddId(self.uri, self.position)
|
||||
@@ -39,18 +41,21 @@ impl CommandRequest for AddIdRequest {
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let uri = match parts.next() {
|
||||
Some(s) => s,
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let position = match parts.next() {
|
||||
Some(s) => Some(
|
||||
s.parse::<SongPosition>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, s.to_owned()))?,
|
||||
),
|
||||
Some(s) => Some(s.parse::<SongPosition>().map_err(|_| {
|
||||
RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "SongPosition".to_string(),
|
||||
raw_input: s.to_owned(),
|
||||
}
|
||||
})?),
|
||||
None => None,
|
||||
};
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(AddIdRequest {
|
||||
uri: uri.to_string(),
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct AddTagIdRequest {
|
||||
|
||||
impl CommandRequest for AddTagIdRequest {
|
||||
const COMMAND: &'static str = "addtagid";
|
||||
const MIN_ARGS: u32 = 3;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::AddTagId(self.songid, self.tag_name, self.tag_value)
|
||||
@@ -44,22 +46,34 @@ impl CommandRequest for AddTagIdRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let songid = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let songid = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let songid = songid
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, songid.to_string()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "SongId".to_string(),
|
||||
raw_input: songid.to_owned(),
|
||||
})?;
|
||||
|
||||
let tag_name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let tag_name = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
let tag_name = tag_name
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, tag_name.to_string()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "TagName".to_string(),
|
||||
raw_input: tag_name.to_owned(),
|
||||
})?;
|
||||
|
||||
let tag_value = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let tag_value = parts.next().ok_or(Self::missing_arguments_error(2))?;
|
||||
let tag_value = tag_value
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, tag_value.to_string()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 2,
|
||||
expected_type: "TagValue".to_string(),
|
||||
raw_input: tag_value.to_owned(),
|
||||
})?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(AddTagIdRequest {
|
||||
songid,
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct ClearTagIdRequest {
|
||||
|
||||
impl CommandRequest for ClearTagIdRequest {
|
||||
const COMMAND: &'static str = "cleartagid";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::ClearTagId(self.songid, self.tag_name)
|
||||
@@ -35,17 +37,25 @@ impl CommandRequest for ClearTagIdRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let songid = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let songid = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let songid = songid
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, songid.to_string()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "SongId".to_string(),
|
||||
raw_input: songid.to_string(),
|
||||
})?;
|
||||
|
||||
let tag_name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let tag_name = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
let tag_name = tag_name
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, tag_name.to_string()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "TagName".to_string(),
|
||||
raw_input: tag_name.to_string(),
|
||||
})?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(ClearTagIdRequest { songid, tag_name })
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct MoveRequest {
|
||||
|
||||
impl CommandRequest for MoveRequest {
|
||||
const COMMAND: &'static str = "move";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Move(self.from_or_range, self.to)
|
||||
@@ -43,7 +45,7 @@ impl CommandRequest for MoveRequest {
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, to.to_string()))?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(MoveRequest { from_or_range, to })
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct MoveIdRequest {
|
||||
|
||||
impl CommandRequest for MoveIdRequest {
|
||||
const COMMAND: &'static str = "moveid";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::MoveId(self.id, self.to)
|
||||
@@ -43,7 +45,7 @@ impl CommandRequest for MoveIdRequest {
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, to.to_string()))?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(MoveIdRequest { id, to })
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ pub struct PlaylistFindRequest {
|
||||
|
||||
impl CommandRequest for PlaylistFindRequest {
|
||||
const COMMAND: &'static str = "playlistfind";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::PlaylistFind(self.filter, self.sort, self.window)
|
||||
@@ -53,7 +55,7 @@ impl CommandRequest for PlaylistFindRequest {
|
||||
Some(f) => {
|
||||
Filter::parse(f).map_err(|_| RequestParserError::SyntaxError(1, f.to_owned()))?
|
||||
}
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let mut sort_or_window = parts.next();
|
||||
@@ -76,7 +78,7 @@ impl CommandRequest for PlaylistFindRequest {
|
||||
);
|
||||
}
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(PlaylistFindRequest {
|
||||
filter,
|
||||
|
||||
@@ -19,6 +19,8 @@ pub struct PlaylistSearchRequest {
|
||||
|
||||
impl CommandRequest for PlaylistSearchRequest {
|
||||
const COMMAND: &'static str = "playlistsearch";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::PlaylistSearch(self.filter, self.sort, self.window)
|
||||
@@ -52,7 +54,7 @@ impl CommandRequest for PlaylistSearchRequest {
|
||||
Some(f) => {
|
||||
Filter::parse(f).map_err(|_| RequestParserError::SyntaxError(1, f.to_owned()))?
|
||||
}
|
||||
None => return Err(RequestParserError::UnexpectedEOF),
|
||||
None => return Err(Self::missing_arguments_error(0)),
|
||||
};
|
||||
|
||||
let mut sort_or_window = parts.next();
|
||||
@@ -75,7 +77,7 @@ impl CommandRequest for PlaylistSearchRequest {
|
||||
);
|
||||
}
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(PlaylistSearchRequest {
|
||||
filter,
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct PlChangesRequest {
|
||||
|
||||
impl CommandRequest for PlChangesRequest {
|
||||
const COMMAND: &'static str = "plchanges";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::PlChanges(self.version, self.window)
|
||||
@@ -52,7 +54,7 @@ impl CommandRequest for PlChangesRequest {
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(PlChangesRequest { version, window })
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct PlChangesPosIdRequest {
|
||||
|
||||
impl CommandRequest for PlChangesPosIdRequest {
|
||||
const COMMAND: &'static str = "plchangesposid";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::PlChangesPosId(self.version, self.window)
|
||||
@@ -52,7 +54,7 @@ impl CommandRequest for PlChangesPosIdRequest {
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(PlChangesPosIdRequest { version, window })
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct PrioRequest {
|
||||
|
||||
impl CommandRequest for PrioRequest {
|
||||
const COMMAND: &'static str = "prio";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Prio(self.prio, self.window)
|
||||
@@ -43,7 +45,7 @@ impl CommandRequest for PrioRequest {
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, window.to_string()))?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(PrioRequest { prio, window })
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ pub struct PrioIdRequest {
|
||||
|
||||
impl CommandRequest for PrioIdRequest {
|
||||
const COMMAND: &'static str = "prioid";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
// TODO: should this be 2?
|
||||
const MAX_ARGS: Option<u32> = None;
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::PrioId(self.prio, self.songids)
|
||||
@@ -53,7 +56,7 @@ impl CommandRequest for PrioIdRequest {
|
||||
})
|
||||
.collect::<Result<Vec<SongId>, RequestParserError>>()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(PrioIdRequest { prio, songids })
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct RangeIdRequest {
|
||||
|
||||
impl CommandRequest for RangeIdRequest {
|
||||
const COMMAND: &'static str = "rangeid";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::RangeId(self.songid, self.time_interval)
|
||||
@@ -46,7 +48,7 @@ impl CommandRequest for RangeIdRequest {
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, time_interval.to_string()))?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(RangeIdRequest {
|
||||
songid,
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct SwapRequest {
|
||||
|
||||
impl CommandRequest for SwapRequest {
|
||||
const COMMAND: &'static str = "swap";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Swap(self.songpos1, self.songpos2)
|
||||
@@ -43,7 +45,7 @@ impl CommandRequest for SwapRequest {
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, songpos2.to_string()))?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(SwapRequest { songpos1, songpos2 })
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct SwapIdRequest {
|
||||
|
||||
impl CommandRequest for SwapIdRequest {
|
||||
const COMMAND: &'static str = "swapid";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::SwapId(self.songid1, self.songid2)
|
||||
@@ -43,7 +45,7 @@ impl CommandRequest for SwapIdRequest {
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, songid2.to_string()))?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(SwapIdRequest { songid1, songid2 })
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ pub struct StickerDecRequest {
|
||||
|
||||
impl CommandRequest for StickerDecRequest {
|
||||
const COMMAND: &'static str = "sticker dec";
|
||||
const MIN_ARGS: u32 = 4;
|
||||
const MAX_ARGS: Option<u32> = Some(4);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::StickerDec(self.sticker_type, self.uri, self.name, self.value)
|
||||
@@ -47,27 +49,40 @@ impl CommandRequest for StickerDecRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let sticker_type = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let sticker_type = sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, sticker_type.to_owned()))?;
|
||||
let sticker_type = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let sticker_type =
|
||||
sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "StickerType".to_string(),
|
||||
raw_input: sticker_type.to_string(),
|
||||
})?;
|
||||
|
||||
let uri = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let uri = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
let uri = uri
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, uri.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "Uri".to_string(),
|
||||
raw_input: uri.to_string(),
|
||||
})?;
|
||||
|
||||
let name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let name = parts.next().ok_or(Self::missing_arguments_error(2))?;
|
||||
let name = name
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, name.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 2,
|
||||
expected_type: "String".to_string(),
|
||||
raw_input: name.to_string(),
|
||||
})?;
|
||||
|
||||
let value = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let value = value
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, value.to_owned()))?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(StickerDecRequest {
|
||||
sticker_type,
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct StickerDeleteRequest {
|
||||
|
||||
impl CommandRequest for StickerDeleteRequest {
|
||||
const COMMAND: &'static str = "sticker delete";
|
||||
const MIN_ARGS: u32 = 3;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::StickerDelete(self.sticker_type, self.uri, self.name)
|
||||
@@ -44,22 +46,35 @@ impl CommandRequest for StickerDeleteRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let sticker_type = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let sticker_type = sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, sticker_type.to_owned()))?;
|
||||
let sticker_type = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let sticker_type =
|
||||
sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "StickerType".to_string(),
|
||||
raw_input: sticker_type.to_string(),
|
||||
})?;
|
||||
|
||||
let uri = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let uri = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
let uri = uri
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, uri.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "Uri".to_string(),
|
||||
raw_input: uri.to_string(),
|
||||
})?;
|
||||
|
||||
let name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let name = parts.next().ok_or(Self::missing_arguments_error(2))?;
|
||||
let name = name
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, name.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 2,
|
||||
expected_type: "String".to_string(),
|
||||
raw_input: name.to_string(),
|
||||
})?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(StickerDeleteRequest {
|
||||
sticker_type,
|
||||
|
||||
@@ -20,6 +20,8 @@ pub struct StickerFindRequest {
|
||||
|
||||
impl CommandRequest for StickerFindRequest {
|
||||
const COMMAND: &'static str = "sticker find";
|
||||
const MIN_ARGS: u32 = 3;
|
||||
const MAX_ARGS: Option<u32> = Some(5);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::StickerFind(
|
||||
@@ -65,20 +67,33 @@ impl CommandRequest for StickerFindRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let sticker_type = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let sticker_type = sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, sticker_type.to_owned()))?;
|
||||
let sticker_type = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let sticker_type =
|
||||
sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "StickerType".to_string(),
|
||||
raw_input: sticker_type.to_string(),
|
||||
})?;
|
||||
|
||||
let uri = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let uri = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
let uri = uri
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, uri.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "Uri".to_string(),
|
||||
raw_input: uri.to_string(),
|
||||
})?;
|
||||
|
||||
let name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let name = parts.next().ok_or(Self::missing_arguments_error(2))?;
|
||||
let name = name
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, name.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 2,
|
||||
expected_type: "String".to_string(),
|
||||
raw_input: name.to_string(),
|
||||
})?;
|
||||
|
||||
let mut sort_or_window = parts.next();
|
||||
let mut sort = None;
|
||||
@@ -100,7 +115,7 @@ impl CommandRequest for StickerFindRequest {
|
||||
);
|
||||
}
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(StickerFindRequest {
|
||||
sticker_type,
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct StickerGetRequest {
|
||||
|
||||
impl CommandRequest for StickerGetRequest {
|
||||
const COMMAND: &'static str = "sticker get";
|
||||
const MIN_ARGS: u32 = 3;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::StickerGet(self.sticker_type, self.uri, self.name)
|
||||
@@ -44,22 +46,35 @@ impl CommandRequest for StickerGetRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let sticker_type = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let sticker_type = sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, sticker_type.to_owned()))?;
|
||||
let sticker_type = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let sticker_type =
|
||||
sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "StickerType".to_string(),
|
||||
raw_input: sticker_type.to_string(),
|
||||
})?;
|
||||
|
||||
let uri = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let uri = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
let uri = uri
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, uri.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "Uri".to_string(),
|
||||
raw_input: uri.to_string(),
|
||||
})?;
|
||||
|
||||
let name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let name = parts.next().ok_or(Self::missing_arguments_error(2))?;
|
||||
let name = name
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, name.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 2,
|
||||
expected_type: "String".to_string(),
|
||||
raw_input: name.to_string(),
|
||||
})?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(StickerGetRequest {
|
||||
sticker_type,
|
||||
|
||||
@@ -18,6 +18,8 @@ pub struct StickerIncRequest {
|
||||
|
||||
impl CommandRequest for StickerIncRequest {
|
||||
const COMMAND: &'static str = "sticker inc";
|
||||
const MIN_ARGS: u32 = 4;
|
||||
const MAX_ARGS: Option<u32> = Some(4);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::StickerInc(self.sticker_type, self.uri, self.name, self.value)
|
||||
@@ -47,27 +49,40 @@ impl CommandRequest for StickerIncRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let sticker_type = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let sticker_type = sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, sticker_type.to_owned()))?;
|
||||
let sticker_type = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let sticker_type =
|
||||
sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "StickerType".to_string(),
|
||||
raw_input: sticker_type.to_string(),
|
||||
})?;
|
||||
|
||||
let uri = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let uri = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
let uri = uri
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, uri.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "Uri".to_string(),
|
||||
raw_input: uri.to_string(),
|
||||
})?;
|
||||
|
||||
let name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let name = parts.next().ok_or(Self::missing_arguments_error(2))?;
|
||||
let name = name
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, name.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 2,
|
||||
expected_type: "String".to_string(),
|
||||
raw_input: name.to_string(),
|
||||
})?;
|
||||
|
||||
let value = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let value = value
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, value.to_owned()))?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(StickerIncRequest {
|
||||
sticker_type,
|
||||
|
||||
@@ -19,6 +19,8 @@ pub struct StickerListRequest {
|
||||
|
||||
impl CommandRequest for StickerListRequest {
|
||||
const COMMAND: &'static str = "sticker list";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::StickerList(self.sticker_type, self.uri)
|
||||
@@ -38,17 +40,26 @@ impl CommandRequest for StickerListRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let sticker_type = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let sticker_type = sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, sticker_type.to_owned()))?;
|
||||
let sticker_type = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let sticker_type =
|
||||
sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "StickerType".to_string(),
|
||||
raw_input: sticker_type.to_string(),
|
||||
})?;
|
||||
|
||||
let uri = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let uri = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
let uri = uri
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(1, uri.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "Uri".to_string(),
|
||||
raw_input: uri.to_string(),
|
||||
})?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(StickerListRequest { sticker_type, uri })
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ pub struct StickerSetRequest {
|
||||
|
||||
impl CommandRequest for StickerSetRequest {
|
||||
const COMMAND: &'static str = "sticker set";
|
||||
const MIN_ARGS: u32 = 4;
|
||||
const MAX_ARGS: Option<u32> = Some(4);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::StickerSet(self.sticker_type, self.uri, self.name, self.value)
|
||||
@@ -47,24 +49,37 @@ impl CommandRequest for StickerSetRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let sticker_type = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let sticker_type = sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, sticker_type.to_owned()))?;
|
||||
let sticker_type = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let sticker_type =
|
||||
sticker_type
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 0,
|
||||
expected_type: "StickerType".to_string(),
|
||||
raw_input: sticker_type.to_string(),
|
||||
})?;
|
||||
|
||||
let uri = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let uri = parts.next().ok_or(Self::missing_arguments_error(1))?;
|
||||
let uri = uri
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, uri.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 1,
|
||||
expected_type: "Uri".to_string(),
|
||||
raw_input: uri.to_string(),
|
||||
})?;
|
||||
|
||||
let name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let name = parts.next().ok_or(Self::missing_arguments_error(2))?;
|
||||
let name = name
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, name.to_owned()))?;
|
||||
.map_err(|_| RequestParserError::SubtypeParserError {
|
||||
argument_index: 2,
|
||||
expected_type: "String".to_string(),
|
||||
raw_input: name.to_string(),
|
||||
})?;
|
||||
|
||||
let value = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(StickerSetRequest {
|
||||
sticker_type,
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct StickerNamesTypesRequest(Option<StickerType>);
|
||||
|
||||
impl CommandRequest for StickerNamesTypesRequest {
|
||||
const COMMAND: &'static str = "stickernamestypes";
|
||||
const MIN_ARGS: u32 = 0;
|
||||
const MAX_ARGS: Option<u32> = Some(1);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::StickerNamesTypes(self.0)
|
||||
@@ -48,7 +50,7 @@ impl CommandRequest for StickerNamesTypesRequest {
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(StickerNamesTypesRequest(sticker_type))
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ pub struct ListPlaylistRequest {
|
||||
|
||||
impl CommandRequest for ListPlaylistRequest {
|
||||
const COMMAND: &'static str = "listplaylist";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::ListPlaylist(self.name, self.range)
|
||||
@@ -56,7 +58,7 @@ impl CommandRequest for ListPlaylistRequest {
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(ListPlaylistRequest { name, range })
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct ListPlaylistInfoRequest {
|
||||
|
||||
impl CommandRequest for ListPlaylistInfoRequest {
|
||||
const COMMAND: &'static str = "listplaylistinfo";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::ListPlaylistInfo(self.name, self.range)
|
||||
@@ -52,7 +54,7 @@ impl CommandRequest for ListPlaylistInfoRequest {
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(ListPlaylistInfoRequest { name, range })
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct LoadRequest {
|
||||
|
||||
impl CommandRequest for LoadRequest {
|
||||
const COMMAND: &'static str = "load";
|
||||
const MIN_ARGS: u32 = 1;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Load(self.name, self.range, self.position)
|
||||
@@ -53,7 +55,7 @@ impl CommandRequest for LoadRequest {
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.ok_or(Self::missing_arguments_error(0))?
|
||||
.to_string();
|
||||
|
||||
let mut range = None;
|
||||
@@ -73,7 +75,7 @@ impl CommandRequest for LoadRequest {
|
||||
}
|
||||
}
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(LoadRequest {
|
||||
name: playlist_name,
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct PlaylistAddRequest {
|
||||
|
||||
impl CommandRequest for PlaylistAddRequest {
|
||||
const COMMAND: &'static str = "playlistadd";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::PlaylistAdd(self.playlist_name, self.uri, self.position)
|
||||
@@ -53,12 +55,12 @@ impl CommandRequest for PlaylistAddRequest {
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.ok_or(Self::missing_arguments_error(0))?
|
||||
.to_string();
|
||||
|
||||
let uri = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.ok_or(Self::missing_arguments_error(1))?
|
||||
.to_string();
|
||||
|
||||
let position = parts
|
||||
@@ -69,7 +71,7 @@ impl CommandRequest for PlaylistAddRequest {
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(PlaylistAddRequest {
|
||||
playlist_name,
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct PlaylistDeleteRequest {
|
||||
|
||||
impl CommandRequest for PlaylistDeleteRequest {
|
||||
const COMMAND: &'static str = "playlistdelete";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::PlaylistDelete(self.playlist_name, self.position)
|
||||
@@ -45,7 +47,7 @@ impl CommandRequest for PlaylistDeleteRequest {
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.ok_or(Self::missing_arguments_error(0))?
|
||||
.to_string();
|
||||
|
||||
// TODO: this can be a range, according to docs
|
||||
@@ -54,7 +56,7 @@ impl CommandRequest for PlaylistDeleteRequest {
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, position.to_string()))?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(PlaylistDeleteRequest {
|
||||
playlist_name,
|
||||
|
||||
@@ -17,6 +17,8 @@ pub struct PlaylistMoveRequest {
|
||||
|
||||
impl CommandRequest for PlaylistMoveRequest {
|
||||
const COMMAND: &'static str = "playlistmove";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::PlaylistMove(self.playlist_name, self.from, self.to)
|
||||
@@ -53,7 +55,7 @@ impl CommandRequest for PlaylistMoveRequest {
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.ok_or(Self::missing_arguments_error(0))?
|
||||
.to_string();
|
||||
|
||||
let mut from = None;
|
||||
@@ -61,7 +63,7 @@ impl CommandRequest for PlaylistMoveRequest {
|
||||
|
||||
let to = parts.next();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
let to = if let Some(to) = to {
|
||||
from = Some(from_or_range_or_to.parse().map_err(|_| {
|
||||
|
||||
@@ -15,6 +15,8 @@ pub struct RenameRequest {
|
||||
|
||||
impl CommandRequest for RenameRequest {
|
||||
const COMMAND: &'static str = "rename";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(2);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Rename(self.old_name, self.new_name)
|
||||
@@ -36,15 +38,15 @@ impl CommandRequest for RenameRequest {
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let old_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.ok_or(Self::missing_arguments_error(0))?
|
||||
.to_string();
|
||||
|
||||
let new_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.ok_or(Self::missing_arguments_error(1))?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(RenameRequest { old_name, new_name })
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ pub struct SaveRequest {
|
||||
|
||||
impl CommandRequest for SaveRequest {
|
||||
const COMMAND: &'static str = "save";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::Save(self.playlist_name, self.mode)
|
||||
@@ -45,7 +47,7 @@ impl CommandRequest for SaveRequest {
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.ok_or(Self::missing_arguments_error(0))?
|
||||
.to_string();
|
||||
|
||||
let mode = parts
|
||||
@@ -56,7 +58,7 @@ impl CommandRequest for SaveRequest {
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(SaveRequest {
|
||||
playlist_name,
|
||||
|
||||
@@ -18,6 +18,8 @@ pub struct SearchPlaylistRequest {
|
||||
|
||||
impl CommandRequest for SearchPlaylistRequest {
|
||||
const COMMAND: &'static str = "searchplaylist";
|
||||
const MIN_ARGS: u32 = 2;
|
||||
const MAX_ARGS: Option<u32> = Some(3);
|
||||
|
||||
fn into_request_enum(self) -> crate::Request {
|
||||
crate::Request::SearchPlaylist(self.name, self.filter, self.range)
|
||||
@@ -44,7 +46,7 @@ impl CommandRequest for SearchPlaylistRequest {
|
||||
}
|
||||
|
||||
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
|
||||
let name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let name = parts.next().ok_or(Self::missing_arguments_error(0))?;
|
||||
let name = name
|
||||
.parse::<PlaylistName>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, name.to_owned()))?;
|
||||
@@ -64,7 +66,7 @@ impl CommandRequest for SearchPlaylistRequest {
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
Self::throw_if_too_many_arguments(parts)?;
|
||||
|
||||
Ok(SearchPlaylistRequest {
|
||||
name,
|
||||
|
||||
Reference in New Issue
Block a user