1use crate::{AsrVendor, ConnectState, FlowState, Region, VoiceServer};
4use std::fmt::{Debug, Formatter};
5use std::sync::Arc;
6
7use cal_jambonz::dial::TranscribeDial;
8use cal_jambonz::listen::Listen;
9
10pub use crate::device::ani_router::ANIRouter;
11pub use crate::device::app_flow::AppFlow;
12pub use crate::device::client::Client;
13pub use crate::device::date_range_router::DateRangeRouter;
14pub use crate::device::day_of_week_router::DayOfWeekRouter;
15pub use crate::device::digit_router::DigitRouter;
16pub use crate::device::dnis_router::DNISRouter;
17pub use crate::device::email::Email;
18pub use crate::device::event::Event;
19pub use crate::device::hunt_group::HuntGroup;
20pub use crate::device::inbound_flow::InboundFlow;
21pub use crate::device::message_ani_router::MessageAniRouter;
22pub use crate::device::message_buttons::MessageButtons;
23pub use crate::device::message_dnis_router::MessageDnisRouter;
24pub use crate::device::message_plugin::MessagePlugin;
25pub use crate::device::message_template::MessageTemplate;
26pub use crate::device::message_text::MessageText;
27pub use crate::device::outbound_flow::OutboundFlow;
28pub use crate::device::play::Play;
29pub use crate::device::plugin::Plugin;
30pub use crate::device::queue::Queue;
31pub use crate::device::remote::Remote;
32pub use crate::device::say::Say;
33pub use crate::device::service::Service;
34pub use crate::device::shared::{RecordOptions, TranscribeOptions};
35pub use crate::device::sip_extension::SipExtension;
36pub use crate::device::sip_gateway::SipGateway;
37pub use crate::device::sms::Sms;
38pub use crate::device::tag_router::TagRouter;
39pub use crate::device::teams::Teams;
40pub use crate::device::time_range_router::TimeRangeRouter;
41pub use crate::device::voicemail::VoiceMail;
42pub use crate::device::whatsapp_flow::WhatsAppFlow;
43pub use crate::zone_router::ZoneRouter;
44use serde::{Deserialize, Deserializer, Serialize};
45use serde_json::Value;
46#[cfg(feature = "openapi")]
47use utoipa::{ToSchema, IntoParams};
48
49use crate::script::Script;
50use crate::tag::Tag;
51
52pub trait Connector {
53 fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState;
54
55 fn is_endpoint(&self) -> bool {
57 false
58 }
59
60 fn supports_routing(&self) -> bool {
62 true
63 }
64}
65
66pub trait BaseDevice {
67 fn get_id(&mut self) -> String;
68 fn get_name(&mut self) -> String;
69 fn get_extension(&mut self) -> u16;
70}
71
72#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
74#[cfg_attr(feature = "openapi", derive(ToSchema))]
75#[cfg_attr(feature = "openapi", schema(
76 title ="Enumeration of all available device types in the system",
77 example = "CLIENT"
78))]
79pub enum DeviceType {
80 #[serde(rename = "ROUTE_START")]
82 InboundFlow,
83
84 #[serde(rename = "MATCH_START")]
86 OutboundFlow,
87
88 #[serde(rename = "WHATSAPP_START")]
90 WhatsAppFlow,
91
92 #[serde(rename = "APP_START")]
94 AppFlow,
95
96 #[serde(rename = "ANI_ROUTER")]
98 AniRouter,
99
100 #[serde(rename = "DNIS_ROUTER")]
102 DnisRouter,
103
104 #[serde(rename = "ZONE_ROUTER")]
106 ZoneRouter,
107
108 #[serde(rename = "NUMBER_PLAN")]
110 DigitRouter,
111
112 #[serde(rename = "TIME_RANGE_ROUTER")]
114 TimeRangeRouter,
115
116 #[serde(rename = "DAY_OF_WEEK_ROUTER")]
118 DayOfWeekRouter,
119
120 #[serde(rename = "DATE_RANGE_ROUTER")]
122 DateRangeRouter,
123
124 #[serde(rename = "HUNT_GROUP")]
126 HuntGroup,
127
128 #[serde(rename = "CLIENT")]
130 Client,
131
132 #[serde(rename = "TEAMS")]
134 Teams,
135
136 #[serde(rename = "SIP")]
138 SipExtension,
139
140 #[serde(rename = "SIP_GATEWAY")]
142 SipGateway,
143
144 #[serde(rename = "REMOTE")]
146 Remote,
147
148 #[serde(rename = "PLUGIN")]
150 Plugin,
151
152 #[serde(rename = "PLAY")]
154 Play,
155
156 #[serde(rename = "SAY")]
158 Say,
159
160 #[serde(rename = "VOICEMAIL")]
162 Voicemail,
163
164 #[serde(rename = "SCRIPT")]
166 Script,
167
168 #[serde(rename = "QUEUE")]
170 Queue,
171
172 #[serde(rename = "SMS")]
174 Sms,
175
176 #[serde(rename = "EMAIL")]
178 Email,
179
180 #[serde(rename = "TAG")]
182 Tag,
183
184 #[serde(rename = "TAG_ROUTER")]
186 TagRouter,
187
188 #[serde(rename = "MESSAGE_PLUGIN")]
190 MessagePlugin,
191
192 #[serde(rename = "MESSAGE_TEXT")]
194 MessageText,
195
196 #[serde(rename = "MESSAGE_BUTTONS")]
198 MessageButtons,
199
200 #[serde(rename = "MESSAGE_TEMPLATE")]
202 MessageTemplate,
203
204 #[serde(rename = "MESSAGE_ANI_ROUTER")]
206 MessageAniRouter,
207
208 #[serde(rename = "SERVICE")]
210 Service,
211}
212
213#[derive(Serialize, Deserialize, Clone)]
215#[serde(untagged)]
216pub enum Device {
217 InboundFlow(InboundFlow),
218 OutboundFlow(OutboundFlow),
219 WhatsAppFlow(WhatsAppFlow),
220 AppFlow(AppFlow),
221 AniRouter(ANIRouter),
222 DnisRouter(DNISRouter),
223 DigitRouter(DigitRouter),
224 TimeRangeRouter(TimeRangeRouter),
225 DayOfWeekRouter(DayOfWeekRouter),
226 DateRangeRouter(DateRangeRouter),
227 ZoneRouter(ZoneRouter),
228 HuntGroup(HuntGroup),
229 Client(Client),
230 Teams(Teams),
231 SipExtension(SipExtension),
232 SipGateway(SipGateway),
233 Remote(Remote),
234 Plugin(Plugin),
235 Play(Play),
236 Say(Say),
237 Voicemail(VoiceMail),
238 Script(Script),
239 Queue(Queue),
240 Sms(Sms),
241 Email(Email),
242 Tag(Tag),
243 TagRouter(TagRouter),
244 MessagePlugin(MessagePlugin),
245 MessageButtons(MessageButtons),
246 MessageText(MessageText),
247 MessageTemplate(MessageTemplate),
248 MessageAniRouter(MessageAniRouter),
249 Service(Service),
250}
251
252#[derive(Serialize, Deserialize, Clone)]
254#[cfg_attr(feature = "openapi", derive(ToSchema))]
255#[cfg_attr(feature = "openapi", schema(
256 title ="Device configuration containing all possible device types and their settings",
257 example = json!({
258 "_id": "dev_507f1f77bcf86cd799439011",
259 "type": "CLIENT",
260 "name": "John's Desk Phone",
261 "extension": 1001,
262 "tags": [
263 {
264 "type": "session",
265 "name": "department",
266 "value": "sales"
267 }
268 ],
269 "client": {
270 "username": "john.doe",
271 "password": "encrypted_password",
272 "realm": "sip.example.com"
273 }
274 })
275))]
276#[serde(rename_all = "camelCase")]
277pub struct DeviceStruct {
278 #[serde(rename = "_id")]
280 #[cfg_attr(feature = "openapi", schema(example = "dev_507f1f77bcf86cd799439011"))]
281 pub id: String,
282
283 #[serde(rename = "type")]
285 pub device_type: DeviceType,
286
287 #[cfg_attr(feature = "openapi", schema(example = "Reception Phone", min_length = 1))]
289 pub name: String,
290
291 #[serde(deserialize_with = "from_str")]
293 #[cfg_attr(feature = "openapi", schema(example = 1001, minimum = 1, maximum = 9999))]
294 pub extension: u16,
295
296 #[serde(default)]
298 pub tags: Vec<DeviceTag>,
299
300 #[serde(rename = "startRoute")]
302 #[serde(skip_serializing_if = "Option::is_none")]
303 pub start_route: Option<InboundFlow>,
304
305 #[serde(rename = "regexRoute")]
307 #[serde(skip_serializing_if = "Option::is_none")]
308 pub regex_route: Option<OutboundFlow>,
309
310 #[serde(rename = "appRoute")]
312 #[serde(skip_serializing_if = "Option::is_none")]
313 pub app_route: Option<AppFlow>,
314
315 #[serde(rename = "numberPlan")]
317 #[serde(skip_serializing_if = "Option::is_none")]
318 pub number_plan: Option<DigitRouter>,
319
320 #[serde(rename = "aniRouter")]
322 #[serde(skip_serializing_if = "Option::is_none")]
323 pub ani_router: Option<ANIRouter>,
324
325 #[serde(rename = "dnisRouter")]
327 #[serde(skip_serializing_if = "Option::is_none")]
328 pub dnis_router: Option<DNISRouter>,
329
330 #[serde(rename = "zoneRouter")]
332 #[serde(skip_serializing_if = "Option::is_none")]
333 pub zone_router: Option<ZoneRouter>,
334
335 #[serde(rename = "tagRouter")]
337 #[serde(skip_serializing_if = "Option::is_none")]
338 pub tag_router: Option<TagRouter>,
339
340 #[serde(rename = "timeRangeRoute")]
342 #[serde(skip_serializing_if = "Option::is_none")]
343 pub time_range_router: Option<TimeRangeRouter>,
344
345 #[serde(rename = "dayOfWeekRoute")]
347 #[serde(skip_serializing_if = "Option::is_none")]
348 pub day_of_week_router: Option<DayOfWeekRouter>,
349
350 #[serde(rename = "dateRangeRoute")]
352 #[serde(skip_serializing_if = "Option::is_none")]
353 pub date_range_router: Option<DateRangeRouter>,
354
355 #[serde(rename = "huntGroup")]
357 #[serde(skip_serializing_if = "Option::is_none")]
358 pub hunt_group: Option<HuntGroup>,
359
360 #[serde(rename = "client")]
362 #[serde(skip_serializing_if = "Option::is_none")]
363 pub client: Option<Client>,
364
365 #[serde(rename = "teams")]
367 #[serde(skip_serializing_if = "Option::is_none")]
368 pub teams: Option<Teams>,
369
370 #[serde(rename = "sipExtension")]
372 #[serde(skip_serializing_if = "Option::is_none")]
373 pub sip_extension: Option<SipExtension>,
374
375 #[serde(rename = "sipGateway")]
377 #[serde(skip_serializing_if = "Option::is_none")]
378 pub sip_gateway: Option<SipGateway>,
379
380 #[serde(rename = "remote")]
382 #[serde(skip_serializing_if = "Option::is_none")]
383 pub remote: Option<Remote>,
384
385 #[serde(rename = "voicemail")]
387 #[serde(skip_serializing_if = "Option::is_none")]
388 pub voice_mail: Option<VoiceMail>,
389
390 #[serde(rename = "queue")]
392 #[serde(skip_serializing_if = "Option::is_none")]
393 pub queue: Option<Queue>,
394
395 #[serde(rename = "plugin")]
397 #[serde(skip_serializing_if = "Option::is_none")]
398 pub plugin: Option<Plugin>,
399
400 #[serde(rename = "service")]
402 #[serde(skip_serializing_if = "Option::is_none")]
403 pub service: Option<Service>,
404
405 #[serde(rename = "play")]
407 #[serde(skip_serializing_if = "Option::is_none")]
408 pub play: Option<Play>,
409
410 #[serde(rename = "say")]
412 #[serde(skip_serializing_if = "Option::is_none")]
413 pub say: Option<Say>,
414
415 #[serde(rename = "script")]
417 #[serde(skip_serializing_if = "Option::is_none")]
418 pub script: Option<Script>,
419
420 #[serde(rename = "email")]
422 #[serde(skip_serializing_if = "Option::is_none")]
423 pub email: Option<Email>,
424
425 #[serde(rename = "sms")]
427 #[serde(skip_serializing_if = "Option::is_none")]
428 pub sms: Option<Sms>,
429
430 #[serde(rename = "tag")]
432 #[serde(skip_serializing_if = "Option::is_none")]
433 pub tag: Option<Tag>,
434
435 #[serde(rename = "event")]
437 #[serde(skip_serializing_if = "Option::is_none")]
438 pub event: Option<Event>,
439
440 #[serde(rename = "whatsAppRoute")]
442 #[serde(skip_serializing_if = "Option::is_none")]
443 pub whats_app_flow: Option<WhatsAppFlow>,
444
445 #[serde(rename = "messagePlugin")]
447 #[serde(skip_serializing_if = "Option::is_none")]
448 pub message_plugin: Option<MessagePlugin>,
449
450 #[serde(rename = "messageText")]
452 #[serde(skip_serializing_if = "Option::is_none")]
453 pub message_text: Option<MessageText>,
454
455 #[serde(rename = "messageButtons")]
457 #[serde(skip_serializing_if = "Option::is_none")]
458 pub message_buttons: Option<MessageButtons>,
459
460 #[serde(rename = "messageTemplate")]
462 #[serde(skip_serializing_if = "Option::is_none")]
463 pub message_template: Option<MessageTemplate>,
464
465 #[serde(rename = "messageANIRouter")]
467 #[serde(skip_serializing_if = "Option::is_none")]
468 pub message_ani_router: Option<MessageAniRouter>,
469
470 #[serde(rename = "messageDNISRouter")]
472 #[serde(skip_serializing_if = "Option::is_none")]
473 pub message_dnis_router: Option<MessageDnisRouter>,
474}
475
476fn from_str<'de, D>(deserializer: D) -> Result<u16, D::Error>
478where
479 D: Deserializer<'de>,
480{
481 let value = Value::deserialize(deserializer)?;
482 if value.is_string() {
483 Ok(value.as_str().unwrap().parse().unwrap())
484 } else if value.is_u64() {
485 Ok(value.as_u64().unwrap() as u16)
486 } else if value.is_i64() {
487 Ok(value.as_i64().unwrap() as u16)
488 } else {
489 Err(serde::de::Error::custom("Cannot map extension to u16"))
490 }
491}
492
493impl DeviceStruct {
494 pub fn record_options(&self) -> Option<RecordOptions> {
496 match &self.device_type {
497 DeviceType::HuntGroup => self.hunt_group.as_ref().map(|h| h.record_options.clone()),
498 DeviceType::Client => self.client.as_ref().map(|c| c.record_options.clone()),
499 DeviceType::Teams => self.teams.as_ref().map(|t| t.record_options.clone()),
500 DeviceType::SipExtension => self.sip_extension.as_ref().map(|s| s.record_options.clone()),
501 DeviceType::SipGateway => self.sip_gateway.as_ref().map(|s| s.record_options.clone()),
502 DeviceType::Remote => self.remote.as_ref().map(|r| r.record_options.clone()),
503 DeviceType::Plugin => self.plugin.as_ref().map(|p| p.record_options.clone()),
504 DeviceType::Voicemail => self.voice_mail.as_ref().map(|v| v.record_options.clone()),
505 _ => None,
506 }
507 }
508
509 pub fn transcribe_options(&self) -> Option<TranscribeOptions> {
511 match &self.device_type {
512 DeviceType::HuntGroup => self.hunt_group.as_ref().map(|h| h.transcribe_options.clone()),
513 DeviceType::Client => self.client.as_ref().map(|c| c.transcribe_options.clone()),
514 DeviceType::Teams => self.teams.as_ref().map(|t| t.transcribe_options.clone()),
515 DeviceType::SipExtension => self.sip_extension.as_ref().map(|s| s.transcribe_options.clone()),
516 DeviceType::SipGateway => self.sip_gateway.as_ref().map(|s| s.transcribe_options.clone()),
517 DeviceType::Remote => self.remote.as_ref().map(|r| r.transcribe_options.clone()),
518 DeviceType::Plugin => self.plugin.as_ref().map(|p| p.transcribe_options.clone()),
519 DeviceType::Voicemail => self.voice_mail.as_ref().map(|v| v.transcribe_options.clone()),
520 _ => None,
521 }
522 }
523
524 pub fn is_id(&self, _id: &str) -> bool {
526 self.id == _id
527 }
528
529 pub fn is_device_type(&self, device_type: DeviceType) -> bool {
531 self.device_type == device_type
532 }
533
534 pub fn match_device(&self, str: &str) -> bool {
536 let matched = match &self.device_type {
537 DeviceType::InboundFlow => {
538 self.start_route
539 .as_ref()
540 .map_or(false, |v| v.ddis.contains(&str.to_string()))
541 }
542 DeviceType::Client => {
543 self.client
544 .as_ref()
545 .map_or(false, |v| v.username.eq(str))
546 }
547 DeviceType::SipGateway => {
548 self.sip_gateway
549 .as_ref()
550 .map_or(false, |v| v.trunks.contains(&str.to_string()))
551 }
552 _ => false,
553 };
554
555 matched || self.id.eq(str) || self.extension.to_string().eq(str)
556 }
557
558 pub fn match_outbound_flow(&self) -> bool {
560 match &self.device_type {
561 DeviceType::OutboundFlow => true,
562 _ => false,
563 }
564 }
565
566 pub fn is_connector(&self) -> bool {
568 vec![
569 DeviceType::InboundFlow,
570 DeviceType::OutboundFlow,
571 DeviceType::AppFlow,
572 DeviceType::WhatsAppFlow,
573 DeviceType::AniRouter,
574 DeviceType::DnisRouter,
575 DeviceType::DigitRouter,
576 DeviceType::TimeRangeRouter,
577 DeviceType::DayOfWeekRouter,
578 DeviceType::DateRangeRouter,
579 DeviceType::Play,
580 DeviceType::Say,
581 DeviceType::Voicemail,
582 DeviceType::Script,
583 DeviceType::Queue,
584 DeviceType::Sms,
585 DeviceType::Email,
586 DeviceType::Tag,
587 DeviceType::TagRouter,
588 DeviceType::Service,
589 ]
590 .contains(&self.device_type)
591 }
592
593 pub fn is_call_handler(&self) -> bool {
595 vec![
596 DeviceType::HuntGroup,
597 DeviceType::Client,
598 DeviceType::Teams,
599 DeviceType::SipExtension,
600 DeviceType::SipGateway,
601 DeviceType::Remote,
602 DeviceType::Plugin,
603 ]
604 .contains(&self.device_type)
605 }
606}
607
608#[derive(Serialize, Deserialize, Clone)]
610#[cfg_attr(feature = "openapi", derive(ToSchema))]
611#[cfg_attr(feature = "openapi", schema(
612 title ="Tag for categorizing and routing devices",
613 example = json!({
614 "type": "session",
615 "name": "department",
616 "value": "sales"
617 })
618))]
619#[serde(rename_all = "camelCase")]
620pub struct DeviceTag {
621 #[serde(rename = "type")]
623 pub tag_type: TagType,
624
625 #[cfg_attr(feature = "openapi", schema(example = "department"))]
627 pub name: String,
628
629 #[cfg_attr(feature = "openapi", schema(example = "sales"))]
631 pub value: String,
632}
633
634#[derive(Serialize, Deserialize, Eq, PartialEq, Clone)]
636#[cfg_attr(feature = "openapi", derive(ToSchema))]
637#[cfg_attr(feature = "openapi", schema(
638 title ="Scope of the tag - session-specific or globally available"
639))]
640#[serde(rename_all = "camelCase")]
641pub enum TagType {
642 Session,
644 Global,
646}
647
648pub trait Endpoint {
649 fn get_caller_id(&self, state: &FlowState) -> String {
650 state.initial_request.from.clone()
651 }
652 fn get_called_id(&self, state: &FlowState) -> String {
653 state.initial_request.to.clone()
654 }
655 fn get_listen(&self, state: &FlowState) -> Option<Listen>;
656 fn get_proxy(&self, _state: &FlowState, _regions:Vec<Arc<Region>>) -> Option<VoiceServer> {
657 None
658 }
659 fn get_transcribe(&self, _state: &FlowState) -> Option<TranscribeDial> {
660 None
661 }
662}
663
664pub trait EndpointDevice: Connector {
666 fn is_endpoint(&self) -> bool {
667 true
668 }
669
670 fn device_type_name(&self) -> &'static str;
672
673 fn supports_routing(&self) -> bool {
675 false
676 }
677}
678
679impl Debug for DeviceType {
683 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
684 match self {
685 DeviceType::InboundFlow => write!(f, "InboundFlow"),
686 DeviceType::OutboundFlow => write!(f, "OutboundFlow"),
687 DeviceType::WhatsAppFlow => write!(f, "WhatsAppFlow"),
688 DeviceType::AppFlow => write!(f, "AppFlow"),
689 DeviceType::AniRouter => write!(f, "AniRouter"),
690 DeviceType::DnisRouter => write!(f, "DnisRouter"),
691 DeviceType::DigitRouter => write!(f, "DigitRouter"),
692 DeviceType::TimeRangeRouter => write!(f, "TimeRangeRouter"),
693 DeviceType::DayOfWeekRouter => write!(f, "DayOfWeekRouter"),
694 DeviceType::DateRangeRouter => write!(f, "DateRangeRouter"),
695 DeviceType::ZoneRouter => write!(f, "ZoneRouter"),
696 DeviceType::HuntGroup => write!(f, "HuntGroup"),
697 DeviceType::Client => write!(f, "Client"),
698 DeviceType::Teams => write!(f, "Teams"),
699 DeviceType::SipExtension => write!(f, "SipExtension"),
700 DeviceType::SipGateway => write!(f, "SipGateway"),
701 DeviceType::Remote => write!(f, "Remote"),
702 DeviceType::Plugin => write!(f, "Plugin"),
703 DeviceType::Play => write!(f, "Play"),
704 DeviceType::Say => write!(f, "Say"),
705 DeviceType::Voicemail => write!(f, "Voicemail"),
706 DeviceType::Script => write!(f, "Script"),
707 DeviceType::Queue => write!(f, "Queue"),
708 DeviceType::Sms => write!(f, "Sms"),
709 DeviceType::Email => write!(f, "Email"),
710 DeviceType::Tag => write!(f, "Tag"),
711 DeviceType::TagRouter => write!(f, "TagRouter"),
712 DeviceType::MessagePlugin => write!(f, "MessagePlugin"),
713 DeviceType::MessageText => write!(f, "MessageText"),
714 DeviceType::MessageButtons => write!(f, "MessageButtons"),
715 DeviceType::MessageTemplate => write!(f, "MessageTemplate"),
716 DeviceType::MessageAniRouter => write!(f, "MessageAniRouter"),
717 DeviceType::Service => write!(f, "Service"),
718 }
719 }
720}
721
722impl Debug for Device {
724 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
725 match self {
726 Device::InboundFlow(_) => write!(f, "Device::InboundFlow"),
727 Device::OutboundFlow(_) => write!(f, "Device::OutboundFlow"),
728 Device::WhatsAppFlow(_) => write!(f, "Device::WhatsAppFlow"),
729 Device::AppFlow(_) => write!(f, "Device::AppFlow"),
730 Device::AniRouter(_) => write!(f, "Device::AniRouter"),
731 Device::DnisRouter(_) => write!(f, "Device::DnisRouter"),
732 Device::DigitRouter(_) => write!(f, "Device::DigitRouter"),
733 Device::TimeRangeRouter(_) => write!(f, "Device::TimeRangeRouter"),
734 Device::DayOfWeekRouter(_) => write!(f, "Device::DayOfWeekRouter"),
735 Device::DateRangeRouter(_) => write!(f, "Device::DateRangeRouter"),
736 Device::ZoneRouter(_) => write!(f, "Device::ZoneRouter"),
737 Device::HuntGroup(_) => write!(f, "Device::HuntGroup"),
738 Device::Client(_) => write!(f, "Device::Client"),
739 Device::Teams(_) => write!(f, "Device::Teams"),
740 Device::SipExtension(_) => write!(f, "Device::SipExtension"),
741 Device::SipGateway(_) => write!(f, "Device::SipGateway"),
742 Device::Remote(_) => write!(f, "Device::Remote"),
743 Device::Plugin(_) => write!(f, "Device::Plugin"),
744 Device::Play(_) => write!(f, "Device::Play"),
745 Device::Say(_) => write!(f, "Device::Say"),
746 Device::Voicemail(_) => write!(f, "Device::Voicemail"),
747 Device::Script(_) => write!(f, "Device::Script"),
748 Device::Queue(_) => write!(f, "Device::Queue"),
749 Device::Sms(_) => write!(f, "Device::Sms"),
750 Device::Email(_) => write!(f, "Device::Email"),
751 Device::Tag(_) => write!(f, "Device::Tag"),
752 Device::TagRouter(_) => write!(f, "Device::TagRouter"),
753 Device::MessagePlugin(_) => write!(f, "Device::MessagePlugin"),
754 Device::MessageButtons(_) => write!(f, "Device::MessageButtons"),
755 Device::MessageText(_) => write!(f, "Device::MessageText"),
756 Device::MessageTemplate(_) => write!(f, "Device::MessageTemplate"),
757 Device::MessageAniRouter(_) => write!(f, "Device::MessageAniRouter"),
758 Device::Service(_) => write!(f, "Device::Service"),
759 }
760 }
761}
762
763impl Debug for DeviceStruct {
765 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
766 f.debug_struct("DeviceStruct")
767 .field("id", &self.id)
768 .field("device_type", &self.device_type)
769 .field("name", &self.name)
770 .field("extension", &self.extension)
771 .finish_non_exhaustive()
772 }
773}
774
775impl Debug for TagType {
777 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
778 match self {
779 TagType::Session => write!(f, "Session"),
780 TagType::Global => write!(f, "Global"),
781 }
782 }
783}
784
785impl Debug for DeviceTag {
787 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
788 f.debug_struct("DeviceTag")
789 .field("tag_type", &self.tag_type)
790 .field("name", &self.name)
791 .field("value", &self.value)
792 .finish()
793 }
794}
795
796impl Debug for RecordOptions {
798 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
799 f.debug_struct("RecordOptions")
800 .field("enabled", &self.enabled)
801 .field("retention", &self.retention)
802 .field("mix_type", &self.mix_type)
803 .field("sample_rate", &self.sample_rate)
804 .finish()
805 }
806}
807
808impl Debug for TranscribeOptions {
810 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
811 f.debug_struct("TranscribeOptions")
812 .field("enabled", &self.enabled)
813 .field("language", &self.language)
814 .finish()
815 }
816}
817
818impl Debug for AsrVendor {
820 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
821 match self {
822 AsrVendor::Google => write!(f, "Google"),
823 AsrVendor::Deepgram => write!(f, "DeepGram"),
824 AsrVendor::Microsoft => write!(f, "Microsoft"),
825 AsrVendor::Aws => write!(f, "Aws"),
826 AsrVendor::Ibm => write!(f, "Ibm"),
827 AsrVendor::Nuance => write!(f, "Nuance"),
828 AsrVendor::Nvidia =>write!(f, "Nvidia"),
829 AsrVendor::Soniox => write!(f, "Soniox"),
830 }
831 }
832}