1use crate::ffi::collections::NonNullConst;
3use crate::ffi::module::native_module::{
4 NativeModule as NativeModuleFFI, NativeModuleBinding,
5 NativeModuleInterface as NativeModuleInterfaceFFI,
6};
7use crate::ffi::CBaseBinding;
8use crate::module::{Error, Interface, InterfaceDescriptor, Module, ModuleInfo};
9use crate::ownership::{
10 AccessIdentifier, BorrowImmutable, BorrowMutable, ImmutableAccessIdentifier,
11 MutableAccessIdentifier, Owned,
12};
13use crate::CBaseInterfaceInfo;
14use std::marker::PhantomData;
15use std::ops::{Deref, DerefMut};
16use std::ptr::NonNull;
17
18#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
20pub struct NativeModuleInstance<'a, O> {
21 _handle: Option<NonNull<NativeModuleFFI>>,
22 _phantom: PhantomData<&'a ()>,
23 _ownership: PhantomData<*const O>,
24}
25
26unsafe impl<O> Send for NativeModuleInstance<'_, O> {}
27unsafe impl<O> Sync for NativeModuleInstance<'_, O> {}
28
29impl<O> NativeModuleInstance<'_, O>
30where
31 O: AccessIdentifier,
32{
33 #[inline]
40 pub const unsafe fn new(handle: Option<NonNull<NativeModuleFFI>>) -> Self {
41 Self {
42 _handle: handle,
43 _phantom: PhantomData,
44 _ownership: PhantomData,
45 }
46 }
47
48 #[inline]
50 pub const fn as_handle(&self) -> Option<NonNull<NativeModuleFFI>> {
51 self._handle
52 }
53}
54
55impl NativeModuleInstance<'_, Owned> {
56 #[inline]
58 pub const fn as_borrowed(&self) -> NativeModuleInstance<'_, BorrowImmutable<'_>> {
59 unsafe { NativeModuleInstance::<BorrowImmutable<'_>>::new(self._handle) }
60 }
61
62 #[inline]
64 pub fn as_borrowed_mut(&mut self) -> NativeModuleInstance<'_, BorrowMutable<'_>> {
65 unsafe { NativeModuleInstance::<BorrowMutable<'_>>::new(self._handle) }
66 }
67}
68
69#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
71pub struct NativeModule<'a, O> {
72 _interface: NonNullConst<NativeModuleInterfaceFFI>,
73 _phantom: PhantomData<&'a ()>,
74 _ownership: PhantomData<*const O>,
75}
76
77unsafe impl<O> Send for NativeModule<'_, O> {}
78unsafe impl<O> Sync for NativeModule<'_, O> {}
79
80impl<O> Deref for NativeModule<'_, O> {
81 type Target = NonNullConst<NativeModuleInterfaceFFI>;
82
83 fn deref(&self) -> &Self::Target {
84 &self._interface
85 }
86}
87
88impl<O> DerefMut for NativeModule<'_, O> {
89 fn deref_mut(&mut self) -> &mut Self::Target {
90 &mut self._interface
91 }
92}
93
94impl<O> NativeModule<'_, O>
95where
96 O: AccessIdentifier,
97{
98 #[inline]
105 pub const unsafe fn new(interface: NonNullConst<NativeModuleInterfaceFFI>) -> Self {
106 Self {
107 _interface: interface,
108 _phantom: PhantomData,
109 _ownership: PhantomData,
110 }
111 }
112}
113
114impl NativeModule<'_, Owned> {
115 #[inline]
117 pub const fn as_borrowed(&self) -> NativeModule<'_, BorrowImmutable<'_>> {
118 unsafe { NativeModule::<'_, BorrowImmutable<'_>>::new(self._interface) }
119 }
120
121 #[inline]
123 pub fn as_borrowed_mut(&mut self) -> NativeModule<'_, BorrowMutable<'_>> {
124 unsafe { NativeModule::<'_, BorrowMutable<'_>>::new(self._interface) }
125 }
126}
127
128impl<'a, O> NativeModule<'a, O>
129where
130 O: MutableAccessIdentifier,
131{
132 #[inline]
148 pub unsafe fn load<MO>(
149 &mut self,
150 module: &Module<'_, MO>,
151 interface: &impl CBaseInterfaceInfo,
152 ) -> Result<NativeModuleInstance<'a, Owned>, Error>
153 where
154 MO: AccessIdentifier,
155 {
156 let internal = interface.internal_interface();
157 let interface_handle = internal.base_module();
158 let has_fn_fn = internal.fetch_has_function_fn();
159 let get_fn_fn = internal.fetch_get_function_fn();
160
161 self._interface
162 .into_mut()
163 .as_mut()
164 .load(module.as_handle(), interface_handle, has_fn_fn, get_fn_fn)
165 .map_or_else(
166 |e| Err(Error::FFIError(e)),
167 |v| Ok(NativeModuleInstance::new(v)),
168 )
169 }
170
171 #[inline]
187 pub unsafe fn unload(
188 &mut self,
189 instance: NativeModuleInstance<'_, Owned>,
190 ) -> Result<(), Error> {
191 self._interface
192 .into_mut()
193 .as_mut()
194 .unload(instance.as_handle())
195 .to_result()
196 .map_or_else(|e| Err(Error::FFIError(e)), |_v| Ok(()))
197 }
198
199 #[inline]
215 pub unsafe fn initialize(
216 &mut self,
217 instance: &mut NativeModuleInstance<'_, Owned>,
218 ) -> Result<(), Error> {
219 self._interface
220 .into_mut()
221 .as_mut()
222 .initialize(instance.as_handle())
223 .to_result()
224 .map_or_else(|e| Err(Error::FFIError(e)), |_v| Ok(()))
225 }
226
227 #[inline]
243 pub unsafe fn terminate(
244 &mut self,
245 instance: &mut NativeModuleInstance<'_, Owned>,
246 ) -> Result<(), Error> {
247 self._interface
248 .into_mut()
249 .as_mut()
250 .terminate(instance.as_handle())
251 .to_result()
252 .map_or_else(|e| Err(Error::FFIError(e)), |_v| Ok(()))
253 }
254}
255
256impl<'a, O> NativeModule<'a, O>
257where
258 O: ImmutableAccessIdentifier,
259{
260 #[inline]
276 pub unsafe fn get_interface<'instance, IO, T>(
277 &self,
278 instance: &'instance NativeModuleInstance<'instance, IO>,
279 interface: &InterfaceDescriptor,
280 caster: impl FnOnce(crate::ffi::module::Interface) -> T,
281 ) -> Result<Interface<'instance, T>, Error>
282 where
283 IO: ImmutableAccessIdentifier,
284 {
285 self._interface
286 .as_ref()
287 .get_interface(instance.as_handle(), NonNullConst::from(interface))
288 .to_result()
289 .map_or_else(
290 |e| Err(Error::FFIError(e)),
291 |v| Ok(Interface::new(caster(v))),
292 )
293 }
294
295 #[inline]
311 pub unsafe fn get_module_info<'instance, IO>(
312 &self,
313 instance: &'instance NativeModuleInstance<'instance, IO>,
314 ) -> Result<&'instance ModuleInfo, Error>
315 where
316 IO: ImmutableAccessIdentifier,
317 {
318 self._interface
319 .as_ref()
320 .get_module_info(instance.as_handle())
321 .to_result()
322 .map_or_else(|e| Err(Error::FFIError(e)), |v| Ok(&*v.as_ptr()))
323 }
324
325 #[inline]
337 pub unsafe fn get_load_dependencies(&self) -> &'a [InterfaceDescriptor] {
338 let span = self._interface.as_ref().get_load_dependencies();
339 if span.is_empty() {
340 <&[_]>::default()
341 } else {
342 std::slice::from_raw_parts(span.as_ptr(), span.len())
343 }
344 }
345
346 #[inline]
362 pub unsafe fn get_runtime_dependencies<'instance, IO>(
363 &self,
364 instance: &'instance NativeModuleInstance<'instance, IO>,
365 ) -> Result<&'instance [InterfaceDescriptor], Error>
366 where
367 IO: ImmutableAccessIdentifier,
368 {
369 self._interface
370 .as_ref()
371 .get_runtime_dependencies(instance.as_handle())
372 .to_result()
373 .map_or_else(
374 |e| Err(Error::FFIError(e)),
375 |v| {
376 if v.is_empty() {
377 Ok(<&[_]>::default())
378 } else {
379 Ok(std::slice::from_raw_parts(v.as_ptr(), v.len()))
380 }
381 },
382 )
383 }
384
385 #[inline]
401 pub unsafe fn get_exportable_interfaces<'instance, IO>(
402 &self,
403 instance: &'instance NativeModuleInstance<'instance, IO>,
404 ) -> Result<&'instance [InterfaceDescriptor], Error>
405 where
406 IO: ImmutableAccessIdentifier,
407 {
408 self._interface
409 .as_ref()
410 .get_exportable_interfaces(instance.as_handle())
411 .to_result()
412 .map_or_else(
413 |e| Err(Error::FFIError(e)),
414 |v| {
415 if v.is_empty() {
416 Ok(<&[_]>::default())
417 } else {
418 Ok(std::slice::from_raw_parts(v.as_ptr(), v.len()))
419 }
420 },
421 )
422 }
423}