rtc_interceptor/
registry.rs1use crate::Interceptor;
23use crate::noop::NoopInterceptor;
24
25#[derive(Clone)]
63pub struct Registry<P> {
64 inner: P,
65}
66
67impl Registry<NoopInterceptor> {
68 pub fn new() -> Self {
80 Registry {
81 inner: NoopInterceptor::new(),
82 }
83 }
84}
85
86impl Default for Registry<NoopInterceptor> {
87 fn default() -> Self {
88 Self::new()
89 }
90}
91
92impl<P: Interceptor> Registry<P> {
93 pub fn from(inner: P) -> Self {
102 Registry { inner }
103 }
104
105 pub fn with<O, F>(self, f: F) -> Registry<O>
117 where
118 F: FnOnce(P) -> O,
119 O: Interceptor,
120 {
121 Registry {
122 inner: f(self.inner),
123 }
124 }
125
126 pub fn build(self) -> P {
137 self.inner
138 }
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144 use crate::TaggedPacket;
145 use sansio::Protocol;
146 use shared::error::Error;
147 use std::time::Instant;
148
149 fn dummy_rtp_packet() -> TaggedPacket {
150 TaggedPacket {
151 now: Instant::now(),
152 transport: Default::default(),
153 message: crate::Packet::Rtp(rtp::Packet::default()),
154 }
155 }
156
157 struct TestInterceptor<P> {
159 inner: P,
160 name: &'static str,
161 }
162
163 impl<P> TestInterceptor<P> {
164 fn new(inner: P) -> Self {
165 Self {
166 inner,
167 name: "test",
168 }
169 }
170
171 fn with_name(name: &'static str) -> impl FnOnce(P) -> Self {
172 move |inner| Self { inner, name }
173 }
174 }
175
176 impl<P: Interceptor> Protocol<TaggedPacket, TaggedPacket, ()> for TestInterceptor<P> {
177 type Rout = TaggedPacket;
178 type Wout = TaggedPacket;
179 type Eout = ();
180 type Error = Error;
181 type Time = Instant;
182
183 fn handle_read(&mut self, msg: TaggedPacket) -> Result<(), Self::Error> {
184 self.inner.handle_read(msg)
185 }
186
187 fn poll_read(&mut self) -> Option<Self::Rout> {
188 self.inner.poll_read()
189 }
190
191 fn handle_write(&mut self, msg: TaggedPacket) -> Result<(), Self::Error> {
192 self.inner.handle_write(msg)
193 }
194
195 fn poll_write(&mut self) -> Option<Self::Wout> {
196 self.inner.poll_write()
197 }
198 }
199
200 impl<P: Interceptor> Interceptor for TestInterceptor<P> {
201 fn bind_local_stream(&mut self, info: &crate::StreamInfo) {
202 self.inner.bind_local_stream(info);
203 }
204 fn unbind_local_stream(&mut self, info: &crate::StreamInfo) {
205 self.inner.unbind_local_stream(info);
206 }
207 fn bind_remote_stream(&mut self, info: &crate::StreamInfo) {
208 self.inner.bind_remote_stream(info);
209 }
210 fn unbind_remote_stream(&mut self, info: &crate::StreamInfo) {
211 self.inner.unbind_remote_stream(info);
212 }
213 }
214
215 #[test]
216 fn test_registry_new() {
217 let registry = Registry::new();
218 let mut chain = registry.build();
219 let pkt = dummy_rtp_packet();
220 chain.handle_read(pkt).unwrap();
221 assert!(chain.poll_read().is_none());
222 }
223
224 #[test]
225 fn test_registry_with_single_interceptor() {
226 let registry = Registry::new().with(TestInterceptor::new);
227 let mut chain = registry.build();
228
229 let pkt = dummy_rtp_packet();
230 chain.handle_read(pkt).unwrap();
231 assert!(chain.poll_read().is_none());
232 assert_eq!(chain.name, "test");
233 }
234
235 #[test]
236 fn test_registry_with_multiple_interceptors() {
237 let registry = Registry::new()
238 .with(TestInterceptor::with_name("inner"))
239 .with(TestInterceptor::with_name("outer"));
240 let mut chain = registry.build();
241
242 let pkt = dummy_rtp_packet();
243 chain.handle_read(pkt).unwrap();
244 assert!(chain.poll_read().is_none());
245 assert_eq!(chain.name, "outer");
246 assert_eq!(chain.inner.name, "inner");
247 }
248
249 #[test]
250 fn test_registry_from_inner() {
251 let custom = NoopInterceptor::new();
252 let registry = Registry::from(custom).with(TestInterceptor::new);
253 let mut chain = registry.build();
254
255 let pkt = dummy_rtp_packet();
256 let pkt_message = pkt.message.clone();
257 chain.handle_write(pkt).unwrap();
258 assert_eq!(chain.poll_write().unwrap().message, pkt_message);
259 }
260
261 fn register_test_interceptors<P: Interceptor>(
263 registry: Registry<P>,
264 ) -> Registry<TestInterceptor<TestInterceptor<P>>> {
265 registry
266 .with(TestInterceptor::with_name("first"))
267 .with(TestInterceptor::with_name("second"))
268 }
269
270 #[test]
271 fn test_helper_function_pattern() {
272 let registry = Registry::new();
273 let registry = register_test_interceptors(registry);
274 let mut chain = registry.build();
275
276 let pkt = dummy_rtp_packet();
277 chain.handle_read(pkt).unwrap();
278 assert!(chain.poll_read().is_none());
279 assert_eq!(chain.name, "second");
280 assert_eq!(chain.inner.name, "first");
281 }
282}