rx_rust/operators/conditional_boolean/
contains.rs1use crate::utils::subscribe_with_auto_dispose_on_termination;
2use crate::utils::subscribe_with_auto_dispose_on_termination::subscribe_with_auto_dispose_on_termination;
3use crate::utils::types::MaybeSend;
4use crate::{
5 observable::{Observable, Subscription},
6 observer::{Flow, Observer, Termination},
7};
8use educe::Educe;
9
10#[derive(Educe)]
37#[educe(Debug, Clone)]
38pub struct Contains<T, OE> {
39 source: OE,
40 item: T,
41}
42
43impl<T, OE> Contains<T, OE> {
44 pub fn new<'or, E>(source: OE, item: T) -> Self
45 where
46 OE: Observable<'or, T, E>,
47 {
48 Self { source, item }
49 }
50}
51
52impl<'or, T, E, OE> Observable<'or, bool, E> for Contains<T, OE>
53where
54 OE: Observable<'or, T, E>,
55 OE::D: MaybeSend + 'or,
56 T: PartialEq + MaybeSend + 'or,
57{
58 type D = subscribe_with_auto_dispose_on_termination::Disposal<OE::D>;
59
60 fn subscribe(
61 self,
62 observer: impl Observer<bool, E> + MaybeSend + 'or,
63 ) -> Subscription<Self::D> {
64 subscribe_with_auto_dispose_on_termination(observer, |observer| {
65 let observer = ContainsObserver {
66 observer: Some(observer),
67 item: self.item,
68 };
69 self.source.subscribe(observer)
70 })
71 }
72}
73
74struct ContainsObserver<T, OR> {
75 observer: Option<OR>,
76 item: T,
77}
78
79impl<T, E, OR> Observer<T, E> for ContainsObserver<T, OR>
80where
81 OR: Observer<bool, E>,
82 T: PartialEq,
83{
84 fn on_next(&mut self, value: T) -> Flow {
85 if self.item != value {
86 return Flow::Continue;
87 }
88 let Some(mut observer) = self.observer.take() else {
90 return Flow::Stop;
91 };
92 if observer.on_next(true).is_continue() {
93 observer.on_termination(Termination::Completed);
94 }
95 Flow::Stop
96 }
97
98 fn on_termination(mut self, termination: Termination<E>) {
99 if let Some(mut observer) = self.observer.take() {
100 match termination {
101 Termination::Completed => drop(observer.on_next(false)),
102 Termination::Error(_) => {}
103 }
104 observer.on_termination(termination);
105 }
106 }
107}