Skip to main content

freeswitch_types/sofia/
gateway.rs

1//! Gateway registration state and ping status enums.
2
3wire_enum! {
4    /// Gateway registration state from `sofia::gateway_state` events.
5    ///
6    /// The `State` header value, mapping to `reg_state_t` / `sofia_state_names[]`
7    /// in mod_sofia.
8    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
9    #[cfg_attr(feature = "serde", serde(rename_all = "SCREAMING_SNAKE_CASE"))]
10    pub enum GatewayRegState {
11        #[cfg_attr(feature = "serde", serde(alias = "Unreged"))]
12        Unreged => "UNREGED",
13        #[cfg_attr(feature = "serde", serde(alias = "Trying"))]
14        Trying => "TRYING",
15        #[cfg_attr(feature = "serde", serde(alias = "Register"))]
16        Register => "REGISTER",
17        #[cfg_attr(feature = "serde", serde(alias = "Reged"))]
18        Reged => "REGED",
19        #[cfg_attr(feature = "serde", serde(alias = "Unregister"))]
20        Unregister => "UNREGISTER",
21        #[cfg_attr(feature = "serde", serde(alias = "Failed"))]
22        Failed => "FAILED",
23        #[cfg_attr(feature = "serde", serde(alias = "FailWait"))]
24        FailWait => "FAIL_WAIT",
25        #[cfg_attr(feature = "serde", serde(alias = "Expired"))]
26        Expired => "EXPIRED",
27        #[cfg_attr(feature = "serde", serde(alias = "Noreg"))]
28        Noreg => "NOREG",
29        #[cfg_attr(feature = "serde", serde(alias = "Down"))]
30        Down => "DOWN",
31        #[cfg_attr(feature = "serde", serde(alias = "Timeout"))]
32        Timeout => "TIMEOUT",
33    }
34    error ParseGatewayRegStateError("gateway reg state");
35    tests: gateway_reg_state_wire_tests;
36}
37
38wire_enum! {
39    /// Gateway ping status from `sofia::gateway_state` events.
40    ///
41    /// The `Ping-Status` header value, mapping to `sofia_gateway_status_name()`.
42    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
43    #[cfg_attr(feature = "serde", serde(rename_all = "SCREAMING_SNAKE_CASE"))]
44    pub enum GatewayPingStatus {
45        #[cfg_attr(feature = "serde", serde(alias = "Down"))]
46        Down => "DOWN",
47        #[cfg_attr(feature = "serde", serde(alias = "Up"))]
48        Up => "UP",
49        #[cfg_attr(feature = "serde", serde(alias = "Invalid"))]
50        Invalid => "INVALID",
51    }
52    error ParseGatewayPingStatusError("gateway ping status");
53    tests: gateway_ping_status_wire_tests;
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    const ALL_REG_STATES: &[GatewayRegState] = &[
61        GatewayRegState::Unreged,
62        GatewayRegState::Trying,
63        GatewayRegState::Register,
64        GatewayRegState::Reged,
65        GatewayRegState::Unregister,
66        GatewayRegState::Failed,
67        GatewayRegState::FailWait,
68        GatewayRegState::Expired,
69        GatewayRegState::Noreg,
70        GatewayRegState::Down,
71        GatewayRegState::Timeout,
72    ];
73
74    #[test]
75    fn reg_state_round_trip() {
76        for &state in ALL_REG_STATES {
77            let wire = state.to_string();
78            let parsed: GatewayRegState = wire
79                .parse()
80                .unwrap();
81            assert_eq!(parsed, state, "round-trip failed for {wire}");
82        }
83    }
84
85    #[test]
86    fn reg_state_count() {
87        assert_eq!(ALL_REG_STATES.len(), 11);
88    }
89
90    #[test]
91    fn reg_state_rejects_unknown() {
92        assert!("BOGUS"
93            .parse::<GatewayRegState>()
94            .is_err());
95        assert!("reged"
96            .parse::<GatewayRegState>()
97            .is_err());
98    }
99
100    const ALL_PING_STATUSES: &[GatewayPingStatus] = &[
101        GatewayPingStatus::Down,
102        GatewayPingStatus::Up,
103        GatewayPingStatus::Invalid,
104    ];
105
106    #[test]
107    fn ping_status_round_trip() {
108        for &status in ALL_PING_STATUSES {
109            let wire = status.to_string();
110            let parsed: GatewayPingStatus = wire
111                .parse()
112                .unwrap();
113            assert_eq!(parsed, status, "round-trip failed for {wire}");
114        }
115    }
116
117    #[test]
118    fn ping_status_rejects_unknown() {
119        assert!("BOGUS"
120            .parse::<GatewayPingStatus>()
121            .is_err());
122        assert!("up"
123            .parse::<GatewayPingStatus>()
124            .is_err());
125    }
126
127    #[cfg(feature = "serde")]
128    mod serde_tests {
129        use super::*;
130
131        #[test]
132        fn reg_state_serde_uses_wire_format() {
133            for &state in ALL_REG_STATES {
134                let json = serde_json::to_string(&state).unwrap();
135                let expected = format!("\"{}\"", state.as_str());
136                assert_eq!(json, expected, "serde must serialize as wire format");
137            }
138        }
139
140        #[test]
141        fn reg_state_serde_round_trip() {
142            for &state in ALL_REG_STATES {
143                let json = serde_json::to_string(&state).unwrap();
144                let parsed: GatewayRegState = serde_json::from_str(&json).unwrap();
145                assert_eq!(parsed, state);
146            }
147        }
148
149        #[test]
150        fn reg_state_serde_accepts_pascal_case_alias() {
151            let cases = [
152                ("\"Noreg\"", GatewayRegState::Noreg),
153                ("\"Reged\"", GatewayRegState::Reged),
154                ("\"FailWait\"", GatewayRegState::FailWait),
155                ("\"Unreged\"", GatewayRegState::Unreged),
156            ];
157            for (json, expected) in cases {
158                let parsed: GatewayRegState = serde_json::from_str(json).unwrap();
159                assert_eq!(parsed, expected, "PascalCase alias failed for {json}");
160            }
161        }
162
163        #[test]
164        fn ping_status_serde_uses_wire_format() {
165            for &status in ALL_PING_STATUSES {
166                let json = serde_json::to_string(&status).unwrap();
167                let expected = format!("\"{}\"", status.as_str());
168                assert_eq!(json, expected, "serde must serialize as wire format");
169            }
170        }
171
172        #[test]
173        fn ping_status_serde_round_trip() {
174            for &status in ALL_PING_STATUSES {
175                let json = serde_json::to_string(&status).unwrap();
176                let parsed: GatewayPingStatus = serde_json::from_str(&json).unwrap();
177                assert_eq!(parsed, status);
178            }
179        }
180
181        #[test]
182        fn ping_status_serde_accepts_pascal_case_alias() {
183            let cases = [
184                ("\"Down\"", GatewayPingStatus::Down),
185                ("\"Up\"", GatewayPingStatus::Up),
186                ("\"Invalid\"", GatewayPingStatus::Invalid),
187            ];
188            for (json, expected) in cases {
189                let parsed: GatewayPingStatus = serde_json::from_str(json).unwrap();
190                assert_eq!(parsed, expected, "PascalCase alias failed for {json}");
191            }
192        }
193    }
194}