rx_rust/operators/utility/
dematerialize.rs1use crate::utils::types::MaybeSend;
2use crate::{
3 observable::Observable,
4 observable::Subscription,
5 observer::{Event, Flow, Observer, Termination},
6 utils::subscribe_with_auto_dispose_on_termination::subscribe_with_auto_dispose_on_termination,
7};
8use educe::Educe;
9use std::convert::Infallible;
10
11#[derive(Educe)]
41#[educe(Debug, Clone)]
42pub struct Dematerialize<OE>(OE);
43
44impl<OE> Dematerialize<OE> {
45 pub fn new(source: OE) -> Self {
46 Self(source)
47 }
48}
49
50impl<'or, T, E, OE> Observable<'or, T, E> for Dematerialize<OE>
51where
52 OE: Observable<'or, Event<T, E>, Infallible>,
53 OE::D: MaybeSend + 'or,
54{
55 type D = crate::utils::subscribe_with_auto_dispose_on_termination::Disposal<OE::D>;
56
57 fn subscribe(self, observer: impl Observer<T, E> + MaybeSend + 'or) -> Subscription<Self::D> {
58 subscribe_with_auto_dispose_on_termination(observer, |observer| {
59 self.0.subscribe(DematerializeObserver(Some(observer)))
60 })
61 }
62}
63
64struct DematerializeObserver<OR>(Option<OR>);
65
66impl<T, E, OR> Observer<Event<T, E>, Infallible> for DematerializeObserver<OR>
67where
68 OR: Observer<T, E>,
69{
70 fn on_next(&mut self, value: Event<T, E>) -> Flow {
71 match value {
72 Event::Next(value) => match self.0.as_mut() {
73 Some(observer) => {
74 let flow = observer.on_next(value);
75 if flow.is_stop() {
76 drop(self.0.take());
77 }
78 flow
79 }
80 None => Flow::Stop,
82 },
83 Event::Termination(termination) => {
84 if let Some(observer) = self.0.take() {
85 observer.on_termination(termination);
86 }
87 Flow::Stop
90 }
91 }
92 }
93
94 fn on_termination(mut self, termination: Termination<Infallible>) {
95 match termination {
96 Termination::Completed => {
97 if let Some(observer) = self.0.take() {
98 observer.on_termination(Termination::Completed);
99 }
100 }
101 Termination::Error(error) => match error {},
103 }
104 }
105}