emf_core_base_rs/
module.rs

1//! Module api
2//!
3//! # Example
4//!
5//! ```no_run
6//! # use emf_core_base_rs::{CBaseAccess, CBase};
7//! # let base_interface: &mut CBase = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
8//! use emf_core_base_rs::CBaseAPI;
9//! use emf_core_base_rs::version::VersionAPI;
10//! use emf_core_base_rs::module::{
11//!     ModuleAPI, DEFAULT_HANDLE, InterfaceDescriptor, InterfaceName, Error, Module
12//! };
13//! use emf_core_base_rs::ffi::collections::ConstSpan;
14//! use std::path::Path;
15//!
16//! let result = CBaseAccess::lock(base_interface, |interface| -> Result<Module<'_, _>, Error> {
17//!     let module_path = Path::new("path to a module");
18//!     let interface_desc = InterfaceDescriptor {
19//!         name: InterfaceName::from("my_interface"),
20//!         version: VersionAPI::new_short(interface, 1, 0, 0),
21//!         extensions: ConstSpan::new()
22//!     };
23//!
24//!     let mut module = ModuleAPI::add_module(interface, &DEFAULT_HANDLE, &module_path)?;
25//!     ModuleAPI::load(interface, &mut module)?;
26//!     ModuleAPI::initialize(interface, &mut module)?;
27//!     ModuleAPI::export_interface(interface, &mut module, &interface_desc)?;
28//!     Ok(module)
29//! });
30//!
31//! assert_eq!(result.is_ok(), true);
32//! ```
33use crate::ffi::module::{InternalHandle, LoaderHandle, ModuleHandle};
34use crate::ownership::{AccessIdentifier, BorrowImmutable, BorrowMutable, Owned};
35use std::marker::PhantomData;
36use std::ops::{Deref, DerefMut};
37
38mod api;
39pub mod module_loader;
40pub mod native_module;
41
42pub use crate::ffi::module::InterfaceDescriptor;
43pub use crate::ffi::module::InterfaceExtension;
44pub use crate::ffi::module::InterfaceName;
45pub use crate::ffi::module::ModuleInfo;
46pub use crate::ffi::module::ModuleName;
47pub use crate::ffi::module::ModuleStatus;
48pub use crate::ffi::module::ModuleType;
49pub use crate::ffi::module::ModuleVersion;
50pub use crate::ffi::module::INTERFACE_EXTENSION_NAME_MAX_LENGTH;
51pub use crate::ffi::module::INTERFACE_INFO_NAME_MAX_LENGTH;
52pub use crate::ffi::module::MODULE_INFO_NAME_MAX_LENGTH;
53pub use crate::ffi::module::MODULE_INFO_VERSION_MAX_LENGTH;
54pub use crate::ffi::module::MODULE_LOADER_TYPE_MAX_LENGTH;
55pub use crate::ffi::module::NATIVE_MODULE_INTERFACE_SYMBOL_NAME;
56pub use crate::ffi::module::NATIVE_MODULE_TYPE_NAME;
57
58pub use api::ModuleAPI;
59
60/// Handle of the default loader.
61pub const DEFAULT_HANDLE: Loader<'static, BorrowMutable<'static>> =
62    unsafe { Loader::new(crate::ffi::module::MODULE_LOADER_DEFAULT_HANDLE) };
63
64/// Errors of the module api.
65#[non_exhaustive]
66#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq)]
67pub enum Error {
68    /// A Parameter error.
69    ParameterError(String),
70    /// Raw ffi module error.
71    FFIError(crate::ffi::module::Error),
72}
73
74/// A module handle.
75#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
76pub struct Module<'a, O> {
77    _handle: ModuleHandle,
78    _lifetime: PhantomData<&'a ModuleHandle>,
79    _ownership: PhantomData<*const O>,
80}
81
82impl<'a, O> Module<'a, O>
83where
84    O: AccessIdentifier,
85{
86    /// Construct a new instance from a handle.
87    ///
88    /// # Safety
89    ///
90    /// This function allows the creation of invalid handles
91    /// by bypassing lifetimes.
92    #[inline]
93    pub const unsafe fn new(handle: ModuleHandle) -> Self {
94        Self {
95            _handle: handle,
96            _lifetime: PhantomData,
97            _ownership: PhantomData,
98        }
99    }
100
101    /// Fetches the internal handle.
102    #[inline]
103    pub const fn as_handle(&self) -> ModuleHandle {
104        self._handle
105    }
106}
107
108impl<'a> Module<'a, Owned> {
109    /// Borrows the library handle.
110    #[inline]
111    pub const fn as_borrowed(&self) -> Module<'a, BorrowImmutable<'_>> {
112        unsafe { Module::<BorrowImmutable<'_>>::new(self._handle) }
113    }
114
115    /// Borrows the library handle mutably.
116    #[inline]
117    pub fn as_borrowed_mut(&mut self) -> Module<'a, BorrowMutable<'_>> {
118        unsafe { Module::<BorrowMutable<'_>>::new(self._handle) }
119    }
120}
121
122/// A loader handle.
123#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
124pub struct Loader<'a, O> {
125    _handle: LoaderHandle,
126    _lifetime: PhantomData<&'a LoaderHandle>,
127    _ownership: PhantomData<*const O>,
128}
129
130impl<'a, O> Loader<'a, O>
131where
132    O: AccessIdentifier,
133{
134    /// Construct a new instance from a handle.
135    ///
136    /// # Safety
137    ///
138    /// This function allows the creation of invalid handles
139    /// by bypassing lifetimes.
140    #[inline]
141    pub const unsafe fn new(handle: LoaderHandle) -> Self {
142        Self {
143            _handle: handle,
144            _lifetime: PhantomData,
145            _ownership: PhantomData,
146        }
147    }
148
149    /// Fetches the internal handle.
150    #[inline]
151    pub const fn as_handle(&self) -> LoaderHandle {
152        self._handle
153    }
154}
155
156impl<'a> Loader<'a, Owned> {
157    /// Borrows the loader handle.
158    #[inline]
159    pub const fn as_borrowed(&self) -> Loader<'a, BorrowImmutable<'_>> {
160        unsafe { Loader::<BorrowImmutable<'_>>::new(self._handle) }
161    }
162
163    /// Borrows the loader handle mutably.
164    #[inline]
165    pub fn as_borrowed_mut(&mut self) -> Loader<'a, BorrowMutable<'_>> {
166        unsafe { Loader::<BorrowMutable<'_>>::new(self._handle) }
167    }
168}
169
170/// A loader handle.
171#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
172pub struct InternalModule<O> {
173    _handle: InternalHandle,
174    _ownership: PhantomData<*const O>,
175}
176
177impl<O> InternalModule<O>
178where
179    O: AccessIdentifier,
180{
181    /// Construct a new instance from a handle.
182    ///
183    /// # Safety
184    ///
185    /// This function allows the creation of invalid handles
186    /// by bypassing lifetimes.
187    #[inline]
188    pub const unsafe fn new(handle: InternalHandle) -> Self {
189        Self {
190            _handle: handle,
191            _ownership: PhantomData,
192        }
193    }
194
195    /// Fetches the internal handle.
196    #[inline]
197    pub const fn as_handle(&self) -> InternalHandle {
198        self._handle
199    }
200}
201
202impl InternalModule<Owned> {
203    /// Borrows the loader handle.
204    #[inline]
205    pub const fn as_borrowed(&self) -> InternalModule<BorrowImmutable<'_>> {
206        unsafe { InternalModule::<BorrowImmutable<'_>>::new(self._handle) }
207    }
208
209    /// Borrows the loader handle mutably.
210    #[inline]
211    pub fn as_borrowed_mut(&mut self) -> InternalModule<BorrowMutable<'_>> {
212        unsafe { InternalModule::<BorrowMutable<'_>>::new(self._handle) }
213    }
214}
215
216/// Interface from a module.
217#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
218pub struct Interface<'a, T> {
219    _interface: T,
220    _phantom: PhantomData<&'a ()>,
221}
222
223impl<T> Interface<'_, T> {
224    #[inline]
225    fn new(interface: T) -> Self {
226        Self {
227            _interface: interface,
228            _phantom: PhantomData,
229        }
230    }
231}
232
233impl<T> Deref for Interface<'_, T> {
234    type Target = T;
235
236    fn deref(&self) -> &Self::Target {
237        &self._interface
238    }
239}
240
241impl<T> DerefMut for Interface<'_, T> {
242    fn deref_mut(&mut self) -> &mut Self::Target {
243        &mut self._interface
244    }
245}