rtc_interceptor/
noop.rs

1//! NoOp Interceptor - A pass-through terminal for interceptor chains.
2
3use crate::stream_info::StreamInfo;
4use crate::{Interceptor, TaggedPacket};
5use shared::error::Error;
6use std::collections::VecDeque;
7use std::time::Instant;
8
9/// A no-operation interceptor that simply queues messages for pass-through.
10///
11/// `NoopInterceptor` serves as the innermost layer of an interceptor chain.
12/// It accepts messages via `handle_read`/`handle_write`/etc and returns them
13/// unchanged via `poll_read`/`poll_write`/etc.
14///
15/// # Example
16///
17/// ```ignore
18/// use rtc_interceptor::NoopInterceptor;
19/// use sansio::Protocol;
20///
21/// let mut noop = NoopInterceptor::new();
22/// noop.handle_read(TaggedPacket::Rtp(...)).unwrap();
23/// assert!(noop.poll_read().is_some());
24/// ```
25pub struct NoopInterceptor {
26    write_queue: VecDeque<TaggedPacket>,
27}
28
29impl NoopInterceptor {
30    /// Create a new NoopInterceptor.
31    pub fn new() -> Self {
32        Self {
33            write_queue: VecDeque::new(),
34        }
35    }
36}
37
38impl Default for NoopInterceptor {
39    fn default() -> Self {
40        Self::new()
41    }
42}
43
44impl sansio::Protocol<TaggedPacket, TaggedPacket, ()> for NoopInterceptor {
45    type Rout = TaggedPacket;
46    type Wout = TaggedPacket;
47    type Eout = ();
48    type Error = Error;
49    type Time = Instant;
50
51    fn handle_read(&mut self, _msg: TaggedPacket) -> Result<(), Self::Error> {
52        Ok(())
53    }
54
55    fn poll_read(&mut self) -> Option<Self::Rout> {
56        None
57    }
58
59    fn handle_write(&mut self, msg: TaggedPacket) -> Result<(), Self::Error> {
60        self.write_queue.push_back(msg);
61        Ok(())
62    }
63
64    fn poll_write(&mut self) -> Option<Self::Wout> {
65        self.write_queue.pop_front()
66    }
67
68    fn handle_event(&mut self, _evt: ()) -> Result<(), Self::Error> {
69        Ok(())
70    }
71
72    fn poll_event(&mut self) -> Option<Self::Eout> {
73        None
74    }
75
76    fn handle_timeout(&mut self, _now: Self::Time) -> Result<(), Self::Error> {
77        Ok(())
78    }
79
80    fn poll_timeout(&mut self) -> Option<Self::Time> {
81        None
82    }
83
84    fn close(&mut self) -> Result<(), Self::Error> {
85        self.write_queue.clear();
86        Ok(())
87    }
88}
89
90impl Interceptor for NoopInterceptor {
91    fn bind_local_stream(&mut self, _info: &StreamInfo) {}
92    fn unbind_local_stream(&mut self, _info: &StreamInfo) {}
93    fn bind_remote_stream(&mut self, _info: &StreamInfo) {}
94    fn unbind_remote_stream(&mut self, _info: &StreamInfo) {}
95}
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100    use sansio::Protocol;
101
102    fn dummy_rtp_packet() -> TaggedPacket {
103        TaggedPacket {
104            now: Instant::now(),
105            transport: Default::default(),
106            message: crate::Packet::Rtp(rtp::Packet::default()),
107        }
108    }
109
110    #[test]
111    fn test_noop_read_write() {
112        let mut noop = NoopInterceptor::new();
113
114        // Test read
115        let pkt1 = dummy_rtp_packet();
116        let pkt2 = dummy_rtp_packet();
117        noop.handle_read(pkt1).unwrap();
118        noop.handle_read(pkt2).unwrap();
119        assert!(noop.poll_read().is_none());
120
121        // Test write
122        let pkt3 = dummy_rtp_packet();
123        let pkt4 = dummy_rtp_packet();
124        let pkt3_message = pkt3.message.clone();
125        let pkt4_message = pkt4.message.clone();
126        noop.handle_write(pkt3).unwrap();
127        noop.handle_write(pkt4).unwrap();
128        assert_eq!(noop.poll_write().unwrap().message, pkt3_message);
129        assert_eq!(noop.poll_write().unwrap().message, pkt4_message);
130        assert!(noop.poll_write().is_none());
131    }
132
133    #[test]
134    fn test_noop_close_clears_queues() {
135        let mut noop = NoopInterceptor::new();
136
137        noop.handle_read(dummy_rtp_packet()).unwrap();
138        noop.handle_write(dummy_rtp_packet()).unwrap();
139
140        noop.close().unwrap();
141
142        assert!(noop.poll_read().is_none());
143        assert!(noop.poll_write().is_none());
144    }
145}