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}