use std::ffi::c_char;
use std::ptr;
use audio_cpp_sys::*;
use crate::error::Error;
use crate::ffi;
use crate::model::Model;
use crate::types::{Device, LoaderInfo, ModelFamily};
pub struct Registry {
raw: *mut audiocpp_registry,
}
unsafe impl Send for Registry {}
unsafe impl Sync for Registry {}
impl Registry {
pub fn new() -> Result<Self, Error> {
let raw = unsafe { audiocpp_registry_default() };
if raw.is_null() {
return Err(Error::NullHandle(ffi::last_error()));
}
Ok(Self { raw })
}
pub fn families(&self) -> Result<Vec<String>, Error> {
let mut out: *mut c_char = ptr::null_mut();
ffi::check_rc(unsafe { audiocpp_registry_families_json(self.raw, &mut out) })?;
let json = unsafe { ffi::take_string(out)? };
serde_json::from_str(&json).map_err(Error::from)
}
pub fn loaders(&self) -> Result<Vec<LoaderInfo>, Error> {
let mut out: *mut c_char = ptr::null_mut();
ffi::check_rc(unsafe { audiocpp_registry_loaders_json(self.raw, &mut out) })?;
let json = unsafe { ffi::take_string(out)? };
let root: serde_json::Value = serde_json::from_str(&json)?;
Ok(serde_json::from_value(root["loaders"].clone())?)
}
pub fn devices() -> Result<Vec<Device>, Error> {
let mut out: *mut c_char = ptr::null_mut();
ffi::check_rc(unsafe { audiocpp_registry_devices_json(&mut out) })?;
let json = unsafe { ffi::take_string(out)? };
serde_json::from_str(&json).map_err(Error::from)
}
pub fn load(
&self,
model_path: &str,
family_hint: Option<ModelFamily>,
load_options: Option<&str>,
) -> Result<Model, Error> {
let path_c = ffi::cstring(model_path)?;
let hint_c = family_hint
.as_ref()
.map(|f| ffi::cstring(f.as_str()))
.transpose()?;
let options_c = load_options.map(ffi::cstring).transpose()?;
let raw = unsafe {
audiocpp_registry_load(
self.raw,
path_c.as_ptr() as *const c_char,
hint_c.as_ref().map_or(ptr::null(), |s| s.as_ptr() as *const c_char),
options_c.as_ref().map_or(ptr::null(), |s| s.as_ptr() as *const c_char),
)
};
if raw.is_null() {
return Err(Error::NullHandle(ffi::last_error()));
}
Ok(Model::from_raw(raw))
}
}
impl Drop for Registry {
fn drop(&mut self) {
unsafe {
audiocpp_registry_free(self.raw);
}
}
}