1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Re-export of the paste crate to perform macro expansion in plugins
pub use paste as plugin_paste;
/// This macro automatically creates all the components that are required by the app to load the plugin and check the compatibility
/// ```
/// use aanyx::{export_plugin, plugin::PluginRegistrar};
/// # mod public_plugin_struct {
/// # pub struct MyPlugin {}
/// # }
///
/// use public_plugin_struct::MyPlugin as MyPlugin;
///
/// #[allow(improper_ctypes_definitions)]
/// extern "C" fn register(registrar: &mut dyn PluginRegistrar< MyPlugin >) {
/// registrar.register_plugin("MyPlugin", Box::new( MyPlugin {} ));
/// }
/// export_plugin!( register, MyPlugin );
/// ```
///
/// Or even better using traits:
/// ```
/// use aanyx::{ export_plugin, plugin::PluginRegistrar};
/// # mod public_plugin_trait {
/// # pub trait MyPlugin {
/// # fn plugin( &self ){}
/// # }
/// # }
///
/// use public_plugin_trait::MyPlugin as MyPluginTrait;
/// struct MyPlugin;
/// impl MyPluginTrait for MyPlugin {
/// // Trait implentation goes here
/// };
///
/// #[allow(improper_ctypes_definitions)]
/// extern "C" fn register(registrar: &mut dyn PluginRegistrar<dyn MyPluginTrait>) {
/// registrar.register_plugin("MyPlugin", Box::new(MyPlugin));
/// }
/// export_plugin!( register, dyn MyPluginTrait );
/// ```
///
/// ## Limitations
/// See [`import_plugin's limitations`](crate::import_plugin#limtations).
/// This is a macro that generates the name of the plugin declaration in a module.
/// Using this makes easier to check type compatibility between plugins and host systems,
/// because if the plugin doesn't support the requested plugin type then no declaration will be found.
/// ```
/// use aanyx::import_plugin;
/// assert_eq!( import_plugin!( MyPlugin ), b"plugin_declaration_MyPlugin");
/// assert_eq!( import_plugin!( dyn MyPluginTrait ), b"plugin_declaration_dyn_MyPluginTrait");
/// ```
///
/// ## Limitations
/// Because of Rust macros limitations a type cannot contains `::`.
/// This means that this is invalid:
/// ```compile_fail, no_run
/// use aanyx::import_plugin;
/// import_plugin!( myplugin::MyPlugin )
/// ```
/// A workaround is the following:
/// ```
/// # mod myplugin { pub struct MyPlugin {} }
/// use myplugin::MyPlugin as MyPlugin;
/// use aanyx::import_plugin;
///
/// import_plugin!( MyPlugin );
/// ```
/// Also using a type alias makes a result not compatible between host and plugin.
/// ```
/// # mod myplugin { pub struct MyPlugin {} }
/// use aanyx::import_plugin;
/// use myplugin::MyPlugin as MyPlugin;
/// type MyAlias = MyPlugin;
///
/// assert_ne!( import_plugin!( MyAlias ), import_plugin!( MyPlugin ) );
/// ```