emf_core_base_rs_ffi/module.rs
1//! Module api.
2//!
3//! # Example
4//!
5//! ```no_run
6//! # use emf_core_base_rs_ffi::CBaseBinding;
7//! # let base_interface: &mut dyn CBaseBinding = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
8//! use emf_core_base_rs_ffi::sys::api::SysBinding;
9//! use emf_core_base_rs_ffi::version::api::VersionBinding;
10//! use emf_core_base_rs_ffi::module::api::ModuleBinding;
11//! use emf_core_base_rs_ffi::library::OSPathChar;
12//! use emf_core_base_rs_ffi::collections::{NonNullConst, ConstSpan};
13//! use emf_core_base_rs_ffi::module::{MODULE_LOADER_DEFAULT_HANDLE,
14//! InterfaceDescriptor, InterfaceName};
15//!
16//! unsafe {
17//! // `base_interface` has the type `&mut dyn CBaseBinding`.
18//! SysBinding::lock(base_interface);
19//!
20//! // Path of the module. Platform dependent initialisation.
21//! let mod_path: OSPathChar = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
22//!
23//! let handle = match ModuleBinding::add_module(
24//! base_interface,
25//! MODULE_LOADER_DEFAULT_HANDLE,
26//! NonNullConst::from(&mod_path)
27//! ).to_result() {
28//! Ok(handle) => handle,
29//! Err(_) => {
30//! SysBinding::panic(
31//! base_interface,
32//! Some(NonNullConst::from(b"Unable to add the module.\0"))
33//! );
34//! }
35//! };
36//!
37//! if ModuleBinding::load(base_interface, handle).is_err() {
38//! SysBinding::panic(
39//! base_interface,
40//! Some(NonNullConst::from(b"Unable to load the module.\0"))
41//! );
42//! }
43//!
44//! if ModuleBinding::initialize(base_interface, handle).is_err() {
45//! SysBinding::panic(
46//! base_interface,
47//! Some(NonNullConst::from(b"Unable to initialize the module.\0"))
48//! );
49//! }
50//!
51//! let interface_desc = InterfaceDescriptor {
52//! name: InterfaceName::from("jobs_interface"),
53//! version: VersionBinding::new_short(base_interface, 1, 0, 0),
54//! extensions: ConstSpan::new()
55//! };
56//!
57//! if ModuleBinding::export_interface(
58//! base_interface,
59//! handle,
60//! NonNullConst::from(&interface_desc)
61//! ).is_err() {
62//! SysBinding::panic(
63//! base_interface,
64//! Some(NonNullConst::from(b"Unable to export the interface.\0"))
65//! );
66//! }
67//!
68//! SysBinding::unlock(base_interface);
69//! }
70//! ```
71use crate::collections::{ConstSpan, StaticVec};
72use crate::version::Version;
73use std::ffi::c_void;
74use std::ptr::NonNull;
75
76pub mod api;
77pub mod module_loader;
78pub mod native_module;
79
80/// Maximum length of a module name.
81pub const MODULE_INFO_NAME_MAX_LENGTH: usize = 32;
82
83/// Maximum length of a module version.
84pub const MODULE_INFO_VERSION_MAX_LENGTH: usize = 32;
85
86/// Maximum length of an interface name.
87pub const INTERFACE_INFO_NAME_MAX_LENGTH: usize = 32;
88
89/// Maximum length of an extension name.
90pub const INTERFACE_EXTENSION_NAME_MAX_LENGTH: usize = 32;
91
92/// Maximum length of a module type.
93pub const MODULE_LOADER_TYPE_MAX_LENGTH: usize = 64;
94
95/// Type of a native module.
96pub const NATIVE_MODULE_TYPE_NAME: &str = "emf::core_base::native";
97
98/// Native module entry symbol.
99pub const NATIVE_MODULE_INTERFACE_SYMBOL_NAME: &str = "emf_cbase_native_module_interface";
100
101/// Default loader handle.
102pub const MODULE_LOADER_DEFAULT_HANDLE: LoaderHandle = LoaderHandle {
103 id: PredefinedHandles::Native as i32,
104};
105
106/// Predefined loader handles.
107#[repr(i32)]
108#[non_exhaustive]
109#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
110pub enum PredefinedHandles {
111 Native = 0,
112}
113
114/// Module api errors.
115#[repr(i32)]
116#[non_exhaustive]
117#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
118pub enum Error {
119 PathInvalid = 0,
120 ModuleStateInvalid = 1,
121 ModuleHandleInvalid = 2,
122 LoaderHandleInvalid = 3,
123 InternalHandleInvalid = 4,
124 ModuleTypeInvalid = 5,
125 ModuleTypeNotFound = 6,
126 DuplicateModuleType = 7,
127 InterfaceNotFound = 8,
128 DuplicateInterface = 9,
129 ModuleDependencyNotFound = 10,
130 BufferOverflow = 11,
131}
132
133/// Status of a module.
134#[repr(i32)]
135#[non_exhaustive]
136#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
137pub enum ModuleStatus {
138 Unloaded = 0,
139 Terminated = 1,
140 Ready = 2,
141}
142
143/// Handle of a module.
144#[repr(C)]
145#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
146pub struct ModuleHandle {
147 pub id: i32,
148}
149
150/// Handle of a module loader.
151#[repr(C)]
152#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
153pub struct LoaderHandle {
154 pub id: i32,
155}
156
157/// Internal handle of a module.
158#[repr(C)]
159#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
160pub struct InternalHandle {
161 pub id: isize,
162}
163
164/// Interface from a module.
165#[repr(C)]
166#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
167pub struct Interface {
168 pub interface: NonNull<c_void>,
169}
170
171/// Name of a module.
172pub type ModuleName = StaticVec<u8, MODULE_INFO_NAME_MAX_LENGTH>;
173
174/// Type of a module.
175pub type ModuleType = StaticVec<u8, MODULE_LOADER_TYPE_MAX_LENGTH>;
176
177/// Version a module.
178pub type ModuleVersion = StaticVec<u8, MODULE_INFO_VERSION_MAX_LENGTH>;
179
180/// Name of an interface.
181pub type InterfaceName = StaticVec<u8, INTERFACE_INFO_NAME_MAX_LENGTH>;
182
183/// Extension of an interface.
184pub type InterfaceExtension = StaticVec<u8, INTERFACE_EXTENSION_NAME_MAX_LENGTH>;
185
186/// Information regarding a module.
187#[repr(C)]
188#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
189pub struct ModuleInfo {
190 pub name: ModuleName,
191 pub version: ModuleVersion,
192}
193
194/// Information regarding an interface.
195#[repr(C)]
196#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
197pub struct InterfaceDescriptor {
198 pub name: InterfaceName,
199 pub version: Version,
200 pub extensions: ConstSpan<InterfaceExtension>,
201}