commands: move ResponseAttributes parser out of Command
Some checks failed
Build and test / build (push) Successful in 1m0s
Build and test / check (push) Failing after 52s
Build and test / test (push) Successful in 1m45s
Build and test / docs (push) Successful in 1m23s

This commit is contained in:
2025-02-23 16:33:34 +01:00
parent d80ebfc4cf
commit 44ba3eb4dc

View File

@@ -66,6 +66,64 @@ pub trait Command {
) -> Result<Self::Response, ResponseParserError<'_>>;
fn parse_raw_response(raw: &str) -> Result<Self::Response, ResponseParserError<'_>> {
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<GenericResponse<'a>, &'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<GenericResponseValue<'a>>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct ResponseAttributes<'a>(Vec<(&'a str, GenericResponseValue<'a>)>);
impl<'a> ResponseAttributes<'a> {
pub fn new(raw: &'a str) -> Result<Self, ResponseParserError<'a>> {
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<GenericResponse<'a>, &'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<GenericResponseValue<'a>>),
}
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()