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}