From 44ba3eb4dc2cf05fdd362a91773a58d06a90cb7f Mon Sep 17 00:00:00 2001 From: h7x4 Date: Sun, 23 Feb 2025 16:33:34 +0100 Subject: [PATCH] commands: move `ResponseAttributes` parser out of `Command` --- src/commands.rs | 109 ++++++++++++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 46 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index 860d9d3..af1fe7e 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -66,6 +66,64 @@ pub trait Command { ) -> Result>; fn parse_raw_response(raw: &str) -> Result> { + Self::parse_response(ResponseAttributes::new(raw)?) + } +} + +pub type RequestParserResult<'a> = Result<(Request, &'a str), RequestParserError>; + +#[derive(Debug, Clone, PartialEq)] +pub enum RequestParserError { + SyntaxError(u64, String), + MissingCommandListEnd(u64), + NestedCommandList(u64), + UnexpectedCommandListEnd(u64), + UnexpectedEOF, + MissingNewline, +} + +// TODO: should these be renamed to fit the mpd docs? +// "Attribute" instead of "Property"? +#[derive(Debug, Clone, PartialEq)] +pub enum ResponseParserError<'a> { + /// A property was expected to be present in the response, but was not found. + MissingProperty(&'a str), + + // TODO: change name to UnexpectedPropertyEncoding + /// An expected property was found in the response, but its encoding was not as expected. (e.g. binary instead of text) + UnexpectedPropertyType(&'a str, &'a str), + + /// A property was found in the response that was not expected. + UnexpectedProperty(&'a str), + + /// The property value is parsable, but the value is invalid or nonsensical. + InvalidProperty(&'a str, &'a str), + + /// Could not parse the response due to a syntax error. + SyntaxError(u64, &'a str), + + /// Response ended early, while more properties were expected. + UnexpectedEOF, + + // MissingNewline, +} + +pub type GenericResponseResult<'a> = Result, &'a str>; + +pub type GenericResponse<'a> = HashMap<&'a str, GenericResponseValue<'a>>; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum GenericResponseValue<'a> { + Text(&'a str), + Binary(&'a [u8]), + // Many(Vec>), +} + +#[derive(Debug, Clone, PartialEq)] +pub struct ResponseAttributes<'a>(Vec<(&'a str, GenericResponseValue<'a>)>); + +impl<'a> ResponseAttributes<'a> { + pub fn new(raw: &'a str) -> Result> { let mut parts = Vec::new(); let mut lines = raw.lines(); loop { @@ -92,55 +150,14 @@ pub trait Command { parts.push((key, GenericResponseValue::Text(value))); } - Self::parse_response(parts.into()) + Ok(parts.into()) } + + // pub fn get<'a>(&self, key: &str) -> Option<&GenericResponseValue<'a>> { + // self.0.iter().find_map(|(k, v)| if k == &key { Some(v) } else { None }) + // } } -pub type RequestParserResult<'a> = Result<(Request, &'a str), RequestParserError>; - -#[derive(Debug, Clone, PartialEq)] -pub enum RequestParserError { - SyntaxError(u64, String), - MissingCommandListEnd(u64), - NestedCommandList(u64), - UnexpectedCommandListEnd(u64), - UnexpectedEOF, - MissingNewline, -} - -// TODO: should these be renamed to fit the mpd docs? -// "Attribute" instead of "Property"? -#[derive(Debug, Clone, PartialEq)] -pub enum ResponseParserError<'a> { - MissingProperty(&'a str), - UnexpectedPropertyType(&'a str, &'a str), - UnexpectedProperty(&'a str), - InvalidProperty(&'a str, &'a str), - SyntaxError(u64, &'a str), - UnexpectedEOF, - MissingNewline, -} - -pub type GenericResponseResult<'a> = Result, &'a str>; - -pub type GenericResponse<'a> = HashMap<&'a str, GenericResponseValue<'a>>; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum GenericResponseValue<'a> { - Text(&'a str), - Binary(&'a [u8]), - // Many(Vec>), -} - -pub struct ResponseAttributes<'a>(Vec<(&'a str, GenericResponseValue<'a>)>); - -// impl ResponseAttributes<'_> { -// pub fn -// pub fn get<'a>(&self, key: &str) -> Option<&GenericResponseValue<'a>> { -// self.0.iter().find_map(|(k, v)| if k == &key { Some(v) } else { None }) -// } -// } - impl ResponseAttributes<'_> { pub fn is_empty(&self) -> bool { self.0.is_empty()