#[cfg(all(target_os = "macos", feature = "system-capture-mac"))]
use anyhow::Context;
use anyhow::Result;
use clap::Args as ClapArgs;
#[derive(ClapArgs, Debug)]
pub struct Args {}
#[cfg(any(test, all(target_os = "macos", feature = "system-capture-mac")))]
#[derive(Clone, Debug, Eq, PartialEq)]
struct DeviceRow {
uid: String,
name: String,
is_default: bool,
}
#[cfg(any(test, all(target_os = "macos", feature = "system-capture-mac")))]
fn render_devices(mut devices: Vec<DeviceRow>) -> String {
devices.sort_by(|left, right| left.uid.cmp(&right.uid));
let mut rendered = String::from("uid\tdefault\tname\n");
for device in devices {
let default = if device.is_default { "yes" } else { "" };
rendered.push_str(&device.uid);
rendered.push('\t');
rendered.push_str(default);
rendered.push('\t');
rendered.push_str(&device.name);
rendered.push('\n');
}
rendered
}
pub fn run(_args: Args) -> Result<()> {
#[cfg(all(target_os = "macos", feature = "system-capture-mac"))]
{
let devices = scrybe_capture_mac::input_devices()
.map_err(anyhow::Error::from)
.context("enumerating macOS Core Audio input devices")?
.into_iter()
.map(|device| DeviceRow {
uid: device.uid,
name: device.name,
is_default: device.is_default,
})
.collect();
print!("{}", render_devices(devices));
Ok(())
}
#[cfg(not(all(target_os = "macos", feature = "system-capture-mac")))]
{
anyhow::bail!(
"scrybe devices is supported only by a macOS build with the `system-capture-mac` \
feature; Linux and Windows device selectors are deferred to M8"
);
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
#[test]
fn render_devices_keeps_duplicate_names_distinct_by_uid() {
let rendered = render_devices(vec![
DeviceRow {
uid: "usb-input".to_string(),
name: "MacBook Pro Microphone".to_string(),
is_default: false,
},
DeviceRow {
uid: "built-in-input".to_string(),
name: "MacBook Pro Microphone".to_string(),
is_default: true,
},
]);
assert_eq!(
rendered,
"uid\tdefault\tname\n\
built-in-input\tyes\tMacBook Pro Microphone\n\
usb-input\t\tMacBook Pro Microphone\n"
);
}
#[test]
#[cfg(not(all(target_os = "macos", feature = "system-capture-mac")))]
fn devices_fail_loudly_without_native_identifier_support() {
let error = run(Args {}).unwrap_err();
assert!(error.to_string().contains("deferred to M8"));
}
}