rx_rust/operators/conditional_boolean/
take_until.rs1use crate::utils::subscribe_with_context::{
2 self, SubscriptionContext, subscribe_with_context_owning_source,
3};
4use crate::utils::types::MaybeSend;
5use crate::{
6 disposable::Disposable,
7 observable::{Observable, Subscription},
8 observer::{Flow, Observer, Termination},
9};
10use educe::Educe;
11
12#[derive(Educe)]
54#[educe(Debug, Clone)]
55pub struct TakeUntil<OE, OE1> {
56 source: OE,
57 stop: OE1,
58}
59
60impl<OE, OE1> TakeUntil<OE, OE1> {
61 pub fn new<'or, T, E>(source: OE, stop: OE1) -> Self
62 where
63 OE: Observable<'or, T, E>,
64 OE1: Observable<'or, (), E>,
65 {
66 Self { source, stop }
67 }
68}
69
70impl<'or, T, E, OE, OE1> Observable<'or, T, E> for TakeUntil<OE, OE1>
71where
72 T: MaybeSend + 'or,
73 E: MaybeSend + 'or,
74 OE: Observable<'or, T, E>,
75 OE::D: MaybeSend + 'or,
76 OE1: Observable<'or, (), E>,
77 OE1::D: MaybeSend + 'or,
78{
79 type D = subscribe_with_context::OwningDisposal<'or>;
80
81 fn subscribe(self, observer: impl Observer<T, E> + MaybeSend + 'or) -> Subscription<Self::D> {
82 subscribe_with_context_owning_source(observer, (), |context| {
83 let subscription_1 = self.stop.subscribe(StopObserver(context.clone()));
84 let subscription_2 = self.source.subscribe(TakeUntilObserver(context));
85 subscription_1.preceded_by_bound(subscription_2)
86 })
87 }
88}
89
90struct TakeUntilObserver<T, E, OR, D: Disposable>(SubscriptionContext<T, E, OR, (), D>);
91
92impl<T, E, OR, D> Observer<T, E> for TakeUntilObserver<T, E, OR, D>
93where
94 OR: Observer<T, E>,
95 D: Disposable,
96{
97 fn on_next(&mut self, value: T) -> Flow {
98 self.0.send_next(value)
99 }
100
101 fn on_termination(self, termination: Termination<E>) {
102 self.0.send_termination(termination);
103 }
104}
105
106struct StopObserver<T, E, OR, D: Disposable>(SubscriptionContext<T, E, OR, (), D>);
107
108impl<T, E, OR, D> Observer<(), E> for StopObserver<T, E, OR, D>
109where
110 OR: Observer<T, E>,
111 D: Disposable,
112{
113 fn on_next(&mut self, _: ()) -> Flow {
114 self.0.send_termination(Termination::Completed);
115 Flow::Stop
117 }
118
119 fn on_termination(self, termination: Termination<E>) {
120 self.0.send_termination(termination);
121 }
122}