mj_controller/pollers/
feed.rs1use super::*;
2
3pub trait FeedSource {
6 type Item;
7
8 fn wait(&mut self) -> impl Future<Output = Option<Self::Item>>;
10
11 fn poll_now(&mut self) -> Option<Self::Item>;
12}
13
14impl<T> FeedSource for tokio::sync::mpsc::Receiver<T> {
15 type Item = T;
16
17 fn wait(&mut self) -> impl Future<Output = Option<T>> {
18 self.recv()
19 }
20
21 fn poll_now(&mut self) -> Option<T> {
22 self.try_recv().ok()
23 }
24}
25
26impl<T> FeedSource for tokio::sync::mpsc::UnboundedReceiver<T> {
27 type Item = T;
28
29 fn wait(&mut self) -> impl Future<Output = Option<T>> {
30 self.recv()
31 }
32
33 fn poll_now(&mut self) -> Option<T> {
34 self.try_recv().ok()
35 }
36}
37
38impl<T: Clone> FeedSource for tokio::sync::watch::Receiver<T> {
39 type Item = T;
40
41 async fn wait(&mut self) -> Option<T> {
42 self.changed().await.ok()?;
43 Some(self.borrow_and_update().clone())
44 }
45
46 fn poll_now(&mut self) -> Option<T> {
47 self.has_changed()
48 .ok()
49 .filter(|changed| *changed)
50 .map(|_| self.borrow_and_update().clone())
51 }
52}
53
54impl FeedSource for SessionManagerUpdates {
55 type Item = SessionManagerUpdate;
56
57 fn wait(&mut self) -> impl Future<Output = Option<SessionManagerUpdate>> {
58 self.recv()
59 }
60
61 fn poll_now(&mut self) -> Option<SessionManagerUpdate> {
62 self.try_recv().ok()
63 }
64}
65
66impl FeedSource for RecoveryCoordinator {
67 type Item = RecoveryResult;
68
69 fn wait(&mut self) -> impl Future<Output = Option<RecoveryResult>> {
70 self.result()
71 }
72
73 fn poll_now(&mut self) -> Option<RecoveryResult> {
74 self.try_result()
75 }
76}
77
78impl FeedSource for CredentialSyncCoordinator {
79 type Item = mj_core::credentials::CredentialSyncResult;
80
81 fn wait(&mut self) -> impl Future<Output = Option<Self::Item>> {
82 self.result()
83 }
84
85 fn poll_now(&mut self) -> Option<Self::Item> {
86 self.try_result()
87 }
88}
89
90pub struct Feed<S: FeedSource> {
98 pub(super) source: S,
99 pub(super) pending: Option<S::Item>,
100 pub(super) open: bool,
101 pub(super) delivered: bool,
105}
106
107impl<S: FeedSource> Feed<S> {
108 pub fn new(source: S) -> Self {
109 Self {
110 source,
111 pending: None,
112 open: true,
113 delivered: false,
114 }
115 }
116
117 pub fn is_open(&self) -> bool {
118 self.open
119 }
120
121 pub fn wait(&mut self) -> impl Future<Output = Option<S::Item>> {
122 self.source.wait()
123 }
124
125 pub fn accept(&mut self, message: Option<S::Item>) -> bool {
128 match message {
129 Some(message) => {
130 self.pending = Some(message);
131 true
132 }
133 None => {
134 self.open = false;
135 false
136 }
137 }
138 }
139
140 pub fn next_ready(&mut self) -> Option<S::Item> {
143 let message = self.pending.take().or_else(|| self.source.poll_now());
144 self.delivered |= message.is_some();
145 message
146 }
147
148 pub fn take_delivered(&mut self) -> bool {
150 std::mem::take(&mut self.delivered)
151 }
152}