use crate::*;
use std::ffi::OsString;
use std::os::windows::ffi::*;
pub fn get_audio_device_ids(user_index: impl TryInto<u32>) -> Result<AudioDeviceIds, Error> {
fn_context!(xinput::get_audio_device_ids => XInputGetAudioDeviceIds);
#[allow(non_snake_case)] let XInputGetAudioDeviceIds = imports::XInputGetAudioDeviceIds.load(core::sync::atomic::Ordering::Relaxed);
let user_index = user_index.try_into().map_err(|_| fn_param_error!(user_index, error::BAD_ARGUMENTS))?;
let mut render_id = [0u16; 4096];
let mut capture_id = [0u16; 4096];
let mut render_len = 4096;
let mut capture_len = 4096;
let code = unsafe { XInputGetAudioDeviceIds(user_index, render_id.as_mut_ptr(), &mut render_len, capture_id.as_mut_ptr(), &mut capture_len) };
check_success!(code)?;
let render_device_id = OsString::from_wide(render_id .get(..render_len as usize).ok_or(fn_param_error!(render_device_id, error::BUFFER_TOO_SMALL))?.split(|c| *c==0).next().unwrap_or(&[]));
let capture_device_id = OsString::from_wide(capture_id.get(..capture_len as usize).ok_or(fn_param_error!(capture_device_id, error::BUFFER_TOO_SMALL))?.split(|c| *c==0).next().unwrap_or(&[]));
Ok(AudioDeviceIds {
render_device_id: if render_device_id .is_empty() { None } else { Some(render_device_id.into() ) },
capture_device_id: if capture_device_id.is_empty() { None } else { Some(capture_device_id.into()) },
})
}
#[test] fn test_valid_args() {
for user_index in 0 .. 4 {
if let Err(err) = get_audio_device_ids(user_index) {
assert!(matches!(err.kind(), error::DEVICE_NOT_CONNECTED | error::INVALID_FUNCTION | error::CO_E_NOTINITIALIZED), "unexpected error type: {err:?}");
}
}
}
#[test] fn test_bad_user_index() {
for user_index in xuser::invalids().chain(Some(xuser::INDEX_ANY)) {
let err = get_audio_device_ids(user_index).expect_err("get_audio_devices_ids should return an error for invalid users");
assert!(matches!(err.kind(), error::BAD_ARGUMENTS | error::INVALID_FUNCTION | error::CO_E_NOTINITIALIZED), "unexpected error type: {err:?}");
}
}