Skip to main content

clack_host/host/
extensions.rs

1use crate::host::HostHandlers;
2use clack_common::extensions::*;
3use std::ffi::{CStr, c_void};
4use std::marker::PhantomData;
5use std::ptr::NonNull;
6
7/// A collection of all extensions supported for a given [`HostHandlers`] type.
8///
9/// Host can declare the different extensions they support by using the
10/// [`register`](HostExtensions::register) method on this struct, during a call to
11/// [`declare_extensions`](HostHandlers::declare_extensions).
12pub struct HostExtensions<'a, H: ?Sized> {
13    found: Option<NonNull<c_void>>,
14    requested: &'a CStr,
15    plugin_type: PhantomData<H>,
16}
17
18impl<'a, H: HostHandlers> HostExtensions<'a, H> {
19    #[inline]
20    pub(crate) fn new(requested: &'a CStr) -> Self {
21        Self {
22            found: None,
23            requested,
24            plugin_type: PhantomData,
25        }
26    }
27
28    #[inline]
29    pub(crate) fn found(&self) -> *const c_void {
30        self.found
31            .map(|p| p.as_ptr())
32            .unwrap_or(core::ptr::null_mut())
33    }
34
35    /// Adds a given extension implementation to the list of extensions this plugin supports.
36    pub fn register<E: ExtensionImplementation<H, ExtensionSide = HostExtensionSide>>(
37        &mut self,
38    ) -> &mut Self {
39        if self.found.is_some() {
40            return self;
41        }
42
43        if E::IDENTIFIERS.contains(&self.requested) {
44            self.found = Some(E::IMPLEMENTATION.as_ptr())
45        }
46
47        self
48    }
49}