freeswitch_types/sofia/
sip_user.rs1use std::fmt;
4use std::str::FromStr;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct ParseSipUserPingStatusError(pub String);
9
10impl fmt::Display for ParseSipUserPingStatusError {
11 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12 write!(f, "unknown sip user ping status: {}", self.0)
13 }
14}
15
16impl std::error::Error for ParseSipUserPingStatusError {}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23#[non_exhaustive]
24#[allow(missing_docs)]
25pub enum SipUserPingStatus {
26 Unreachable,
27 Reachable,
28 Invalid,
29}
30
31impl SipUserPingStatus {
32 pub const fn as_str(&self) -> &'static str {
34 match self {
35 Self::Unreachable => "UNREACHABLE",
36 Self::Reachable => "REACHABLE",
37 Self::Invalid => "INVALID",
38 }
39 }
40}
41
42impl fmt::Display for SipUserPingStatus {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 f.write_str(self.as_str())
45 }
46}
47
48impl FromStr for SipUserPingStatus {
49 type Err = ParseSipUserPingStatusError;
50
51 fn from_str(s: &str) -> Result<Self, Self::Err> {
52 match s {
53 "UNREACHABLE" => Ok(Self::Unreachable),
54 "REACHABLE" => Ok(Self::Reachable),
55 "INVALID" => Ok(Self::Invalid),
56 _ => Err(ParseSipUserPingStatusError(s.to_string())),
57 }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 const ALL: &[SipUserPingStatus] = &[
66 SipUserPingStatus::Unreachable,
67 SipUserPingStatus::Reachable,
68 SipUserPingStatus::Invalid,
69 ];
70
71 #[test]
72 fn round_trip() {
73 for &status in ALL {
74 let wire = status.to_string();
75 let parsed: SipUserPingStatus = wire
76 .parse()
77 .unwrap();
78 assert_eq!(parsed, status, "round-trip failed for {wire}");
79 }
80 }
81
82 #[test]
83 fn rejects_unknown() {
84 assert!("BOGUS"
85 .parse::<SipUserPingStatus>()
86 .is_err());
87 assert!("reachable"
88 .parse::<SipUserPingStatus>()
89 .is_err());
90 }
91}