1 use serde::{Deserialize, Serialize};
2 use std::fmt;
3 
4 /// SDPType describes the type of an SessionDescription.
5 #[derive(Default, Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
6 pub enum RTCSdpType {
7     #[default]
8     Unspecified = 0,
9 
10     /// indicates that a description MUST be treated as an SDP offer.
11     #[serde(rename = "offer")]
12     Offer,
13 
14     /// indicates that a description MUST be treated as an
15     /// SDP answer, but not a final answer. A description used as an SDP
16     /// pranswer may be applied as a response to an SDP offer, or an update to
17     /// a previously sent SDP pranswer.
18     #[serde(rename = "pranswer")]
19     Pranswer,
20 
21     /// indicates that a description MUST be treated as an SDP
22     /// final answer, and the offer-answer exchange MUST be considered complete.
23     /// A description used as an SDP answer may be applied as a response to an
24     /// SDP offer or as an update to a previously sent SDP pranswer.
25     #[serde(rename = "answer")]
26     Answer,
27 
28     /// indicates that a description MUST be treated as
29     /// canceling the current SDP negotiation and moving the SDP offer and
30     /// answer back to what it was in the previous stable state. Note the
31     /// local or remote SDP descriptions in the previous stable state could be
32     /// null if there has not yet been a successful offer-answer negotiation.
33     #[serde(rename = "rollback")]
34     Rollback,
35 }
36 
37 const SDP_TYPE_OFFER_STR: &str = "offer";
38 const SDP_TYPE_PRANSWER_STR: &str = "pranswer";
39 const SDP_TYPE_ANSWER_STR: &str = "answer";
40 const SDP_TYPE_ROLLBACK_STR: &str = "rollback";
41 
42 /// creates an SDPType from a string
43 impl From<&str> for RTCSdpType {
from(raw: &str) -> Self44     fn from(raw: &str) -> Self {
45         match raw {
46             SDP_TYPE_OFFER_STR => RTCSdpType::Offer,
47             SDP_TYPE_PRANSWER_STR => RTCSdpType::Pranswer,
48             SDP_TYPE_ANSWER_STR => RTCSdpType::Answer,
49             SDP_TYPE_ROLLBACK_STR => RTCSdpType::Rollback,
50             _ => RTCSdpType::Unspecified,
51         }
52     }
53 }
54 
55 impl fmt::Display for RTCSdpType {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result56     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57         match *self {
58             RTCSdpType::Offer => write!(f, "{SDP_TYPE_OFFER_STR}"),
59             RTCSdpType::Pranswer => write!(f, "{SDP_TYPE_PRANSWER_STR}"),
60             RTCSdpType::Answer => write!(f, "{SDP_TYPE_ANSWER_STR}"),
61             RTCSdpType::Rollback => write!(f, "{SDP_TYPE_ROLLBACK_STR}"),
62             _ => write!(f, "{}", crate::UNSPECIFIED_STR),
63         }
64     }
65 }
66 
67 #[cfg(test)]
68 mod test {
69     use super::*;
70 
71     #[test]
test_new_sdp_type()72     fn test_new_sdp_type() {
73         let tests = vec![
74             ("Unspecified", RTCSdpType::Unspecified),
75             ("offer", RTCSdpType::Offer),
76             ("pranswer", RTCSdpType::Pranswer),
77             ("answer", RTCSdpType::Answer),
78             ("rollback", RTCSdpType::Rollback),
79         ];
80 
81         for (sdp_type_string, expected_sdp_type) in tests {
82             assert_eq!(RTCSdpType::from(sdp_type_string), expected_sdp_type);
83         }
84     }
85 
86     #[test]
test_sdp_type_string()87     fn test_sdp_type_string() {
88         let tests = vec![
89             (RTCSdpType::Unspecified, "Unspecified"),
90             (RTCSdpType::Offer, "offer"),
91             (RTCSdpType::Pranswer, "pranswer"),
92             (RTCSdpType::Answer, "answer"),
93             (RTCSdpType::Rollback, "rollback"),
94         ];
95 
96         for (sdp_type, expected_string) in tests {
97             assert_eq!(sdp_type.to_string(), expected_string);
98         }
99     }
100 }
101