#[macro_export]
macro_rules! nautilus_plugin {
(
$(name: $name:expr,)?
$(vendor: $vendor:expr,)?
$(version: $version:expr,)?
$(custom_data: [$($cd:ty),* $(,)?] ,)?
$(actors: [$($act:ty),* $(,)?] ,)?
$(strategies: [$($strategy:ty),* $(,)?] ,)?
$(controllers: [$($controller:ty),* $(,)?] ,)?
) => {
$crate::__nautilus_plugin_impl! {
@parse
name = ($($name)?),
vendor = ($($vendor)?),
version = ($($version)?),
custom_data = ($($($cd),*)?),
actors = ($($($act),*)?),
strategies = ($($($strategy),*)?),
controllers = ($($($controller),*)?),
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __nautilus_plugin_impl {
(
@parse
name = ($name:expr),
vendor = ($($vendor:expr)?),
version = ($version:expr),
custom_data = ($($cd:ty),*),
actors = ($($act:ty),*),
strategies = ($($strategy:ty),*),
controllers = ($($controller:ty),*),
) => {
const _: () = {
#[allow(unused_imports)]
use $crate::surfaces::custom_data::PluginCustomData as _PluginCustomData;
#[allow(unused_imports)]
use $crate::surfaces::actor::PluginActor as _PluginActor;
#[allow(unused_imports)]
use $crate::surfaces::strategy::PluginStrategy as _PluginStrategy;
#[allow(unused_imports)]
use $crate::surfaces::controller::PluginController as _PluginController;
static CUSTOM_DATA: ::std::sync::LazyLock<
[$crate::manifest::CustomDataRegistration; $crate::__nautilus_plugin_impl!(@count $($cd),*)]
> = ::std::sync::LazyLock::new(|| {
[
$(
$crate::manifest::CustomDataRegistration {
type_name: $crate::boundary::BorrowedStr::from_str(
<$cd as $crate::surfaces::custom_data::PluginCustomData>::TYPE_NAME,
),
vtable: $crate::surfaces::custom_data::custom_data_vtable::<$cd>(),
},
)*
]
});
static ACTORS: ::std::sync::LazyLock<
[$crate::manifest::ActorRegistration; $crate::__nautilus_plugin_impl!(@count $($act),*)]
> = ::std::sync::LazyLock::new(|| {
[
$(
$crate::manifest::ActorRegistration {
type_name: $crate::boundary::BorrowedStr::from_str(
<$act as $crate::surfaces::actor::PluginActor>::TYPE_NAME,
),
vtable: $crate::surfaces::actor::actor_vtable::<$act>(),
},
)*
]
});
static STRATEGIES: ::std::sync::LazyLock<
[$crate::manifest::StrategyRegistration; $crate::__nautilus_plugin_impl!(@count $($strategy),*)]
> = ::std::sync::LazyLock::new(|| {
[
$(
$crate::manifest::StrategyRegistration {
type_name: $crate::boundary::BorrowedStr::from_str(
<$strategy as $crate::surfaces::strategy::PluginStrategy>::TYPE_NAME,
),
vtable: $crate::surfaces::strategy::strategy_vtable::<$strategy>(),
},
)*
]
});
static CONTROLLERS: ::std::sync::LazyLock<
[$crate::manifest::ControllerRegistration; $crate::__nautilus_plugin_impl!(@count $($controller),*)]
> = ::std::sync::LazyLock::new(|| {
[
$(
$crate::manifest::ControllerRegistration {
type_name: $crate::boundary::BorrowedStr::from_str(
<$controller as $crate::surfaces::controller::PluginController>::TYPE_NAME,
),
vtable: $crate::surfaces::controller::controller_vtable::<$controller>(),
},
)*
]
});
static MANIFEST: ::std::sync::LazyLock<$crate::manifest::PluginManifest> =
::std::sync::LazyLock::new(|| $crate::manifest::PluginManifest {
abi_version: $crate::NAUTILUS_PLUGIN_ABI_VERSION,
plugin_name: $crate::boundary::BorrowedStr::from_str($name),
plugin_vendor: $crate::boundary::BorrowedStr::from_str(
$crate::__nautilus_plugin_impl!(@opt $($vendor)?),
),
plugin_version: $crate::boundary::BorrowedStr::from_str($version),
build_id: $crate::manifest::PluginBuildId::current(),
custom_data: $crate::boundary::Slice::from_slice(&*CUSTOM_DATA),
actors: $crate::boundary::Slice::from_slice(&*ACTORS),
strategies: $crate::boundary::Slice::from_slice(&*STRATEGIES),
controllers: $crate::boundary::Slice::from_slice(&*CONTROLLERS),
});
#[unsafe(no_mangle)]
pub unsafe extern "C" fn nautilus_plugin_init(
host: *const $crate::host::HostVTable,
) -> *const $crate::manifest::PluginManifest {
let result = ::std::panic::catch_unwind(|| {
if host.is_null() {
return ::core::ptr::null::<$crate::manifest::PluginManifest>();
}
let host_ref = unsafe { &*host };
if host_ref.abi_version != $crate::NAUTILUS_PLUGIN_ABI_VERSION {
return ::core::ptr::null();
}
&*MANIFEST as *const _
});
match result {
Ok(ptr) => ptr,
Err(payload) => {
$crate::panic::drop_payload(payload);
::core::ptr::null()
}
}
}
};
};
(@opt) => { "" };
(@opt $vendor:expr) => { $vendor };
(@count) => { 0usize };
(@count $head:ty $(, $tail:ty)*) => {
1usize + $crate::__nautilus_plugin_impl!(@count $($tail),*)
};
}