tesseract_swift_utils/future/
cfuture.rs1use super::from::CFutureWrapper;
2use crate::error::CError;
3use crate::ptr::*;
4use crate::response::COptionResponseResult;
5use crate::result::Result;
6use crate::Void;
7use std::future::Future;
8use std::mem::{ManuallyDrop, MaybeUninit};
9
10pub type CFutureOnCompleteCallback<V> = unsafe extern "C" fn(
11 context: SyncPtr<Void>,
12 value: *mut ManuallyDrop<V>,
13 error: *mut ManuallyDrop<CError>,
14);
15
16#[repr(C)]
17pub struct CFuture<V: 'static> {
18 ptr: CAnyDropPtr,
19 set_on_complete: unsafe extern "C" fn(
20 future: &CFuture<V>,
21 context: SyncPtr<Void>,
22 value: *mut ManuallyDrop<V>,
23 error: *mut ManuallyDrop<CError>,
24 cb: CFutureOnCompleteCallback<V>
25 ) -> COptionResponseResult,
26}
27
28struct CFutureContext<V: 'static> {
29 _future: CFuture<V>,
30 closure: Option<Box<dyn FnOnce(Result<V>)>>,
31}
32
33impl<V: 'static> CFutureContext<V> {
34 fn new<F: 'static + FnOnce(Result<V>)>(future: CFuture<V>, closure: F) -> Self {
35 Self {
36 _future: future,
37 closure: Some(Box::new(closure)),
38 }
39 }
40
41 fn resolve(&mut self, result: Result<V>) {
42 (self.closure.take().unwrap())(result);
43 }
44
45 unsafe fn from_raw(mut ptr: SyncPtr<Void>) -> Self {
46 ptr.take_typed()
47 }
48
49 fn into_raw(self) -> SyncPtr<Void> {
50 SyncPtr::new(self).as_void()
51 }
52}
53
54impl<V: 'static> CFuture<V> {
55 pub fn new(
56 ptr: CAnyDropPtr,
57 set_on_complete: unsafe extern "C" fn(
58 future: &CFuture<V>,
59 context: SyncPtr<Void>,
60 value: *mut ManuallyDrop<V>,
61 error: *mut ManuallyDrop<CError>,
62 cb: CFutureOnCompleteCallback<V>
63 ) -> COptionResponseResult,
64 ) -> Self {
65 Self {
66 ptr,
67 set_on_complete,
68 }
69 }
70
71 pub fn on_complete<F: 'static + FnOnce(Result<V>)>(self, cb: F) -> Option<Result<V>> {
72 let set_on_complete = self.set_on_complete;
73 let reference = &self as *const Self; let context = CFutureContext::new(self, cb).into_raw().ptr();
75
76 let mut value: MaybeUninit<ManuallyDrop<V>> = MaybeUninit::uninit();
77 let mut error: MaybeUninit<ManuallyDrop<CError>> = MaybeUninit::uninit();
78 let result = unsafe {
79 set_on_complete(
80 reference.as_ref().unwrap(),
81 SyncPtr::raw(context),
82 value.as_mut_ptr(), error.as_mut_ptr(),
83 Self::on_complete_handler
84 )
85 };
86
87 let value = unsafe { match result {
88 COptionResponseResult::None => None,
89 COptionResponseResult::Error =>
90 Some(Err(ManuallyDrop::into_inner(error.assume_init()))),
91 COptionResponseResult::Some =>
92 Some(Ok(ManuallyDrop::into_inner(value.assume_init())))
93 }};
94 if value.is_some() {
95 let _ = unsafe { CFutureContext::<V>::from_raw(SyncPtr::raw(context)) };
97 }
98 value
99 }
100
101 pub fn ptr(&self) -> &CAnyDropPtr {
102 &self.ptr
103 }
104
105 pub fn try_into_future(self) -> Result<impl Future<Output = Result<V>>> {
106 CFutureWrapper::try_from(self)
107 }
108
109 unsafe extern "C" fn on_complete_handler(
110 context: SyncPtr<Void>,
111 value: *mut ManuallyDrop<V>,
112 error: *mut ManuallyDrop<CError>,
113 ) {
114 let mut context = CFutureContext::from_raw(context);
115 if error.is_null() {
116 context.resolve(Ok(ManuallyDrop::take(value.as_mut().unwrap())));
117 } else {
118 context.resolve(Err(ManuallyDrop::take(error.as_mut().unwrap())));
119 }
120 }
121}