commands: use new error variants for various commands

This commit is contained in:
2025-12-08 15:54:37 +09:00
parent 7863b166a1
commit 3c8cd670d3
59 changed files with 653 additions and 296 deletions

View File

@@ -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(),

View File

@@ -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(),

View File

@@ -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,

View File

@@ -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 })
}

View File

@@ -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 })
}

View File

@@ -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 })
}

View File

@@ -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,

View File

@@ -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,

View File

@@ -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 })
}

View File

@@ -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 })
}

View File

@@ -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 })
}

View File

@@ -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 })
}

View File

@@ -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,

View File

@@ -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 })
}

View File

@@ -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 })
}