commands: implement response parser for outputs
This commit is contained in:
@@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
expect_property_type,
|
||||
};
|
||||
|
||||
pub struct Outputs;
|
||||
@@ -31,6 +32,131 @@ impl Command for Outputs {
|
||||
fn parse_response(
|
||||
_parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError<'_>> {
|
||||
unimplemented!()
|
||||
let mut outputs = Vec::new();
|
||||
|
||||
let mut id: Option<u64> = None;
|
||||
let mut name: Option<String> = None;
|
||||
let mut plugin: Option<String> = None;
|
||||
let mut enabled: Option<bool> = None;
|
||||
let mut attributes: HashMap<String, String> = HashMap::new();
|
||||
|
||||
for (k, v) in _parts.0.into_iter() {
|
||||
match k {
|
||||
"outputid" => {
|
||||
// Reset and store the previous output if all fields are present
|
||||
if let (Some(id), Some(name), Some(plugin), Some(enabled)) =
|
||||
(id.take(), name.take(), plugin.take(), enabled.take())
|
||||
{
|
||||
outputs.push(Output {
|
||||
id,
|
||||
name,
|
||||
plugin,
|
||||
enabled,
|
||||
attribute: attributes,
|
||||
});
|
||||
}
|
||||
attributes = HashMap::new();
|
||||
let id_s = expect_property_type!(Some(v), k, Text);
|
||||
id = Some(
|
||||
id_s.parse::<u64>()
|
||||
.map_err(|_| ResponseParserError::SyntaxError(0, id_s))?,
|
||||
);
|
||||
}
|
||||
"outputname" => {
|
||||
name = Some(expect_property_type!(Some(v), k, Text).to_string());
|
||||
}
|
||||
"plugin" => {
|
||||
plugin = Some(expect_property_type!(Some(v), k, Text).to_string());
|
||||
}
|
||||
"outputenabled" => {
|
||||
let val_s = expect_property_type!(Some(v), k, Text);
|
||||
let val: u64 = val_s
|
||||
.parse::<u64>()
|
||||
.map_err(|_| ResponseParserError::SyntaxError(0, val_s))?;
|
||||
enabled = Some(val != 0);
|
||||
}
|
||||
"attribute" => {
|
||||
let value = expect_property_type!(Some(v), k, Text);
|
||||
let mut parts = value.splitn(2, '=');
|
||||
let attr_key = parts
|
||||
.next()
|
||||
.ok_or(ResponseParserError::SyntaxError(0, &value))?
|
||||
.to_string();
|
||||
let attr_value = parts
|
||||
.next()
|
||||
.ok_or(ResponseParserError::SyntaxError(0, &value))?
|
||||
.to_string();
|
||||
attributes.insert(attr_key, attr_value);
|
||||
}
|
||||
_ => {
|
||||
return Err(ResponseParserError::UnexpectedProperty(k));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store the last output if all fields are present
|
||||
if let (Some(id), Some(name), Some(plugin), Some(enabled)) =
|
||||
(id.take(), name.take(), plugin.take(), enabled.take())
|
||||
{
|
||||
outputs.push(Output {
|
||||
id,
|
||||
name,
|
||||
plugin,
|
||||
enabled,
|
||||
attribute: attributes,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(outputs)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use indoc::indoc;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_response() {
|
||||
let input = indoc! {"
|
||||
outputid: 0
|
||||
outputname: PipeWire Sound Server
|
||||
plugin: pipewire
|
||||
outputenabled: 1
|
||||
outputid: 1
|
||||
outputname: Visualizer feed
|
||||
plugin: fifo
|
||||
outputenabled: 1
|
||||
attribute: fifo_path=/tmp/empidee-visualizer.fifo
|
||||
OK
|
||||
"};
|
||||
let result = Outputs::parse_raw_response(input);
|
||||
assert_eq!(
|
||||
result,
|
||||
Ok(vec![
|
||||
Output {
|
||||
id: 0,
|
||||
name: "PipeWire Sound Server".to_string(),
|
||||
plugin: "pipewire".to_string(),
|
||||
enabled: true,
|
||||
attribute: HashMap::new(),
|
||||
},
|
||||
Output {
|
||||
id: 1,
|
||||
name: "Visualizer feed".to_string(),
|
||||
plugin: "fifo".to_string(),
|
||||
enabled: true,
|
||||
attribute: {
|
||||
let mut map = HashMap::new();
|
||||
map.insert(
|
||||
"fifo_path".to_string(),
|
||||
"/tmp/empidee-visualizer.fifo".to_string(),
|
||||
);
|
||||
map
|
||||
},
|
||||
},
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user