cdp_lite/
event_filter.rs

1use std::pin::Pin;
2use std::task::{Context, Poll};
3use crate::protocol::WsResponse;
4use tokio_stream::{Stream, wrappers::BroadcastStream};
5use crate::error::CdpResult;
6
7pub struct EventFilter {
8    inner: BroadcastStream<WsResponse>,
9    prefix: String,
10}
11
12impl EventFilter {
13    pub fn new(receiver: tokio::sync::broadcast::Receiver<WsResponse>, domain: &'static str) -> Self {
14        Self {
15            inner: BroadcastStream::new(receiver),
16            prefix: format!("{}.", domain),
17        }
18    }
19}
20
21impl Stream for EventFilter {
22    type Item = CdpResult<WsResponse>;
23
24    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
25        loop {
26            match Pin::new(&mut self.inner).poll_next(cx) {
27                Poll::Ready(Some(Ok(response))) => {
28                    if let Some(ref method) = response.method {
29                        if method.starts_with(&self.prefix) {
30                            return Poll::Ready(Some(Ok(response)));
31                        }
32                    }
33                    // Not the domain we want, loop again to poll next
34                    continue;
35                }
36                Poll::Ready(Some(Err(e))) => {
37                    // This 'Err' is specifically a BroadcastStreamRecvError::Lagged
38                    return Poll::Ready(Some(Err(crate::error::CdpError::InternalError(
39                        format!("Event stream lagged: {}", e)
40                    ))));
41                }
42                Poll::Ready(None) => return Poll::Ready(None), // Channel closed
43                Poll::Pending => return Poll::Pending,
44            }
45        }
46    }
47}