use std::io::{ self, Write };
use cpal::
{
Device,
traits::{ DeviceTrait, HostTrait },
};
use crate::config;
fn prompt_selection(devices: &[String], config: &str) -> usize
{
let mut input: String;
loop
{
print!("\nSelect device: ");
io::stdout().flush().unwrap();
input = String::new(); io::stdin().read_line(&mut input).unwrap();
if let Ok(idx) = input.trim().parse::<usize>() && idx != 0
{
if let Some(device) = devices.get(idx - 1)
{
config::client_write(config, device);
println!("Set to: {}", device);
return idx - 1;
}
}
println!("Invalid selection!");
}
}
fn load_devices<T>(all_devices: T) -> Vec<String>
where
T: Iterator<Item = Device>
{
let mut devices = Vec::new();
for device in all_devices
{
if let Ok(name) = device.description().map(|d| d.to_string()) && !devices.contains(&name)
{
devices.push(name);
}
}
devices.sort();
devices
}
fn list_devices(devices: &[String])
{
for (i, device) in devices.iter().enumerate()
{
println!("[{}]: {device}", i + 1);
}
}
pub fn setup_devices() {
let host = cpal::default_host();
println!("Available input devices\n=======================");
let input_devices = load_devices(host.input_devices().unwrap());
list_devices(&input_devices); prompt_selection(&input_devices, "input_device");
println!("\nAvailable output devices\n========================");
let output_devices = load_devices(host.output_devices().unwrap());
list_devices(&output_devices); prompt_selection(&output_devices, "output_device"); }