use clap_sys::host::clap_host;
use std::ffi::{CStr, CString, NulError};
use std::pin::Pin;
use std::sync::Arc;
#[derive(Debug, Clone)]
struct HostInfoInner {
name: Pin<Box<CStr>>,
vendor: Pin<Box<CStr>>,
url: Pin<Box<CStr>>,
version: Pin<Box<CStr>>,
}
#[derive(Debug, Clone)]
pub struct HostInfo {
inner: Arc<HostInfoInner>,
}
impl HostInfo {
pub fn new(name: &str, vendor: &str, url: &str, version: &str) -> Result<Self, NulError> {
Ok(Self::new_from_cstring(
CString::new(name)?,
CString::new(vendor)?,
CString::new(url)?,
CString::new(version)?,
))
}
pub fn new_from_cstring(
name: CString,
vendor: CString,
url: CString,
version: CString,
) -> Self {
Self {
inner: Arc::new(HostInfoInner {
name: Pin::new(name.into_boxed_c_str()),
vendor: Pin::new(vendor.into_boxed_c_str()),
url: Pin::new(url.into_boxed_c_str()),
version: Pin::new(version.into_boxed_c_str()),
}),
}
}
#[cfg(feature = "clack-plugin")]
pub fn from_plugin(info: &clack_plugin::host::HostInfo) -> Self {
fn from_opt(str: Option<&CStr>) -> CString {
match str {
None => CString::new("").unwrap(),
Some(str) => CString::from(str),
}
}
Self::new_from_cstring(
from_opt(info.name()),
from_opt(info.vendor()),
from_opt(info.url()),
from_opt(info.version()),
)
}
#[inline]
pub fn name(&self) -> &CStr {
&self.inner.name
}
#[inline]
pub fn vendor(&self) -> &CStr {
&self.inner.vendor
}
#[inline]
pub fn url(&self) -> &CStr {
&self.inner.url
}
#[inline]
pub fn version(&self) -> &CStr {
&self.inner.version
}
pub(crate) fn write_to_raw(&self, host: &mut clap_host) {
host.name = self.inner.name.as_ptr();
host.vendor = self.inner.vendor.as_ptr();
host.url = self.inner.url.as_ptr();
host.version = self.inner.version.as_ptr();
}
}