use crate::extensions::{ExtensionSide, HostExtensionSide, PluginExtensionSide};
use clap_sys::host::clap_host;
use clap_sys::plugin::clap_plugin;
use std::ffi::c_void;
use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
use std::ptr::NonNull;
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct RawExtension<S: ExtensionSide, T = ()> {
extension_ptr: NonNull<T>,
host_or_plugin_ptr: NonNull<c_void>, _side: PhantomData<fn() -> S>,
}
unsafe impl<S: ExtensionSide, T> Send for RawExtension<S, T> {}
unsafe impl<S: ExtensionSide, T> Sync for RawExtension<S, T> {}
impl<S: ExtensionSide, T> RawExtension<S, T> {
#[inline]
pub const fn as_ptr(&self) -> NonNull<T> {
self.extension_ptr
}
}
impl<S: ExtensionSide> RawExtension<S, ()> {
pub const unsafe fn cast<T>(&self) -> RawExtension<S, T> {
RawExtension {
extension_ptr: self.extension_ptr.cast(),
host_or_plugin_ptr: self.host_or_plugin_ptr,
_side: PhantomData,
}
}
}
impl<T> RawExtension<PluginExtensionSide, T> {
pub const unsafe fn from_raw_plugin_extension(
extension_ptr: NonNull<T>,
plugin_ptr: NonNull<clap_plugin>,
) -> Self {
Self {
extension_ptr,
host_or_plugin_ptr: plugin_ptr.cast(),
_side: PhantomData,
}
}
pub const fn plugin_ptr(&self) -> NonNull<clap_plugin> {
self.host_or_plugin_ptr.cast()
}
}
impl<T> RawExtension<HostExtensionSide, T> {
pub const unsafe fn from_raw_host_extension(
extension_ptr: NonNull<T>,
host_ptr: NonNull<clap_host>,
) -> Self {
Self {
extension_ptr,
host_or_plugin_ptr: host_ptr.cast(),
_side: PhantomData,
}
}
pub const fn host_ptr(&self) -> NonNull<clap_host> {
self.host_or_plugin_ptr.cast()
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct RawExtensionImplementation {
inner: NonNull<c_void>,
}
impl RawExtensionImplementation {
pub const fn new<I>(implementation: &'static I) -> Self {
Self {
inner: unsafe { NonNull::new_unchecked(implementation as *const _ as *mut _) },
}
}
pub const fn as_ptr(&self) -> NonNull<c_void> {
self.inner
}
}
impl Debug for RawExtensionImplementation {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "RawExtensionImplementation({:p})", self.inner)
}
}