139 lines
4.3 KiB
Rust
139 lines
4.3 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::commands::{
|
|
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
|
|
expect_property_type,
|
|
};
|
|
|
|
pub struct Decoders;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct Decoder {
|
|
pub plugin: String,
|
|
pub suffixes: Vec<String>,
|
|
pub mime_types: Vec<String>,
|
|
}
|
|
|
|
pub type DecodersResponse = Vec<Decoder>;
|
|
|
|
impl Command for Decoders {
|
|
type Response = DecodersResponse;
|
|
const COMMAND: &'static str = "decoders";
|
|
|
|
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
|
debug_assert!(parts.next().is_none());
|
|
Ok((Request::Decoders, ""))
|
|
}
|
|
|
|
fn parse_response(
|
|
parts: ResponseAttributes<'_>,
|
|
) -> Result<Self::Response, ResponseParserError<'_>> {
|
|
let mut result = Vec::new();
|
|
let mut current_decoder: Option<Decoder> = None;
|
|
for (key, value) in parts.0.into_iter() {
|
|
match key {
|
|
"plugin" => {
|
|
if let Some(decoder) = current_decoder.take() {
|
|
result.push(decoder);
|
|
}
|
|
|
|
let plugin_name = expect_property_type!(Some(value), key, Text).to_string();
|
|
|
|
current_decoder = Some(Decoder {
|
|
plugin: plugin_name,
|
|
suffixes: Vec::new(),
|
|
mime_types: Vec::new(),
|
|
});
|
|
}
|
|
"suffix" => {
|
|
current_decoder
|
|
.as_mut()
|
|
.ok_or(ResponseParserError::SyntaxError(0, key))?
|
|
.suffixes
|
|
.push(expect_property_type!(Some(value), key, Text).to_string());
|
|
}
|
|
"mime_type" => {
|
|
current_decoder
|
|
.as_mut()
|
|
.ok_or(ResponseParserError::SyntaxError(0, key))?
|
|
.mime_types
|
|
.push(expect_property_type!(Some(value), key, Text).to_string());
|
|
}
|
|
k => {
|
|
return Err(ResponseParserError::UnexpectedProperty(k));
|
|
}
|
|
}
|
|
}
|
|
|
|
if let Some(decoder) = current_decoder.take() {
|
|
result.push(decoder);
|
|
}
|
|
|
|
Ok(result)
|
|
}
|
|
}
|
|
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use indoc::indoc;
|
|
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_parse_response() {
|
|
let input = indoc! {"
|
|
plugin: audiofile
|
|
suffix: wav
|
|
suffix: au
|
|
suffix: aiff
|
|
suffix: aif
|
|
mime_type: audio/wav
|
|
mime_type: audio/aiff
|
|
mime_type: audio/x-wav
|
|
mime_type: audio/x-aiff
|
|
plugin: pcm
|
|
mime_type: audio/L16
|
|
mime_type: audio/L24
|
|
mime_type: audio/x-mpd-float
|
|
mime_type: audio/x-mpd-cdda-pcm
|
|
mime_type: audio/x-mpd-cdda-pcm-reverse
|
|
mime_type: audio/x-mpd-alsa-pcm
|
|
OK
|
|
"};
|
|
let result = Decoders::parse_raw_response(input);
|
|
assert_eq!(
|
|
result,
|
|
Ok(vec![
|
|
Decoder {
|
|
plugin: "audiofile".to_string(),
|
|
suffixes: vec![
|
|
"wav".to_string(),
|
|
"au".to_string(),
|
|
"aiff".to_string(),
|
|
"aif".to_string()
|
|
],
|
|
mime_types: vec![
|
|
"audio/wav".to_string(),
|
|
"audio/aiff".to_string(),
|
|
"audio/x-wav".to_string(),
|
|
"audio/x-aiff".to_string()
|
|
],
|
|
},
|
|
Decoder {
|
|
plugin: "pcm".to_string(),
|
|
suffixes: vec![],
|
|
mime_types: vec![
|
|
"audio/L16".to_string(),
|
|
"audio/L24".to_string(),
|
|
"audio/x-mpd-float".to_string(),
|
|
"audio/x-mpd-cdda-pcm".to_string(),
|
|
"audio/x-mpd-cdda-pcm-reverse".to_string(),
|
|
"audio/x-mpd-alsa-pcm".to_string(),
|
|
],
|
|
},
|
|
])
|
|
);
|
|
}
|
|
}
|