iced_devtools/
executor.rs

1use crate::futures::futures::channel::mpsc;
2use crate::futures::futures::channel::oneshot;
3use crate::futures::futures::stream::{self, StreamExt};
4use crate::runtime::Task;
5
6use std::thread;
7
8pub fn spawn_blocking<T>(
9    f: impl FnOnce(mpsc::Sender<T>) + Send + 'static,
10) -> Task<T>
11where
12    T: Send + 'static,
13{
14    let (sender, receiver) = mpsc::channel(1);
15
16    let _ = thread::spawn(move || {
17        f(sender);
18    });
19
20    Task::stream(receiver)
21}
22
23pub fn try_spawn_blocking<T, E>(
24    f: impl FnOnce(mpsc::Sender<T>) -> Result<(), E> + Send + 'static,
25) -> Task<Result<T, E>>
26where
27    T: Send + 'static,
28    E: Send + 'static,
29{
30    let (sender, receiver) = mpsc::channel(1);
31    let (error_sender, error_receiver) = oneshot::channel();
32
33    let _ = thread::spawn(move || {
34        if let Err(error) = f(sender) {
35            let _ = error_sender.send(Err(error));
36        }
37    });
38
39    Task::stream(stream::select(
40        receiver.map(Ok),
41        stream::once(error_receiver).filter_map(async |result| result.ok()),
42    ))
43}