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    read_queue: VecDeque<TaggedPacket>,
27    write_queue: VecDeque<TaggedPacket>,
28}
29
30impl NoopInterceptor {
31    /// Create a new NoopInterceptor.
32    pub fn new() -> Self {
33        Self {
34            read_queue: VecDeque::new(),
35            write_queue: VecDeque::new(),
36        }
37    }
38}
39
40impl Default for NoopInterceptor {
41    fn default() -> Self {
42        Self::new()
43    }
44}
45
46impl sansio::Protocol<TaggedPacket, TaggedPacket, ()> for NoopInterceptor {
47    type Rout = TaggedPacket;
48    type Wout = TaggedPacket;
49    type Eout = ();
50    type Error = Error;
51    type Time = Instant;
52
53    fn handle_read(&mut self, msg: TaggedPacket) -> Result<(), Self::Error> {
54        self.read_queue.push_back(msg);
55        Ok(())
56    }
57
58    fn poll_read(&mut self) -> Option<Self::Rout> {
59        self.read_queue.pop_front()
60    }
61
62    fn handle_write(&mut self, msg: TaggedPacket) -> Result<(), Self::Error> {
63        self.write_queue.push_back(msg);
64        Ok(())
65    }
66
67    fn poll_write(&mut self) -> Option<Self::Wout> {
68        self.write_queue.pop_front()
69    }
70
71    fn handle_event(&mut self, _evt: ()) -> Result<(), Self::Error> {
72        Ok(())
73    }
74
75    fn poll_event(&mut self) -> Option<Self::Eout> {
76        None
77    }
78
79    fn handle_timeout(&mut self, _now: Self::Time) -> Result<(), Self::Error> {
80        Ok(())
81    }
82
83    fn poll_timeout(&mut self) -> Option<Self::Time> {
84        None
85    }
86
87    fn close(&mut self) -> Result<(), Self::Error> {
88        self.read_queue.clear();
89        self.write_queue.clear();
90        Ok(())
91    }
92}
93
94impl Interceptor for NoopInterceptor {
95    fn bind_local_stream(&mut self, _info: &StreamInfo) {}
96    fn unbind_local_stream(&mut self, _info: &StreamInfo) {}
97    fn bind_remote_stream(&mut self, _info: &StreamInfo) {}
98    fn unbind_remote_stream(&mut self, _info: &StreamInfo) {}
99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104    use sansio::Protocol;
105
106    fn dummy_rtp_packet() -> TaggedPacket {
107        TaggedPacket {
108            now: Instant::now(),
109            transport: Default::default(),
110            message: crate::Packet::Rtp(rtp::Packet::default()),
111        }
112    }
113
114    #[test]
115    fn test_noop_read_write() {
116        let mut noop = NoopInterceptor::new();
117
118        // Test read
119        let pkt1 = dummy_rtp_packet();
120        let pkt2 = dummy_rtp_packet();
121        let pkt1_message = pkt1.message.clone();
122        let pkt2_message = pkt2.message.clone();
123        noop.handle_read(pkt1).unwrap();
124        noop.handle_read(pkt2).unwrap();
125        assert_eq!(noop.poll_read().unwrap().message, pkt1_message);
126        assert_eq!(noop.poll_read().unwrap().message, pkt2_message);
127        assert!(noop.poll_read().is_none());
128
129        // Test write
130        let pkt3 = dummy_rtp_packet();
131        let pkt4 = dummy_rtp_packet();
132        let pkt3_message = pkt3.message.clone();
133        let pkt4_message = pkt4.message.clone();
134        noop.handle_write(pkt3).unwrap();
135        noop.handle_write(pkt4).unwrap();
136        assert_eq!(noop.poll_write().unwrap().message, pkt3_message);
137        assert_eq!(noop.poll_write().unwrap().message, pkt4_message);
138        assert!(noop.poll_write().is_none());
139    }
140
141    #[test]
142    fn test_noop_close_clears_queues() {
143        let mut noop = NoopInterceptor::new();
144
145        noop.handle_read(dummy_rtp_packet()).unwrap();
146        noop.handle_write(dummy_rtp_packet()).unwrap();
147
148        noop.close().unwrap();
149
150        assert!(noop.poll_read().is_none());
151        assert!(noop.poll_write().is_none());
152    }
153}