rx_rust/utils/
pending_events.rs1use crate::observer::{Event, Termination};
2use educe::Educe;
3use std::collections::VecDeque;
4
5#[derive(Educe)]
7#[educe(Debug, Clone, PartialEq, Eq)]
8pub enum EventBatch<T, E> {
9 Next(T),
10 Termination(Termination<E>),
11 NextAndTermination(T, Termination<E>),
12 NextBatch(Vec<T>),
13 NextBatchAndTermination(Vec<T>, Termination<E>),
14}
15
16impl<T, E> EventBatch<T, E> {
17 pub fn ends_stream(&self) -> bool {
19 matches!(
20 self,
21 Self::Termination(_) | Self::NextAndTermination(..) | Self::NextBatchAndTermination(..)
22 )
23 }
24}
25
26#[derive(Educe)]
33#[educe(Debug)]
34pub struct PendingEvents<T, E> {
35 values: VecDeque<T>,
36 termination: Option<Termination<E>>,
37}
38
39impl<T, E> PendingEvents<T, E> {
40 pub fn new() -> Self {
41 Self {
42 values: VecDeque::new(),
43 termination: None,
44 }
45 }
46
47 pub fn with_capacity(capacity: usize) -> Self {
48 Self {
49 values: VecDeque::with_capacity(capacity),
50 termination: None,
51 }
52 }
53
54 pub fn from_batch(events: EventBatch<T, E>) -> (Option<T>, Self) {
60 let empty_queue = |termination| Self {
61 values: VecDeque::new(),
62 termination,
63 };
64 let queue_batch = |values: Vec<T>, termination| {
67 let mut values = VecDeque::from(values);
68 let first_next = values.pop_front();
69 (
70 first_next,
71 Self {
72 values,
73 termination,
74 },
75 )
76 };
77 match events {
78 EventBatch::Next(value) => (Some(value), empty_queue(None)),
79 EventBatch::Termination(termination) => (None, empty_queue(Some(termination))),
80 EventBatch::NextAndTermination(value, termination) => {
81 (Some(value), empty_queue(Some(termination)))
82 }
83 EventBatch::NextBatch(values) => queue_batch(values, None),
84 EventBatch::NextBatchAndTermination(values, termination) => {
85 queue_batch(values, Some(termination))
86 }
87 }
88 }
89
90 pub fn is_terminated(&self) -> bool {
92 self.termination.is_some()
93 }
94
95 pub fn is_empty(&self) -> bool {
97 self.values.is_empty() && self.termination.is_none()
98 }
99
100 #[must_use = "a rejected event must be dropped outside the lock that guards these events"]
102 pub fn push(&mut self, event: Event<T, E>) -> Option<Event<T, E>> {
103 if self.is_terminated() {
104 return Some(event);
105 }
106 match event {
107 Event::Next(value) => self.values.push_back(value),
108 Event::Termination(termination) => self.termination = Some(termination),
109 }
110 None
111 }
112
113 #[must_use = "rejected events must be dropped outside the lock that guards these events"]
118 pub fn push_batch(&mut self, events: EventBatch<T, E>) -> Option<EventBatch<T, E>> {
119 if self.is_terminated() {
120 return Some(events);
121 }
122 match events {
123 EventBatch::Next(value) => self.values.push_back(value),
124 EventBatch::Termination(termination) => self.termination = Some(termination),
125 EventBatch::NextAndTermination(value, termination) => {
126 self.values.push_back(value);
127 self.termination = Some(termination);
128 }
129 EventBatch::NextBatch(values) => self.values.extend(values),
130 EventBatch::NextBatchAndTermination(values, termination) => {
131 self.values.extend(values);
132 self.termination = Some(termination);
133 }
134 }
135 None
136 }
137
138 pub fn pop(&mut self) -> Option<Event<T, E>> {
140 match self.pop_next() {
141 Some(value) => Some(Event::Next(value)),
142 None => self.take_termination().map(Event::Termination),
143 }
144 }
145
146 pub fn pop_next(&mut self) -> Option<T> {
148 self.values.pop_front()
149 }
150
151 pub fn take_termination(&mut self) -> Option<Termination<E>> {
153 self.termination.take()
154 }
155}
156
157impl<T, E> Default for PendingEvents<T, E> {
158 fn default() -> Self {
159 Self::new()
160 }
161}