rx_rust/operators/utility/do_after_termination.rs
1use crate::utils::types::MaybeSend;
2use crate::{
3 observable::Observable,
4 observable::Subscription,
5 observer::{Flow, Observer, Termination},
6};
7use educe::Educe;
8
9/// Invokes a callback when the source Observable terminates (either completes or errors), after the termination notification has been emitted to the downstream observer.
10/// See <https://reactivex.io/documentation/operators/do.html>
11///
12/// # Examples
13/// ```rust
14/// use rx_rust::{
15/// observable::ObservableExt,
16/// observer::Termination,
17/// operators::{
18/// creating::from_iter::FromIter,
19/// utility::do_after_termination::DoAfterTermination,
20/// },
21/// };
22/// use std::sync::{Arc, Mutex};
23///
24/// let mut terminations = Vec::new();
25/// let callback_terminations = Arc::new(Mutex::new(Vec::new()));
26/// let callback_terminations_observer = Arc::clone(&callback_terminations);
27///
28/// DoAfterTermination::new(FromIter::new(vec![1, 2]), move |termination| {
29/// callback_terminations_observer
30/// .lock()
31/// .unwrap()
32/// .push(termination);
33/// })
34/// .subscribe_with_callback(
35/// |_| {},
36/// |termination| terminations.push(termination),
37/// );
38///
39/// assert_eq!(terminations, vec![Termination::Completed]);
40/// assert_eq!(
41/// &*callback_terminations.lock().unwrap(),
42/// &[Termination::Completed]
43/// );
44/// ```
45#[derive(Educe)]
46#[educe(Debug, Clone)]
47pub struct DoAfterTermination<OE, F> {
48 source: OE,
49 callback: F,
50}
51
52impl<OE, F> DoAfterTermination<OE, F> {
53 pub fn new<'or, T, E>(source: OE, callback: F) -> Self
54 where
55 OE: Observable<'or, T, E>,
56 F: FnOnce(Termination<E>),
57 {
58 Self { source, callback }
59 }
60}
61
62impl<'or, T, E, OE, F> Observable<'or, T, E> for DoAfterTermination<OE, F>
63where
64 T: 'or,
65 E: Clone + 'or,
66 OE: Observable<'or, T, E>,
67 F: FnOnce(Termination<E>) + MaybeSend + 'or,
68{
69 type D = OE::D;
70
71 fn subscribe(self, observer: impl Observer<T, E> + MaybeSend + 'or) -> Subscription<Self::D> {
72 self.source.subscribe(DoAfterTerminationObserver {
73 observer,
74 callback: self.callback,
75 })
76 }
77}
78
79struct DoAfterTerminationObserver<OR, F> {
80 observer: OR,
81 callback: F,
82}
83
84impl<T, E, OR, F> Observer<T, E> for DoAfterTerminationObserver<OR, F>
85where
86 E: Clone,
87 OR: Observer<T, E>,
88 F: FnOnce(Termination<E>),
89{
90 fn on_next(&mut self, value: T) -> Flow {
91 self.observer.on_next(value)
92 }
93
94 fn on_termination(self, termination: Termination<E>) {
95 self.observer.on_termination(termination.clone());
96 (self.callback)(termination);
97 }
98}