refactor(daemon): Refactor src/utils/pipewire.rs to flatten deep conditionals and consolidate logic. (#124)

Moved redundant struct initialization into `AudioDevice::new` and unified port mapping assignments in an `add_port` method. This removes nesting using early returns and eliminates an unnecessary clone on the hashmap conversion step.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit is contained in:
Tarasov Aleksandr
2026-06-01 22:51:58 +03:00
committed by GitHub
parent 54011e7ff1
commit 0f8abbc443
2 changed files with 90 additions and 92 deletions
+43
View File
@@ -29,3 +29,46 @@ pub struct AudioDevice {
pub output_fl: Option<Port>,
pub output_fr: Option<Port>,
}
impl AudioDevice {
pub fn new(
id: u32,
nick: Option<&str>,
description: Option<&str>,
name: Option<&str>,
device_type: DeviceType,
) -> Self {
Self {
id,
nick: nick
.or(description)
.or(name)
.unwrap_or_default()
.to_string(),
name: name.unwrap_or_default().to_string(),
device_type,
input_fl: None,
input_fr: None,
output_fl: None,
output_fr: None,
}
}
pub fn add_port(&mut self, port: Port) {
match port.name.as_str() {
"input_FL" => self.input_fl = Some(port),
"input_FR" => self.input_fr = Some(port),
"output_FL" | "capture_FL" => self.output_fl = Some(port),
"output_FR" | "capture_FR" => self.output_fr = Some(port),
"input_MONO" => {
self.input_fl = Some(port.clone());
self.input_fr = Some(port);
}
"output_MONO" | "capture_MONO" => {
self.output_fl = Some(port.clone());
self.output_fr = Some(port);
}
_ => {}
}
}
}
+31 -76
View File
@@ -20,51 +20,40 @@ pub fn setup_pipewire_context() -> Result<(MainLoopRc, ContextRc), String> {
fn parse_global_object(
global_object: &GlobalObject<&DictRef>,
) -> (Option<AudioDevice>, Option<Port>) {
// Only objects with props can be devices/ports
if let Some(props) = global_object.props {
// Only objects with media.class can be devices
let props = match global_object.props {
Some(p) => p,
None => return (None, None),
};
if let Some(media_class) = props.get("media.class") {
let node_id = global_object.id;
let node_nick = props.get("node.nick");
let node_name = props.get("node.name");
let node_description = props.get("node.description");
// Check if the device is an input or output
return if media_class.starts_with("Audio/Source") {
let input_device = AudioDevice {
id: node_id,
nick: node_nick
.unwrap_or(node_description.unwrap_or(node_name.unwrap_or_default()))
.to_string(),
name: node_name.unwrap_or_default().to_string(),
device_type: DeviceType::Input,
input_fl: None,
input_fr: None,
output_fl: None,
output_fr: None,
};
(Some(input_device), None)
if media_class.starts_with("Audio/Source") {
let input_device = AudioDevice::new(
node_id,
node_nick,
node_description,
node_name,
DeviceType::Input,
);
return (Some(input_device), None);
} else if media_class.starts_with("Stream/Output/Audio") {
let output_device = AudioDevice {
id: node_id,
nick: node_nick
.unwrap_or(node_description.unwrap_or(node_name.unwrap_or_default()))
.to_string(),
name: node_name.unwrap_or_default().to_string(),
device_type: DeviceType::Output,
let output_device = AudioDevice::new(
node_id,
node_nick,
node_description,
node_name,
DeviceType::Output,
);
return (Some(output_device), None);
}
return (None, None);
}
input_fl: None,
input_fr: None,
output_fl: None,
output_fr: None,
};
(Some(output_device), None)
} else {
(None, None)
};
// Check if the object is a port
} else if props.get("port.direction").is_some()
if props.get("port.direction").is_some()
&& let (Some(node_id), Some(port_id), Some(port_name)) = (
props.get("node.id").and_then(|id| id.parse::<u32>().ok()),
props.get("port.id").and_then(|id| id.parse::<u32>().ok()),
@@ -76,10 +65,9 @@ fn parse_global_object(
port_id,
name: port_name.to_string(),
};
return (None, Some(port));
}
}
(None, None)
}
@@ -188,47 +176,14 @@ pub async fn get_all_devices() -> Result<(Vec<AudioDevice>, Vec<AudioDevice>)> {
let node_id = port.node_id;
if let Some(input_device) = input_devices.get_mut(&node_id) {
match port.name.as_str() {
"input_FL" => input_device.input_fl = Some(port),
"input_FR" => input_device.input_fr = Some(port),
"output_FL" => input_device.output_fl = Some(port),
"output_FR" => input_device.output_fr = Some(port),
"capture_FL" => input_device.output_fl = Some(port),
"capture_FR" => input_device.output_fr = Some(port),
"input_MONO" => {
input_device.input_fl = Some(port.clone());
input_device.input_fr = Some(port)
}
"capture_MONO" => {
input_device.output_fl = Some(port.clone());
input_device.output_fr = Some(port);
}
_ => {}
}
input_device.add_port(port);
} else if let Some(output_device) = output_devices.get_mut(&node_id) {
match port.name.as_str() {
"input_FL" => output_device.input_fl = Some(port),
"input_FR" => output_device.input_fr = Some(port),
"output_FL" => output_device.output_fl = Some(port),
"output_FR" => output_device.output_fr = Some(port),
"capture_FL" => output_device.output_fl = Some(port),
"capture_FR" => output_device.output_fr = Some(port),
"output_MONO" => {
output_device.output_fl = Some(port.clone());
output_device.output_fr = Some(port)
}
"capture_MONO" => {
output_device.output_fl = Some(port.clone());
output_device.output_fr = Some(port)
}
_ => {}
}
output_device.add_port(port);
}
}
let mut input_devices: Vec<AudioDevice> = input_devices.values().cloned().collect();
let mut output_devices: Vec<AudioDevice> =
output_devices.values().cloned().collect();
let mut input_devices: Vec<AudioDevice> = input_devices.into_values().collect();
let mut output_devices: Vec<AudioDevice> = output_devices.into_values().collect();
input_devices.sort_by_key(|a| a.id);
output_devices.sort_by_key(|a| a.id);