Skip to main content

rx_rust/operators/creating/
timer.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, time::Duration};
9
10/// Creates an Observable that emits a single item after a given delay.
11/// See <https://reactivex.io/documentation/operators/timer.html>
12///
13/// # Examples
14/// ```rust
15/// # #[cfg(not(feature = "tokio-scheduler"))]
16/// # fn main() {}
17/// # #[cfg(feature = "tokio-scheduler")]
18/// #[tokio::main]
19/// async fn main() {
20///     use rx_rust::{
21///         observable::ObservableExt,
22///         observer::Termination,
23///         operators::creating::timer::Timer,
24///     };
25///     use std::sync::{Arc, Mutex};
26///     use std::time::Duration;
27///     use tokio::time::sleep;
28///
29///     let handle = tokio::runtime::Handle::current();
30///     let values = Arc::new(Mutex::new(Vec::new()));
31///     let terminations = Arc::new(Mutex::new(Vec::new()));
32///     let values_observer = Arc::clone(&values);
33///     let terminations_observer = Arc::clone(&terminations);
34///
35///     let subscription = Timer::new("tick", Duration::from_millis(5), handle)
36///         .subscribe_with_callback(
37///             move |value| values_observer.lock().unwrap().push(value),
38///             move |termination| terminations_observer
39///                 .lock()
40///                 .unwrap()
41///                 .push(termination),
42///         );
43///
44///     sleep(Duration::from_millis(10)).await;
45///     drop(subscription);
46///
47///     assert_eq!(&*values.lock().unwrap(), &["tick"]);
48///     assert_eq!(
49///         &*terminations.lock().unwrap(),
50///         &[Termination::Completed]
51///     );
52/// }
53/// ```
54#[derive(Educe)]
55#[educe(Debug, Clone)]
56pub struct Timer<T, S> {
57    value: T,
58    delay: Duration,
59    scheduler: S,
60}
61
62impl<T, S> Timer<T, S> {
63    pub fn new(value: T, delay: Duration, scheduler: S) -> Self {
64        Self {
65            value,
66            delay,
67            scheduler,
68        }
69    }
70}
71
72impl<T, S> Observable<'static, T, Infallible> for Timer<T, S>
73where
74    T: MaybeSend + 'static,
75    S: Scheduler,
76{
77    type D = S::D;
78
79    fn subscribe(
80        self,
81        mut observer: impl Observer<T, Infallible> + MaybeSend + 'static,
82    ) -> Subscription<Self::D> {
83        self.scheduler.schedule(
84            || {
85                if observer.on_next(self.value).is_continue() {
86                    observer.on_termination(Termination::Completed);
87                }
88            },
89            Some(self.delay),
90        )
91    }
92}