1pub mod calls;
8pub mod phone_numbers;
9pub mod routing_rules;
10pub mod trunks;
11pub mod webhooks;
12
13use serde::{Deserialize, Serialize};
14
15use crate::client::Client;
16use crate::common::string_enum;
17
18pub use calls::{
19 CreateSipCallParams, SipCall, SipCallListParams, SipCallsResource, SwitchRoomParams,
20 TransferSipCallParams,
21};
22pub use phone_numbers::{
23 CreatePhoneNumbersParams, PhoneNumberInboundConfig, PhoneNumberInfo, PhoneNumberListParams,
24 PhoneNumberOutboundConfig, PhoneNumberWithGateways, PhoneNumbersResource,
25 UpdatePhoneNumberGatewayParams,
26};
27pub use routing_rules::{
28 CreateRoutingRuleParams, RoutingRuleTarget, SipRoomConfig, SipRoutingRule,
29 SipRoutingRuleListParams, SipRoutingRulesResource, UpdateRoutingRuleParams,
30};
31pub use trunks::{
32 CreateInboundTrunkParams, CreateOutboundTrunkParams, InboundTrunkResource,
33 OutboundTrunkResource, SipTrunk, SipTrunkListParams, SipTrunksResource,
34 UpdateInboundTrunkParams, UpdateOutboundTrunkParams,
35};
36pub use webhooks::{CreateSipWebhookParams, SipWebhook, SipWebhookListParams, SipWebhooksResource};
37
38string_enum! {
39 SipTransport {
41 UDP => "udp",
43 TCP => "tcp",
45 TLS => "tls",
47 }
48}
49
50string_enum! {
51 SipMediaEncryption {
53 ENABLE => "enable",
55 DISABLE => "disable",
57 }
58}
59
60string_enum! {
61 SipIncludeHeaders {
63 ALL => "ALL",
65 SIP_X_HEADERS => "SIP_X_HEADERS",
67 NONE => "NONE",
69 }
70}
71
72string_enum! {
73 SipDirection {
75 INBOUND => "inbound",
77 OUTBOUND => "outbound",
79 }
80}
81
82string_enum! {
83 SipRoomType {
85 STATIC => "static",
87 DYNAMIC => "dynamic",
89 }
90}
91
92string_enum! {
93 SipRoomPrefix {
95 BLANK => "blank",
97 PARTICIPANT_NUMBER => "participantNumber",
99 SIP_NUMBER => "sipNumber",
101 RANDOM => "random",
103 }
104}
105
106string_enum! {
107 SipRegion {
109 AUTO => "auto",
111 US002 => "us002",
113 IN002 => "in002",
115 }
116}
117
118string_enum! {
119 SipCallStatus {
121 INITIATED => "initiated",
123 RINGING => "ringing",
125 MISSED => "missed",
127 NOT_ANSWERED => "not-answered",
129 FAILED => "failed",
131 INCOMING => "incoming",
133 VERIFIED => "verified",
135 REJECTED => "rejected",
137 ABANDONED => "abandoned",
139 ANSWERED => "answered",
141 ENDED => "ended",
143 TRANSFER_INITIATED => "transfer-initiated",
145 TRANSFER_ACCEPTED => "transfer-accepted",
147 TRANSFERRING => "transferring",
149 TRANSFER_RINGING => "transfer-ringing",
151 TRANSFERRED => "transferred",
153 TRANSFER_FAILED => "transfer-failed",
155 SWITCH_ROOM_INITIATED => "switch-room-initiated",
157 SWITCH_ROOM_COMPLETED => "switch-room-completed",
159 SWITCH_ROOM_FAILED => "switch-room-failed",
161 }
162}
163
164string_enum! {
165 SipWebhookEvent {
167 CALL_STARTED => "call-started",
169 CALL_ANSWERED => "call-answered",
171 CALL_HANGUP => "call-hangup",
173 CALL_TRANSFERRED => "call-transferred",
175 CALL_MISSED => "call-missed",
177 CALL_UPDATE => "call-update",
179 CALL_RINGING => "call-ringing",
181 CALL_TRANSFER_INITIATED => "call-transfer-initiated",
183 CALL_TRANSFER_ACCEPTED => "call-transfer-accepted",
185 CALL_TRANSFERRING => "call-transferring",
187 CALL_TRANSFER_RINGING => "call-transfer-ringing",
189 CALL_TRANSFER_FAILED => "call-transfer-failed",
191 SWITCH_ROOM_INITIATED => "switch-room-initiated",
193 SWITCH_ROOM_COMPLETED => "switch-room-completed",
195 SWITCH_ROOM_FAILED => "switch-room-failed",
197 }
198}
199
200#[derive(Debug, Clone, Serialize, Deserialize)]
202pub struct SipAuth {
203 pub username: String,
205 pub password: String,
207}
208
209#[derive(Debug, Clone, Copy)]
211pub struct SipResource<'a> {
212 client: &'a Client,
213}
214
215impl<'a> SipResource<'a> {
216 pub(crate) fn new(client: &'a Client) -> Self {
217 Self { client }
218 }
219
220 pub fn trunks(&self) -> SipTrunksResource<'a> {
222 SipTrunksResource::new(self.client)
223 }
224
225 pub fn routing_rules(&self) -> SipRoutingRulesResource<'a> {
227 SipRoutingRulesResource::new(self.client)
228 }
229
230 pub fn phone_numbers(&self) -> PhoneNumbersResource<'a> {
232 PhoneNumbersResource::new(self.client)
233 }
234
235 pub fn calls(&self) -> SipCallsResource<'a> {
237 SipCallsResource::new(self.client)
238 }
239
240 pub fn webhooks(&self) -> SipWebhooksResource<'a> {
245 SipWebhooksResource::new(self.client)
246 }
247}
248
249#[cfg(test)]
250mod tests {
251 use super::*;
252 use serde_json::json;
253
254 #[test]
255 fn string_enums_round_trip_their_wire_values() {
256 assert_eq!(SipTransport::TLS.as_str(), "tls");
257 assert_eq!(SipIncludeHeaders::SIP_X_HEADERS.as_str(), "SIP_X_HEADERS");
258 assert_eq!(
259 SipRoomPrefix::PARTICIPANT_NUMBER.as_str(),
260 "participantNumber"
261 );
262 assert_eq!(SipCallStatus::NOT_ANSWERED.as_str(), "not-answered");
263 assert_eq!(
264 SipWebhookEvent::SWITCH_ROOM_COMPLETED.as_str(),
265 "switch-room-completed"
266 );
267 assert_eq!(
268 serde_json::to_value(SipDirection::INBOUND).unwrap(),
269 json!("inbound")
270 );
271 }
272
273 #[test]
275 fn an_unknown_value_still_deserializes() {
276 let status: SipCallStatus = serde_json::from_value(json!("some-future-status")).unwrap();
277 assert_eq!(status.as_str(), "some-future-status");
278 assert_eq!(
279 serde_json::to_value(&status).unwrap(),
280 json!("some-future-status")
281 );
282 }
283}