commands/listplaylists: implement

This commit is contained in:
2025-12-07 21:21:58 +09:00
parent d811840ea1
commit a2c143a461

View File

@@ -1,14 +1,26 @@
use serde::{Deserialize, Serialize};
use crate::{
PlaylistName,
commands::{Command, RequestParserError, ResponseParserError},
request_tokenizer::RequestTokenizer,
response_tokenizer::ResponseAttributes,
response_tokenizer::{ResponseAttributes, get_next_and_parse_property, get_next_property},
};
pub struct ListPlaylists;
pub type ListPlaylistsResponse = Vec<ListPlaylistsResponseEntry>;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ListPlaylistsResponseEntry {
pub playlist: PlaylistName,
// TODO: parse this
pub last_modified: Option<String>,
}
impl Command for ListPlaylists {
type Request = ();
type Response = ();
type Response = ListPlaylistsResponse;
const COMMAND: &'static str = "listplaylists";
fn serialize_request(&self, _request: Self::Request) -> String {
@@ -23,6 +35,85 @@ impl Command for ListPlaylists {
fn parse_response(
parts: ResponseAttributes<'_>,
) -> Result<Self::Response, ResponseParserError<'_>> {
unimplemented!()
let mut parts = parts.into_lazy_vec().into_iter().peekable();
// TODO: count instances of 'playlist' to preallocate
let mut result = Vec::new();
while parts.peek().is_some() {
let (key, playlist) = get_next_and_parse_property!(parts, Text);
debug_assert!(key == "playlist");
let last_modified = if let Some(Ok(("Last-Modified", _))) = parts.peek() {
let (_key, last_modified) = get_next_property!(parts, Text);
Some(last_modified.to_string())
} else {
None
};
result.push(ListPlaylistsResponseEntry {
playlist,
last_modified,
});
}
Ok(result)
}
}
#[cfg(test)]
mod tests {
use super::*;
use indoc::indoc;
use pretty_assertions::assert_eq;
#[test]
fn test_parse_response() {
let response = indoc! {"
playlist: My Playlist 1
Last-Modified: 2024-01-01T12:00:00Z
playlist: My Playlist 2
Last-Modified: 2024-02-01T12:00:00Z
playlist: My Playlist 3
Last-Modified: 2024-03-01T12:00:00Z
playlist: My Playlist 4
playlist: My Playlist 5
playlist: My Playlist 6
Last-Modified: 2024-06-01T12:00:00Z
OK
"};
let result = ListPlaylists::parse_raw_response(response);
assert_eq!(
result,
Ok(vec![
ListPlaylistsResponseEntry {
playlist: "My Playlist 1".into(),
last_modified: Some("2024-01-01T12:00:00Z".to_string()),
},
ListPlaylistsResponseEntry {
playlist: "My Playlist 2".into(),
last_modified: Some("2024-02-01T12:00:00Z".to_string()),
},
ListPlaylistsResponseEntry {
playlist: "My Playlist 3".into(),
last_modified: Some("2024-03-01T12:00:00Z".to_string()),
},
ListPlaylistsResponseEntry {
playlist: "My Playlist 4".into(),
last_modified: None,
},
ListPlaylistsResponseEntry {
playlist: "My Playlist 5".into(),
last_modified: None,
},
ListPlaylistsResponseEntry {
playlist: "My Playlist 6".into(),
last_modified: Some("2024-06-01T12:00:00Z".to_string()),
},
])
);
>>>>>>> a0f4105 (commands/listplaylists: implement)
}
}