Skip to main content

clack_host/host/
info.rs

1use clap_sys::host::clap_host;
2use std::ffi::{CStr, CString, NulError};
3use std::pin::Pin;
4use std::sync::Arc;
5
6#[derive(Debug, Clone)]
7struct HostInfoInner {
8    name: Pin<Box<CStr>>,
9    vendor: Pin<Box<CStr>>,
10    url: Pin<Box<CStr>>,
11    version: Pin<Box<CStr>>,
12}
13
14/// Human-readable information and description about the host.
15///
16/// This information is passed to plugins at instantiation time by [`PluginInstance::new`](crate::prelude::PluginInstance::new).
17///
18/// See the [`new`](HostInfo::new) method's documentation for an example of how to instantiate it.
19#[derive(Debug, Clone)]
20pub struct HostInfo {
21    inner: Arc<HostInfoInner>,
22}
23
24impl HostInfo {
25    /// Creates a new host information container from its components.
26    ///
27    /// * `name`: The name of the host. Example: `"Bitwig Studio"`
28    /// * `vendor`: The software vendor of the host. Example: `"Bitwig GmbH"`
29    /// * `url`: Example: `"https://bitwig.com"`
30    /// * `version`: The version string of the host. Example: `"4.3.2"`
31    ///
32    /// All parameters are copied into new string buffers.
33    ///
34    /// # Errors
35    ///
36    /// All parameters must not contain the null (`\0`) character. If any of them do, a [`NulError`] is returned.
37    ///
38    /// # Example
39    ///
40    /// ```
41    /// use clack_host::host::HostInfo;
42    ///
43    /// let info = HostInfo::new("Bitwig Studio", "Bitwig GmbH", "https://bitwig.com", "4.3.2");
44    /// ```
45    ///
46    pub fn new(name: &str, vendor: &str, url: &str, version: &str) -> Result<Self, NulError> {
47        Ok(Self::new_from_cstring(
48            CString::new(name)?,
49            CString::new(vendor)?,
50            CString::new(url)?,
51            CString::new(version)?,
52        ))
53    }
54
55    /// An infallible version of [`new`](HostInfo::new).
56    ///
57    /// This method takes ownership of preexisting [`CString`] buffers, and therefore cannot fail
58    /// from null byte errors, and performs fewer allocations compared to [`new`](HostInfo::new).
59    ///
60    /// See the documentation for [`new`](HostInfo::new) for more information about the arguments.
61    pub fn new_from_cstring(
62        name: CString,
63        vendor: CString,
64        url: CString,
65        version: CString,
66    ) -> Self {
67        Self {
68            inner: Arc::new(HostInfoInner {
69                name: Pin::new(name.into_boxed_c_str()),
70                vendor: Pin::new(vendor.into_boxed_c_str()),
71                url: Pin::new(url.into_boxed_c_str()),
72                version: Pin::new(version.into_boxed_c_str()),
73            }),
74        }
75    }
76
77    /// Creates a new host information container using the data originally provided to a plugin.
78    #[cfg(feature = "clack-plugin")]
79    pub fn from_plugin(info: &clack_plugin::host::HostInfo) -> Self {
80        fn from_opt(str: Option<&CStr>) -> CString {
81            match str {
82                None => CString::new("").unwrap(),
83                Some(str) => CString::from(str),
84            }
85        }
86
87        Self::new_from_cstring(
88            from_opt(info.name()),
89            from_opt(info.vendor()),
90            from_opt(info.url()),
91            from_opt(info.version()),
92        )
93    }
94
95    /// Returns the name of the host.
96    #[inline]
97    pub fn name(&self) -> &CStr {
98        &self.inner.name
99    }
100
101    /// Returns the software vendor of the host.
102    #[inline]
103    pub fn vendor(&self) -> &CStr {
104        &self.inner.vendor
105    }
106
107    /// Returns the host's web homepage's URL.
108    #[inline]
109    pub fn url(&self) -> &CStr {
110        &self.inner.url
111    }
112
113    /// Returns the version string of the host
114    #[inline]
115    pub fn version(&self) -> &CStr {
116        &self.inner.version
117    }
118
119    pub(crate) fn write_to_raw(&self, host: &mut clap_host) {
120        host.name = self.inner.name.as_ptr();
121        host.vendor = self.inner.vendor.as_ptr();
122        host.url = self.inner.url.as_ptr();
123        host.version = self.inner.version.as_ptr();
124    }
125}