commands: fix request de/serialization for list

This commit is contained in:
2025-11-24 22:00:42 +09:00
parent a4276a2caa
commit 5188809327
2 changed files with 48 additions and 23 deletions

View File

@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
use crate::{
commands::{Command, Request, RequestParserError, RequestParserResult, ResponseParserError},
common::{GroupType, TagName},
common::{GroupType, TagName, WindowRange},
filter::Filter,
request_tokenizer::RequestTokenizer,
response_tokenizer::{ResponseAttributes, expect_property_type},
@@ -13,8 +13,9 @@ pub struct List;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ListRequest {
tagname: TagName,
filter: Filter,
group: Option<GroupType>,
filter: Option<Filter>,
groups: Vec<GroupType>,
window: Option<WindowRange>,
}
pub type ListResponse = Vec<String>;
@@ -25,10 +26,16 @@ impl Command for List {
const COMMAND: &'static str = "list";
fn serialize_request(&self, request: Self::Request) -> String {
let mut cmd = format!("{} {} {}", Self::COMMAND, request.tagname, request.filter);
if let Some(group) = request.group {
let mut cmd = match &request.filter {
Some(f) => format!("{} {} {}", Self::COMMAND, request.tagname, f),
None => format!("{} {}", Self::COMMAND, request.tagname),
};
for group in request.groups {
cmd.push_str(&format!(" group {}", group));
}
if let Some(window) = request.window {
cmd.push_str(&format!(" window {}", window));
}
cmd
}
@@ -38,28 +45,46 @@ impl Command for List {
.parse()
.map_err(|_| RequestParserError::SyntaxError(1, tagname.to_owned()))?;
// TODO: This should be optional
let filter = match parts.next() {
Some(f) => {
Filter::parse(f).map_err(|_| RequestParserError::SyntaxError(1, f.to_owned()))?
}
None => return Err(RequestParserError::UnexpectedEOF),
};
let mut filter = None;
let mut groups = Vec::new();
let mut window = None;
let group = if let Some("group") = parts.next() {
let mut next = parts.next();
if let Some(f) = next
&& f != "group"
&& f != "window"
{
let parsed_filter =
Filter::parse(f).map_err(|_| RequestParserError::SyntaxError(1, f.to_owned()))?;
filter = Some(parsed_filter);
next = parts.next();
}
while let Some(g) = next
&& g == "group"
{
let group = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
Some(
group
.parse()
.map_err(|_| RequestParserError::SyntaxError(1, group.to_owned()))?,
)
} else {
None
};
let parsed_group = group
.parse()
.map_err(|_| RequestParserError::SyntaxError(1, group.to_owned()))?;
groups.push(parsed_group);
next = parts.next();
}
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()))?;
window = Some(parsed_window);
}
debug_assert!(parts.next().is_none());
Ok((Request::List(tagname, filter, group), ""))
Ok((Request::List(tagname, filter, groups, window), ""))
}
fn parse_response(

View File

@@ -102,7 +102,7 @@ pub enum Request {
Option<WindowRange>,
Option<SongPosition>,
),
List(TagName, Filter, Option<GroupType>),
List(TagName, Option<Filter>, Vec<GroupType>, Option<WindowRange>),
#[deprecated]
ListAll(Option<Uri>),
#[deprecated]