Lines
0 %
Functions
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use crate::{
commands::{CommandRequest, CommandResponse, RequestParserError, ResponseParserError},
filter::Filter,
request_tokenizer::RequestTokenizer,
response_tokenizer::{ResponseAttributes, get_and_parse_property},
types::GroupType,
};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CountRequest {
filter: Filter,
group: Option<GroupType>,
}
impl CountRequest {
pub fn new(filter: Filter, group: Option<GroupType>) -> Self {
CountRequest { filter, group }
impl CommandRequest for CountRequest {
type Response = CountResponse;
const COMMAND: &'static str = "count";
const MIN_ARGS: u32 = 1;
const MAX_ARGS: Option<u32> = Some(2);
fn serialize(&self) -> String {
let mut cmd = format!("{} {}", Self::COMMAND, self.filter);
if let Some(group) = self.group.as_ref() {
cmd.push_str(&format!(" group {}", group));
cmd.push('\n');
cmd
fn parse(mut parts: RequestTokenizer<'_>) -> Result<Self, RequestParserError> {
let filter = match parts.next() {
Some(f) => {
Filter::parse(f).map_err(|_| RequestParserError::SyntaxError(1, f.to_owned()))?
None => return Err(Self::missing_arguments_error(0)),
let group = if let Some("group") = parts.next() {
let group = parts
.next()
.ok_or(RequestParserError::MissingKeywordValue {
argument_index: 1,
keyword: "group",
})?;
Some(
group
.parse()
.map_err(|_| RequestParserError::SubtypeParserError {
expected_type: "GroupType",
raw_input: group.to_owned(),
})?,
)
} else {
None
Self::throw_if_too_many_arguments(parts)?;
Ok(CountRequest { filter, group })
pub struct CountResponse {
pub songs: usize,
pub playtime: u64,
impl CountResponse {
pub fn new(songs: usize, playtime: u64) -> Self {
CountResponse { songs, playtime }
impl CommandResponse for CountResponse {
type Request = CountRequest;
fn parse(parts: ResponseAttributes<'_>) -> Result<Self, ResponseParserError> {
let parts: HashMap<_, _> = parts.into_map()?;
let songs = get_and_parse_property!(parts, "songs", Text);
let playtime = get_and_parse_property!(parts, "playtime", Text);
Ok(CountResponse { songs, playtime })
fn serialize(&self) -> Vec<u8> {
unimplemented!("response serialization is not yet implemented for CountResponse")