1 use crate::*;
2 
3 use std::future::Future;
4 use std::pin::Pin;
5 
6 pub type BindRtcpReaderFn = Box<
7     dyn (Fn(
8             Arc<dyn RTCPReader + Send + Sync>,
9         )
10             -> Pin<Box<dyn Future<Output = Arc<dyn RTCPReader + Send + Sync>> + Send + Sync>>)
11         + Send
12         + Sync,
13 >;
14 
15 pub type BindRtcpWriterFn = Box<
16     dyn (Fn(
17             Arc<dyn RTCPWriter + Send + Sync>,
18         )
19             -> Pin<Box<dyn Future<Output = Arc<dyn RTCPWriter + Send + Sync>> + Send + Sync>>)
20         + Send
21         + Sync,
22 >;
23 pub type BindLocalStreamFn = Box<
24     dyn (Fn(
25             &StreamInfo,
26             Arc<dyn RTPWriter + Send + Sync>,
27         ) -> Pin<Box<dyn Future<Output = Arc<dyn RTPWriter + Send + Sync>> + Send + Sync>>)
28         + Send
29         + Sync,
30 >;
31 pub type UnbindLocalStreamFn =
32     Box<dyn (Fn(&StreamInfo) -> Pin<Box<dyn Future<Output = ()> + Send + Sync>>) + Send + Sync>;
33 pub type BindRemoteStreamFn = Box<
34     dyn (Fn(
35             &StreamInfo,
36             Arc<dyn RTPReader + Send + Sync>,
37         ) -> Pin<Box<dyn Future<Output = Arc<dyn RTPReader + Send + Sync>> + Send + Sync>>)
38         + Send
39         + Sync,
40 >;
41 pub type UnbindRemoteStreamFn =
42     Box<dyn (Fn(&StreamInfo) -> Pin<Box<dyn Future<Output = ()> + Send + Sync>>) + Send + Sync>;
43 pub type CloseFn =
44     Box<dyn (Fn() -> Pin<Box<dyn Future<Output = Result<()>> + Send + Sync>>) + Send + Sync>;
45 
46 /// MockInterceptor is an mock Interceptor fot testing.
47 #[derive(Default)]
48 pub struct MockInterceptor {
49     pub bind_rtcp_reader_fn: Option<BindRtcpReaderFn>,
50     pub bind_rtcp_writer_fn: Option<BindRtcpWriterFn>,
51     pub bind_local_stream_fn: Option<BindLocalStreamFn>,
52     pub unbind_local_stream_fn: Option<UnbindLocalStreamFn>,
53     pub bind_remote_stream_fn: Option<BindRemoteStreamFn>,
54     pub unbind_remote_stream_fn: Option<UnbindRemoteStreamFn>,
55     pub close_fn: Option<CloseFn>,
56 }
57 
58 #[async_trait]
59 impl Interceptor for MockInterceptor {
60     /// bind_rtcp_reader lets you modify any incoming RTCP packets. It is called once per sender/receiver, however this might
61     /// change in the future. The returned method will be called once per packet batch.
bind_rtcp_reader( &self, reader: Arc<dyn RTCPReader + Send + Sync>, ) -> Arc<dyn RTCPReader + Send + Sync>62     async fn bind_rtcp_reader(
63         &self,
64         reader: Arc<dyn RTCPReader + Send + Sync>,
65     ) -> Arc<dyn RTCPReader + Send + Sync> {
66         if let Some(f) = &self.bind_rtcp_reader_fn {
67             f(reader).await
68         } else {
69             reader
70         }
71     }
72 
73     /// bind_rtcp_writer lets you modify any outgoing RTCP packets. It is called once per PeerConnection. The returned method
74     /// will be called once per packet batch.
bind_rtcp_writer( &self, writer: Arc<dyn RTCPWriter + Send + Sync>, ) -> Arc<dyn RTCPWriter + Send + Sync>75     async fn bind_rtcp_writer(
76         &self,
77         writer: Arc<dyn RTCPWriter + Send + Sync>,
78     ) -> Arc<dyn RTCPWriter + Send + Sync> {
79         if let Some(f) = &self.bind_rtcp_writer_fn {
80             f(writer).await
81         } else {
82             writer
83         }
84     }
85 
86     /// bind_local_stream lets you modify any outgoing RTP packets. It is called once for per LocalStream. The returned method
87     /// will be called once per rtp packet.
bind_local_stream( &self, info: &StreamInfo, writer: Arc<dyn RTPWriter + Send + Sync>, ) -> Arc<dyn RTPWriter + Send + Sync>88     async fn bind_local_stream(
89         &self,
90         info: &StreamInfo,
91         writer: Arc<dyn RTPWriter + Send + Sync>,
92     ) -> Arc<dyn RTPWriter + Send + Sync> {
93         if let Some(f) = &self.bind_local_stream_fn {
94             f(info, writer).await
95         } else {
96             writer
97         }
98     }
99 
100     /// unbind_local_stream is called when the Stream is removed. It can be used to clean up any data related to that track.
unbind_local_stream(&self, info: &StreamInfo)101     async fn unbind_local_stream(&self, info: &StreamInfo) {
102         if let Some(f) = &self.unbind_local_stream_fn {
103             f(info).await
104         }
105     }
106 
107     /// bind_remote_stream lets you modify any incoming RTP packets. It is called once for per RemoteStream. The returned method
108     /// will be called once per rtp packet.
bind_remote_stream( &self, info: &StreamInfo, reader: Arc<dyn RTPReader + Send + Sync>, ) -> Arc<dyn RTPReader + Send + Sync>109     async fn bind_remote_stream(
110         &self,
111         info: &StreamInfo,
112         reader: Arc<dyn RTPReader + Send + Sync>,
113     ) -> Arc<dyn RTPReader + Send + Sync> {
114         if let Some(f) = &self.bind_remote_stream_fn {
115             f(info, reader).await
116         } else {
117             reader
118         }
119     }
120 
121     /// unbind_remote_stream is called when the Stream is removed. It can be used to clean up any data related to that track.
unbind_remote_stream(&self, info: &StreamInfo)122     async fn unbind_remote_stream(&self, info: &StreamInfo) {
123         if let Some(f) = &self.unbind_remote_stream_fn {
124             f(info).await
125         }
126     }
127 
128     /// close closes the Interceptor, cleaning up any data if necessary.
close(&self) -> Result<()>129     async fn close(&self) -> Result<()> {
130         if let Some(f) = &self.close_fn {
131             f().await
132         } else {
133             Ok(())
134         }
135     }
136 }
137