tesseract_swift_utils/future/
into.rs

1use crate::ptr::{CAnyDropPtr, SyncPtr};
2use crate::response::COptionResponseResult;
3use crate::result::Result;
4use crate::error::CError;
5use crate::Void;
6use std::future::Future;
7use std::mem::ManuallyDrop;
8use std::pin::Pin;
9use std::sync::{Arc, Mutex};
10use std::task::{Context, Poll, Wake};
11
12use super::{CFuture, CFutureOnCompleteCallback};
13
14enum State<V: 'static> {
15    Value(Result<V>),
16    Callback(SyncPtr<Void>, CFutureOnCompleteCallback<V>),
17    Resolved,
18}
19
20type StateArc<V> = Arc<Mutex<Option<State<V>>>>;
21
22struct FutureWrapper<V: Send + 'static, F: Future<Output = Result<V>> + Send + 'static> {
23    rs: Mutex<Pin<Box<F>>>,
24    st: StateArc<V>,
25}
26
27impl<V: Send + 'static, F: Future<Output = Result<V>> + Send + 'static> FutureWrapper<V, F> {
28    pub fn new(rs: Pin<Box<F>>, st: StateArc<V>) -> Self {
29        Self {
30            rs: Mutex::new(rs),
31            st,
32        }
33    }
34
35    fn poll_future(self: Arc<Self>) -> std::result::Result<bool, String> {
36        let mut fguard = self.rs.lock().map_err(|e| format!("{}", e))?;
37        let waker = Arc::clone(&self).into();
38        let mut context = Context::from_waker(&waker);
39
40        let poll = fguard.as_mut().poll(&mut context);
41
42        std::mem::drop(fguard);
43
44        match poll {
45            Poll::Pending => Ok(false),
46            Poll::Ready(result) => self.set_response(result).map(|_| true),
47        }
48    }
49
50    fn set_response(&self, response: Result<V>) -> std::result::Result<(), String> {
51        let mut state = self.st.lock().map_err(|e| format!("{}", e))?;
52
53        match state.take() {
54            None => {
55                *state = Some(State::Value(response));
56                Ok(())
57            }
58            Some(current_state) => {
59                match current_state {
60                    State::Value(_) | State::Resolved => {
61                        *state = Some(current_state);
62                        Err("It's a bug. Why is the resolved future gets resolved again?".into())
63                    }
64                    State::Callback(ctx, cb) => {
65                        *state = Some(State::Resolved);
66                        std::mem::drop(state); // free mutex
67                        unsafe {
68                            match response {
69                                Err(err) => {
70                                    cb(ctx, std::ptr::null_mut(), &mut ManuallyDrop::new(err))
71                                }
72                                Ok(val) => {
73                                    cb(ctx, &mut ManuallyDrop::new(val), std::ptr::null_mut())
74                                }
75                            };
76                        };
77                        Ok(())
78                    }
79                }
80            }
81        }
82    }
83
84    fn wrap(future: F) -> CFuture<V> {
85        let boxed = Box::pin(future);
86        let state = Arc::new(Mutex::new(None));
87        let wrapped = Arc::new(Self::new(boxed, Arc::clone(&state)));
88
89        let _ = wrapped.poll_future().unwrap();
90
91        CFuture::new(CAnyDropPtr::new(state), Self::_set_on_complete)
92    }
93
94    unsafe extern "C" fn _set_on_complete(
95        future: &CFuture<V>,
96        context: SyncPtr<Void>,
97        value: *mut ManuallyDrop<V>,
98        error: *mut ManuallyDrop<CError>,
99        cb: CFutureOnCompleteCallback<V>
100    ) -> COptionResponseResult {
101        let arc = Arc::clone(future.ptr().as_ref::<StateArc<V>>().unwrap());
102        let mut state = arc.lock().unwrap();
103
104        match state.take() {
105            None => {
106                *state = Some(State::Callback(context, cb));
107                COptionResponseResult::None
108            }
109            Some(current_state) => match current_state {
110                State::Callback(ctx, cb) => {
111                    *state = Some(State::Callback(ctx, cb));
112                    panic!("Callback already set for this future");
113                }
114                State::Resolved => {
115                    *state = Some(State::Resolved);
116                    panic!("Future is already resolved");
117                }
118                State::Value(response) => {
119                    *state = Some(State::Resolved);
120                    match response {
121                        Err(err) => {
122                            *error = ManuallyDrop::new(err);
123                            COptionResponseResult::Error
124                        },
125                        Ok(val) => {
126                            *value = ManuallyDrop::new(val);
127                            COptionResponseResult::Some
128                        }
129                    }
130                }
131            },
132        }
133    }
134}
135
136impl<V: Send, F: Future<Output = Result<V>> + Send> Wake for FutureWrapper<V, F> {
137    fn wake(self: Arc<Self>) {
138        let _ = self.poll_future().unwrap();
139    }
140}
141
142impl<V: Send + 'static, F: Future<Output = Result<V>> + Send + 'static> From<F> for CFuture<V> {
143    fn from(future: F) -> Self {
144        FutureWrapper::wrap(future)
145    }
146}