diff --git a/src/commands/reflection/decoders.rs b/src/commands/reflection/decoders.rs index 3b361100..07722fa1 100644 --- a/src/commands/reflection/decoders.rs +++ b/src/commands/reflection/decoders.rs @@ -1,9 +1,13 @@ +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, @@ -24,6 +28,111 @@ impl Command for Decoders { fn parse_response( parts: ResponseAttributes<'_>, ) -> Result> { - unimplemented!() + let mut result = Vec::new(); + let mut current_decoder: Option = 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(), + ], + }, + ]) + ); } }