1 use std::fmt; 2 3 /// RTPTransceiverDirection indicates the direction of the RTPTransceiver. 4 #[derive(Debug, Copy, Clone, PartialEq, Eq)] 5 pub enum RTCRtpTransceiverDirection { 6 Unspecified, 7 8 /// Sendrecv indicates the RTPSender will offer 9 /// to send RTP and RTPReceiver the will offer to receive RTP. 10 Sendrecv, 11 12 /// Sendonly indicates the RTPSender will offer to send RTP. 13 Sendonly, 14 15 /// Recvonly indicates the RTPReceiver the will offer to receive RTP. 16 Recvonly, 17 18 /// Inactive indicates the RTPSender won't offer 19 /// to send RTP and RTPReceiver the won't offer to receive RTP. 20 Inactive, 21 } 22 23 const RTP_TRANSCEIVER_DIRECTION_SENDRECV_STR: &str = "sendrecv"; 24 const RTP_TRANSCEIVER_DIRECTION_SENDONLY_STR: &str = "sendonly"; 25 const RTP_TRANSCEIVER_DIRECTION_RECVONLY_STR: &str = "recvonly"; 26 const RTP_TRANSCEIVER_DIRECTION_INACTIVE_STR: &str = "inactive"; 27 28 /// defines a procedure for creating a new 29 /// RTPTransceiverDirection from a raw string naming the transceiver direction. 30 impl From<&str> for RTCRtpTransceiverDirection { from(raw: &str) -> Self31 fn from(raw: &str) -> Self { 32 match raw { 33 RTP_TRANSCEIVER_DIRECTION_SENDRECV_STR => RTCRtpTransceiverDirection::Sendrecv, 34 RTP_TRANSCEIVER_DIRECTION_SENDONLY_STR => RTCRtpTransceiverDirection::Sendonly, 35 RTP_TRANSCEIVER_DIRECTION_RECVONLY_STR => RTCRtpTransceiverDirection::Recvonly, 36 RTP_TRANSCEIVER_DIRECTION_INACTIVE_STR => RTCRtpTransceiverDirection::Inactive, 37 _ => RTCRtpTransceiverDirection::Unspecified, 38 } 39 } 40 } 41 42 impl From<u8> for RTCRtpTransceiverDirection { from(v: u8) -> Self43 fn from(v: u8) -> Self { 44 match v { 45 1 => RTCRtpTransceiverDirection::Sendrecv, 46 2 => RTCRtpTransceiverDirection::Sendonly, 47 3 => RTCRtpTransceiverDirection::Recvonly, 48 4 => RTCRtpTransceiverDirection::Inactive, 49 _ => RTCRtpTransceiverDirection::Unspecified, 50 } 51 } 52 } 53 54 impl fmt::Display for RTCRtpTransceiverDirection { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 56 match *self { 57 RTCRtpTransceiverDirection::Sendrecv => { 58 write!(f, "{RTP_TRANSCEIVER_DIRECTION_SENDRECV_STR}") 59 } 60 RTCRtpTransceiverDirection::Sendonly => { 61 write!(f, "{RTP_TRANSCEIVER_DIRECTION_SENDONLY_STR}") 62 } 63 RTCRtpTransceiverDirection::Recvonly => { 64 write!(f, "{RTP_TRANSCEIVER_DIRECTION_RECVONLY_STR}") 65 } 66 RTCRtpTransceiverDirection::Inactive => { 67 write!(f, "{RTP_TRANSCEIVER_DIRECTION_INACTIVE_STR}") 68 } 69 _ => write!(f, "{}", crate::UNSPECIFIED_STR), 70 } 71 } 72 } 73 74 impl RTCRtpTransceiverDirection { 75 /// reverse indicate the opposite direction reverse(&self) -> RTCRtpTransceiverDirection76 pub fn reverse(&self) -> RTCRtpTransceiverDirection { 77 match *self { 78 RTCRtpTransceiverDirection::Sendonly => RTCRtpTransceiverDirection::Recvonly, 79 RTCRtpTransceiverDirection::Recvonly => RTCRtpTransceiverDirection::Sendonly, 80 _ => *self, 81 } 82 } 83 intersect(&self, other: RTCRtpTransceiverDirection) -> RTCRtpTransceiverDirection84 pub fn intersect(&self, other: RTCRtpTransceiverDirection) -> RTCRtpTransceiverDirection { 85 Self::from_send_recv( 86 self.has_send() && other.has_send(), 87 self.has_recv() && other.has_recv(), 88 ) 89 } 90 from_send_recv(send: bool, recv: bool) -> RTCRtpTransceiverDirection91 pub fn from_send_recv(send: bool, recv: bool) -> RTCRtpTransceiverDirection { 92 match (send, recv) { 93 (true, true) => Self::Sendrecv, 94 (true, false) => Self::Sendonly, 95 (false, true) => Self::Recvonly, 96 (false, false) => Self::Inactive, 97 } 98 } 99 has_send(&self) -> bool100 pub fn has_send(&self) -> bool { 101 matches!(self, Self::Sendrecv | Self::Sendonly) 102 } 103 has_recv(&self) -> bool104 pub fn has_recv(&self) -> bool { 105 matches!(self, Self::Sendrecv | Self::Recvonly) 106 } 107 } 108 109 #[cfg(test)] 110 mod test { 111 use super::*; 112 113 #[test] test_new_rtp_transceiver_direction()114 fn test_new_rtp_transceiver_direction() { 115 let tests = vec![ 116 ("Unspecified", RTCRtpTransceiverDirection::Unspecified), 117 ("sendrecv", RTCRtpTransceiverDirection::Sendrecv), 118 ("sendonly", RTCRtpTransceiverDirection::Sendonly), 119 ("recvonly", RTCRtpTransceiverDirection::Recvonly), 120 ("inactive", RTCRtpTransceiverDirection::Inactive), 121 ]; 122 123 for (ct_str, expected_type) in tests { 124 assert_eq!(RTCRtpTransceiverDirection::from(ct_str), expected_type); 125 } 126 } 127 128 #[test] test_rtp_transceiver_direction_string()129 fn test_rtp_transceiver_direction_string() { 130 let tests = vec![ 131 (RTCRtpTransceiverDirection::Unspecified, "Unspecified"), 132 (RTCRtpTransceiverDirection::Sendrecv, "sendrecv"), 133 (RTCRtpTransceiverDirection::Sendonly, "sendonly"), 134 (RTCRtpTransceiverDirection::Recvonly, "recvonly"), 135 (RTCRtpTransceiverDirection::Inactive, "inactive"), 136 ]; 137 138 for (d, expected_string) in tests { 139 assert_eq!(d.to_string(), expected_string); 140 } 141 } 142 143 #[test] test_rtp_transceiver_has_send()144 fn test_rtp_transceiver_has_send() { 145 let tests = vec![ 146 (RTCRtpTransceiverDirection::Unspecified, false), 147 (RTCRtpTransceiverDirection::Sendrecv, true), 148 (RTCRtpTransceiverDirection::Sendonly, true), 149 (RTCRtpTransceiverDirection::Recvonly, false), 150 (RTCRtpTransceiverDirection::Inactive, false), 151 ]; 152 153 for (d, expected_value) in tests { 154 assert_eq!(d.has_send(), expected_value); 155 } 156 } 157 158 #[test] test_rtp_transceiver_has_recv()159 fn test_rtp_transceiver_has_recv() { 160 let tests = vec![ 161 (RTCRtpTransceiverDirection::Unspecified, false), 162 (RTCRtpTransceiverDirection::Sendrecv, true), 163 (RTCRtpTransceiverDirection::Sendonly, false), 164 (RTCRtpTransceiverDirection::Recvonly, true), 165 (RTCRtpTransceiverDirection::Inactive, false), 166 ]; 167 168 for (d, expected_value) in tests { 169 assert_eq!(d.has_recv(), expected_value); 170 } 171 } 172 173 #[test] test_rtp_transceiver_from_send_recv()174 fn test_rtp_transceiver_from_send_recv() { 175 let tests = vec![ 176 (RTCRtpTransceiverDirection::Sendrecv, (true, true)), 177 (RTCRtpTransceiverDirection::Sendonly, (true, false)), 178 (RTCRtpTransceiverDirection::Recvonly, (false, true)), 179 (RTCRtpTransceiverDirection::Inactive, (false, false)), 180 ]; 181 182 for (expected_value, (send, recv)) in tests { 183 assert_eq!( 184 RTCRtpTransceiverDirection::from_send_recv(send, recv), 185 expected_value 186 ); 187 } 188 } 189 190 #[test] test_rtp_transceiver_intersect()191 fn test_rtp_transceiver_intersect() { 192 use RTCRtpTransceiverDirection::*; 193 194 let tests = vec![ 195 ((Sendrecv, Recvonly), Recvonly), 196 ((Sendrecv, Sendonly), Sendonly), 197 ((Sendrecv, Inactive), Inactive), 198 ((Sendonly, Inactive), Inactive), 199 ((Recvonly, Inactive), Inactive), 200 ((Recvonly, Sendrecv), Recvonly), 201 ((Sendonly, Sendrecv), Sendonly), 202 ((Sendonly, Recvonly), Inactive), 203 ((Recvonly, Recvonly), Recvonly), 204 ]; 205 206 for ((a, b), expected_direction) in tests { 207 assert_eq!(a.intersect(b), expected_direction); 208 } 209 } 210 } 211