Skip to main content

rx_rust/operators/creating/
from_future.rs

1use crate::utils::types::MaybeSend;
2use crate::{
3    observable::{Observable, Subscription},
4    observer::{Observer, Termination},
5    scheduler::Scheduler,
6};
7use educe::Educe;
8use std::convert::Infallible;
9
10/// Converts a Future into an Observable.
11/// See <https://reactivex.io/documentation/operators/from.html>
12///
13/// The output is emitted as the single item, and the Observable then completes. A future of a
14/// `Result` goes through [`FromTryFuture`](crate::operators::creating::from_try_future::FromTryFuture)
15/// instead, which turns its `Err` into the error of the Observable.
16///
17/// # Examples
18/// ```rust
19/// # #[cfg(not(feature = "tokio-scheduler"))]
20/// # fn main() {}
21/// # #[cfg(feature = "tokio-scheduler")]
22/// #[tokio::main]
23/// async fn main() {
24///     use rx_rust::{
25///         observable::ObservableExt,
26///         observer::Termination,
27///         operators::creating::from_future::FromFuture,
28///     };
29///     use std::sync::{Arc, Mutex};
30///     use tokio::time::{sleep, Duration};
31///
32///     let values = Arc::new(Mutex::new(Vec::new()));
33///     let terminations = Arc::new(Mutex::new(Vec::new()));
34///     let values_observer = Arc::clone(&values);
35///     let terminations_observer = Arc::clone(&terminations);
36///     let handle = tokio::runtime::Handle::current();
37///
38///     let subscription = FromFuture::new(async { 7 }, handle).subscribe_with_callback(
39///         move |value| values_observer.lock().unwrap().push(value),
40///         move |termination| terminations_observer
41///             .lock()
42///             .unwrap()
43///             .push(termination),
44///     );
45///
46///     sleep(Duration::from_millis(10)).await;
47///     drop(subscription);
48///
49///     assert_eq!(&*values.lock().unwrap(), &[7]);
50///     assert_eq!(
51///         &*terminations.lock().unwrap(),
52///         &[Termination::Completed]
53///     );
54/// }
55/// ```
56#[derive(Educe)]
57#[educe(Debug, Clone)]
58pub struct FromFuture<FU, S> {
59    future: FU,
60    scheduler: S,
61}
62
63impl<FU, S> FromFuture<FU, S> {
64    pub fn new(future: FU, scheduler: S) -> Self {
65        Self { future, scheduler }
66    }
67}
68
69impl<T, FU, S> Observable<'static, T, Infallible> for FromFuture<FU, S>
70where
71    FU: Future<Output = T> + MaybeSend + 'static,
72    S: Scheduler,
73{
74    type D = S::D;
75
76    fn subscribe(
77        self,
78        mut observer: impl Observer<T, Infallible> + MaybeSend + 'static,
79    ) -> Subscription<Self::D> {
80        self.scheduler.spawn_future(async {
81            let result = self.future.await;
82            if observer.on_next(result).is_continue() {
83                observer.on_termination(Termination::Completed);
84            }
85        })
86    }
87}