zenoh_plugin_trait/vtable.rs
1//
2// Copyright (c) 2023 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0.
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12// ZettaScale Zenoh Team, <zenoh@zettascale.tech>
13//
14use zenoh_result::ZResult;
15
16use crate::{Plugin, StructVersion};
17
18pub type PluginLoaderVersion = u64;
19pub const PLUGIN_LOADER_VERSION: PluginLoaderVersion = 1;
20
21type StartFn<StartArgs, Instance> = fn(&str, &StartArgs) -> ZResult<Instance>;
22
23#[repr(C)]
24pub struct PluginVTable<StartArgs, Instance> {
25 pub plugin_version: &'static str,
26 pub plugin_long_version: &'static str,
27 pub start: StartFn<StartArgs, Instance>,
28}
29impl<StartArgs, Instance> StructVersion for PluginVTable<StartArgs, Instance> {
30 fn struct_version() -> u64 {
31 1
32 }
33 fn struct_features() -> &'static str {
34 ""
35 }
36}
37
38impl<StartArgs, Instance> PluginVTable<StartArgs, Instance> {
39 pub fn new<ConcretePlugin: Plugin<StartArgs = StartArgs, Instance = Instance>>() -> Self {
40 Self {
41 plugin_version: ConcretePlugin::PLUGIN_VERSION,
42 plugin_long_version: ConcretePlugin::PLUGIN_LONG_VERSION,
43 start: ConcretePlugin::start,
44 }
45 }
46}
47
48/// This macro adds non-mangled functions which provides plugin version and loads it into the host.
49/// If plugin library should work also as static, consider calling this macro under feature condition
50///
51/// The functions declared by this macro are:
52///
53/// - `get_plugin_loader_version` - returns `PLUGIN_LOADER_VERSION` const of the crate. The [`PluginsManager`](crate::manager::PluginsManager)
54/// will check if this version is compatible with the host.
55/// - `get_compatibility` - returns [`Compatibility`](crate::Compatibility) struct which contains all version information (Rust compiler version, features used, version of plugin's structures).
56/// The layout of this structure is guaranteed to be stable until the [`PLUGIN_LOADER_VERSION`](crate::PLUGIN_LOADER_VERSION) is changed,
57/// so it's safe to use it in the host after call to `get_plugin_loader_version` returns compatible version.
58/// Then the [`PluginsManager`](crate::manager::PluginsManager) compares the returned [`Compatibility`](crate::Compatibility) with it's own and decides if it can continue loading the plugin.
59/// - `load_plugin` - returns [`PluginVTable`](crate::PluginVTable) which is able to create plugin's instance.
60///
61#[macro_export]
62macro_rules! declare_plugin {
63 ($ty: path) => {
64 #[no_mangle]
65 fn get_plugin_loader_version() -> $crate::PluginLoaderVersion {
66 $crate::PLUGIN_LOADER_VERSION
67 }
68
69 #[no_mangle]
70 fn get_compatibility() -> $crate::Compatibility {
71 $crate::Compatibility::with_plugin_version::<
72 <$ty as $crate::Plugin>::StartArgs,
73 <$ty as $crate::Plugin>::Instance,
74 $ty,
75 >()
76 }
77
78 #[no_mangle]
79 fn load_plugin() -> $crate::PluginVTable<
80 <$ty as $crate::Plugin>::StartArgs,
81 <$ty as $crate::Plugin>::Instance,
82 > {
83 $crate::PluginVTable::new::<$ty>()
84 }
85 };
86}