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
49#[derive(Debug, Deserialize)]
50#[cfg_attr(feature = "openapi", derive(ToSchema, IntoParams))]
51pub struct AccountIdQuery {
52 pub account_id: String,
54}
55use crate::script::Script;
56use crate::tag::Tag;
57
58pub trait Connector {
59
60 fn get_connect_to(&mut self, state: &mut FlowState) -> ConnectState;
61
62 fn is_endpoint(&self) -> bool {
64 false
65 }
66
67 fn supports_routing(&self) -> bool {
69 true
70 }
71}
72
73pub trait BaseDevice {
74 fn get_id(&mut self) -> String;
75 fn get_name(&mut self) -> String;
76 fn get_extension(&mut self) -> u16;
77}
78
79#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
80pub enum DeviceType {
81 #[serde(rename = "ROUTE_START")]
82 InboundFlow,
83 #[serde(rename = "MATCH_START")]
84 OutboundFlow,
85 #[serde(rename = "WHATSAPP_START")]
86 WhatsAppFlow,
87 #[serde(rename = "APP_START")]
88 AppFlow,
89 #[serde(rename = "ANI_ROUTER")]
90 AniRouter,
91 #[serde(rename = "DNIS_ROUTER")]
92 DnisRouter,
93 #[serde(rename = "ZONE_ROUTER")]
94 ZoneRouter,
95 #[serde(rename = "NUMBER_PLAN")]
96 DigitRouter,
97 #[serde(rename = "TIME_RANGE_ROUTER")]
98 TimeRangeRouter,
99 #[serde(rename = "DAY_OF_WEEK_ROUTER")]
100 DayOfWeekRouter,
101 #[serde(rename = "DATE_RANGE_ROUTER")]
102 DateRangeRouter,
103 #[serde(rename = "HUNT_GROUP")]
104 HuntGroup,
105 #[serde(rename = "CLIENT")]
106 Client,
107 #[serde(rename = "TEAMS")]
108 Teams,
109 #[serde(rename = "SIP")]
110 SipExtension,
111 #[serde(rename = "SIP_GATEWAY")]
112 SipGateway,
113 #[serde(rename = "REMOTE")]
114 Remote,
115 #[serde(rename = "PLUGIN")]
116 Plugin,
117 #[serde(rename = "PLAY")]
118 Play,
119 #[serde(rename = "SAY")]
120 Say,
121 #[serde(rename = "VOICEMAIL")]
122 Voicemail,
123 #[serde(rename = "SCRIPT")]
124 Script,
125 #[serde(rename = "QUEUE")]
126 Queue,
127 #[serde(rename = "SMS")]
128 Sms,
129 #[serde(rename = "EMAIL")]
130 Email,
131 #[serde(rename = "TAG")]
132 Tag,
133 #[serde(rename = "TAG_ROUTER")]
134 TagRouter,
135 #[serde(rename = "MESSAGE_PLUGIN")]
136 MessagePlugin,
137 #[serde(rename = "MESSAGE_TEXT")]
138 MessageText,
139 #[serde(rename = "MESSAGE_BUTTONS")]
140 MessageButtons,
141 #[serde(rename = "MESSAGE_TEMPLATE")]
142 MessageTemplate,
143 #[serde(rename = "MESSAGE_ANI_ROUTER")]
144 MessageAniRouter,
145 #[serde(rename = "SERVICE")]
146 Service,
147 }
149
150#[derive(Serialize, Deserialize, Clone)]
151#[serde(untagged)]
152pub enum Device {
153 InboundFlow(InboundFlow),
154 OutboundFlow(OutboundFlow),
155 WhatsAppFlow(WhatsAppFlow),
156 AppFlow(AppFlow),
157 AniRouter(ANIRouter),
158 DnisRouter(DNISRouter),
159 DigitRouter(DigitRouter),
160 TimeRangeRouter(TimeRangeRouter),
161 DayOfWeekRouter(DayOfWeekRouter),
162 DateRangeRouter(DateRangeRouter),
163 ZoneRouter(ZoneRouter),
164 HuntGroup(HuntGroup),
165 Client(Client),
166 Teams(Teams),
167 SipExtension(SipExtension),
168 SipGateway(SipGateway),
169 Remote(Remote),
170 Plugin(Plugin),
171 Play(Play),
172 Say(Say),
173 Voicemail(VoiceMail),
174 Script(Script),
175 Queue(Queue),
176 Sms(Sms),
177 Email(Email),
178 Tag(Tag),
179 TagRouter(TagRouter),
180 MessagePlugin(MessagePlugin),
181 MessageButtons(MessageButtons),
182 MessageText(MessageText),
183 MessageTemplate(MessageTemplate),
184 MessageAniRouter(MessageAniRouter),
185 Service(Service),
186}
187
188#[derive(Serialize, Deserialize, Clone)]
189#[cfg_attr(feature = "openapi", derive(ToSchema))]
190#[serde(rename_all = "camelCase")]
191pub struct DeviceStruct {
192 #[serde(rename = "_id")]
193 pub id: String,
194
195 #[serde(rename = "type")]
196 pub device_type: DeviceType,
197
198 pub name: String,
199
200 #[serde(deserialize_with = "from_str")]
201 pub extension: u16,
202
203 #[serde(default)]
204 pub tags: Vec<DeviceTag>,
205
206 #[serde(rename = "startRoute")]
207 #[serde(skip_serializing_if = "Option::is_none")]
208 pub start_route: Option<InboundFlow>,
209
210 #[serde(rename = "regexRoute")]
211 #[serde(skip_serializing_if = "Option::is_none")]
212 pub regex_route: Option<OutboundFlow>,
213
214 #[serde(rename = "appRoute")]
215 #[serde(skip_serializing_if = "Option::is_none")]
216 pub app_route: Option<AppFlow>,
217
218 #[serde(rename = "numberPlan")]
219 #[serde(skip_serializing_if = "Option::is_none")]
220 pub number_plan: Option<DigitRouter>,
221
222 #[serde(rename = "aniRouter")]
223 #[serde(skip_serializing_if = "Option::is_none")]
224 pub ani_router: Option<ANIRouter>,
225
226 #[serde(rename = "dnisRouter")]
227 #[serde(skip_serializing_if = "Option::is_none")]
228 pub dnis_router: Option<DNISRouter>,
229
230 #[serde(rename = "zoneRouter")]
231 #[serde(skip_serializing_if = "Option::is_none")]
232 pub zone_router: Option<ZoneRouter>,
233
234 #[serde(rename = "tagRouter")]
235 #[serde(skip_serializing_if = "Option::is_none")]
236 pub tag_router: Option<TagRouter>,
237
238 #[serde(rename = "timeRangeRoute")]
239 #[serde(skip_serializing_if = "Option::is_none")]
240 pub time_range_router: Option<TimeRangeRouter>,
241
242 #[serde(rename = "dayOfWeekRoute")]
243 #[serde(skip_serializing_if = "Option::is_none")]
244 pub day_of_week_router: Option<DayOfWeekRouter>,
245
246 #[serde(rename = "dateRangeRoute")]
247 #[serde(skip_serializing_if = "Option::is_none")]
248 pub date_range_router: Option<DateRangeRouter>,
249
250 #[serde(rename = "huntGroup")]
251 #[serde(skip_serializing_if = "Option::is_none")]
252 pub hunt_group: Option<HuntGroup>,
253
254 #[serde(rename = "client")]
255 #[serde(skip_serializing_if = "Option::is_none")]
256 pub client: Option<Client>,
257
258 #[serde(rename = "teams")]
259 #[serde(skip_serializing_if = "Option::is_none")]
260 pub teams: Option<Teams>,
261
262 #[serde(rename = "sipExtension")]
263 #[serde(skip_serializing_if = "Option::is_none")]
264 pub sip_extension: Option<SipExtension>,
265
266 #[serde(rename = "sipGateway")]
267 #[serde(skip_serializing_if = "Option::is_none")]
268 pub sip_gateway: Option<SipGateway>,
269
270 #[serde(rename = "remote")]
271 #[serde(skip_serializing_if = "Option::is_none")]
272 pub remote: Option<Remote>,
273
274 #[serde(rename = "voicemail")]
275 #[serde(skip_serializing_if = "Option::is_none")]
276 pub voice_mail: Option<VoiceMail>,
277
278 #[serde(rename = "queue")]
279 #[serde(skip_serializing_if = "Option::is_none")]
280 pub queue: Option<Queue>,
281
282 #[serde(rename = "plugin")]
283 #[serde(skip_serializing_if = "Option::is_none")]
284 pub plugin: Option<Plugin>,
285
286 #[serde(rename = "service")]
287 #[serde(skip_serializing_if = "Option::is_none")]
288 pub service: Option<Service>,
289
290 #[serde(rename = "play")]
291 #[serde(skip_serializing_if = "Option::is_none")]
292 pub play: Option<Play>,
293
294 #[serde(rename = "say")]
295 #[serde(skip_serializing_if = "Option::is_none")]
296 pub say: Option<Say>,
297
298 #[serde(rename = "script")]
299 #[serde(skip_serializing_if = "Option::is_none")]
300 pub script: Option<Script>,
301
302 #[serde(rename = "email")]
303 #[serde(skip_serializing_if = "Option::is_none")]
304 pub email: Option<Email>,
305
306 #[serde(rename = "sms")]
307 #[serde(skip_serializing_if = "Option::is_none")]
308 pub sms: Option<Sms>,
309
310 #[serde(rename = "tag")]
311 #[serde(skip_serializing_if = "Option::is_none")]
312 pub tag: Option<Tag>,
313
314 #[serde(rename = "event")]
315 #[serde(skip_serializing_if = "Option::is_none")]
316 pub event: Option<Event>,
317
318 #[serde(rename = "whatsAppRoute")]
319 #[serde(skip_serializing_if = "Option::is_none")]
320 pub whats_app_flow: Option<WhatsAppFlow>,
321
322 #[serde(rename = "messagePlugin")]
323 #[serde(skip_serializing_if = "Option::is_none")]
324 pub message_plugin: Option<MessagePlugin>,
325
326 #[serde(rename = "messageText")]
327 #[serde(skip_serializing_if = "Option::is_none")]
328 pub message_text: Option<MessageText>,
329
330 #[serde(rename = "messageButtons")]
331 #[serde(skip_serializing_if = "Option::is_none")]
332 pub message_buttons: Option<MessageButtons>,
333
334 #[serde(rename = "messageTemplate")]
335 #[serde(skip_serializing_if = "Option::is_none")]
336 pub message_template: Option<MessageTemplate>,
337
338 #[serde(rename = "messageANIRouter")]
339 #[serde(skip_serializing_if = "Option::is_none")]
340 pub message_ani_router: Option<MessageAniRouter>,
341
342 #[serde(rename = "messageDNISRouter")]
343 #[serde(skip_serializing_if = "Option::is_none")]
344 pub message_dnis_router: Option<MessageDnisRouter>,
345}
346
347fn from_str<'de, D>(deserializer: D) -> Result<u16, D::Error>
348where
349 D: Deserializer<'de>,
350{
351 let value = Value::deserialize(deserializer)?;
352 if value.is_string() {
353 Ok(value.as_str().unwrap().parse().unwrap())
354 } else if value.is_u64() {
355 Ok(value.as_u64().unwrap() as u16)
356 } else if value.is_i64() {
357 Ok(value.as_i64().unwrap() as u16)
358 } else {
359 Err(serde::de::Error::custom("Cannot map extension to u16"))
360 }
361}
362
363
364impl DeviceStruct {
365 pub fn record_options(&self) -> Option<RecordOptions> {
366 match &self.device_type {
367 DeviceType::HuntGroup => self.hunt_group.as_ref().map(|h| h.record_options.clone()), DeviceType::Client => self.client.as_ref().map(|c| c.record_options.clone()), DeviceType::Teams => self.teams.as_ref().map(|t| t.record_options.clone()), DeviceType::SipExtension => self.sip_extension.as_ref().map(|s| s.record_options.clone()), DeviceType::SipGateway => self.sip_gateway.as_ref().map(|s| s.record_options.clone()), DeviceType::Remote => self.remote.as_ref().map(|r| r.record_options.clone()), DeviceType::Plugin => self.plugin.as_ref().map(|p| p.record_options.clone()), DeviceType::Voicemail => self.voice_mail.as_ref().map(|v| v.record_options.clone()), _ => None,
376 }
377 }
378
379 pub fn transcribe_options(&self) -> Option<TranscribeOptions> {
380 match &self.device_type {
381 DeviceType::HuntGroup => self.hunt_group.as_ref().map(|h| h.transcribe_options.clone()),
382 DeviceType::Client => self.client.as_ref().map(|c| c.transcribe_options.clone()),
383 DeviceType::Teams => self.teams.as_ref().map(|t| t.transcribe_options.clone()),
384 DeviceType::SipExtension => self.sip_extension.as_ref().map(|s| s.transcribe_options.clone()),
385 DeviceType::SipGateway => self.sip_gateway.as_ref().map(|s| s.transcribe_options.clone()),
386 DeviceType::Remote => self.remote.as_ref().map(|r| r.transcribe_options.clone()),
387 DeviceType::Plugin => self.plugin.as_ref().map(|p| p.transcribe_options.clone()),
388 DeviceType::Voicemail => self.voice_mail.as_ref().map(|v| v.transcribe_options.clone()),
389 _ => None,
390 }
391 }
392
393 pub fn is_id(&self, _id: &str) -> bool {
394 self.id == _id
395 }
396
397 pub fn is_device_type(&self, device_type: DeviceType) -> bool {
398 self.device_type == device_type
399 }
400
401 pub fn match_device(&self, str: &str) -> bool {
402 let matched = match &self.device_type {
403 DeviceType::InboundFlow => {
404 self.start_route
405 .as_ref()
406 .map_or(false, |v| v.ddis.contains(&str.to_string()))
407 }
408 DeviceType::Client => {
409 self.client
410 .as_ref()
411 .map_or(false, |v| v.username.eq(str))
412 }
413 DeviceType::SipGateway => {
414 self.sip_gateway
415 .as_ref()
416 .map_or(false, |v| v.trunks.contains(&str.to_string()))
417 }
418 _ => false,
419 };
420
421 matched || self.id.eq(str) || self.extension.to_string().eq(str)
422 }
423
424 pub fn match_outbound_flow(&self) -> bool {
425 match &self.device_type {
426 DeviceType::OutboundFlow => true,
427 _ => false,
428 }
429 }
430
431 pub fn is_connector(&self) -> bool {
432 vec![
433 DeviceType::InboundFlow,
434 DeviceType::OutboundFlow,
435 DeviceType::AppFlow,
436 DeviceType::WhatsAppFlow,
437 DeviceType::AniRouter,
438 DeviceType::DnisRouter,
439 DeviceType::DigitRouter,
440 DeviceType::TimeRangeRouter,
441 DeviceType::DayOfWeekRouter,
442 DeviceType::DateRangeRouter,
443 DeviceType::Play,
444 DeviceType::Say,
445 DeviceType::Voicemail,
446 DeviceType::Script,
447 DeviceType::Queue,
448 DeviceType::Sms,
449 DeviceType::Email,
450 DeviceType::Tag,
451 DeviceType::TagRouter,
452 DeviceType::Service,
453 ]
454 .contains(&self.device_type)
455 }
456
457 pub fn is_call_handler(&self) -> bool {
458 vec![
459 DeviceType::HuntGroup,
460 DeviceType::Client,
461 DeviceType::Teams,
462 DeviceType::SipExtension,
463 DeviceType::SipGateway,
464 DeviceType::Remote,
465 DeviceType::Plugin,
466 ]
467 .contains(&self.device_type)
468 }
469}
470
471#[derive(Serialize, Deserialize, Clone)]
472#[serde(rename_all = "camelCase")]
473pub struct DeviceTag {
474 #[serde(rename = "type")]
475 pub tag_type: TagType,
476 pub name: String,
477 pub value: String,
478}
479
480#[derive(Serialize, Deserialize, Eq, PartialEq, Clone)]
481#[serde(rename_all = "camelCase")]
482pub enum TagType {
483 Session,
484 Global,
485}
486
487
488pub trait Endpoint {
489 fn get_caller_id(&self, state: &FlowState) -> String {
490 state.initial_request.from.clone()
491 }
492 fn get_called_id(&self, state: &FlowState) -> String {
493 state.initial_request.to.clone()
494 }
495 fn get_listen(&self, state: &FlowState) -> Option<Listen>;
496 fn get_proxy(&self, _state: &FlowState, _regions:Vec<Arc<Region>>) -> Option<VoiceServer> {
497 None
498 }
499 fn get_transcribe(&self, _state: &FlowState) -> Option<TranscribeDial> {
500 None
501 }
502}
503
504
505
506
507pub trait EndpointDevice: Connector {
509 fn is_endpoint(&self) -> bool {
510 true
511 }
512
513 fn device_type_name(&self) -> &'static str;
515
516 fn supports_routing(&self) -> bool {
518 false
519 }
520}
521
522
523
524impl Debug for DeviceType {
528 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
529 match self {
530 DeviceType::InboundFlow => write!(f, "InboundFlow"),
531 DeviceType::OutboundFlow => write!(f, "OutboundFlow"),
532 DeviceType::WhatsAppFlow => write!(f, "WhatsAppFlow"),
533 DeviceType::AppFlow => write!(f, "AppFlow"),
534 DeviceType::AniRouter => write!(f, "AniRouter"),
535 DeviceType::DnisRouter => write!(f, "DnisRouter"),
536 DeviceType::DigitRouter => write!(f, "DigitRouter"),
537 DeviceType::TimeRangeRouter => write!(f, "TimeRangeRouter"),
538 DeviceType::DayOfWeekRouter => write!(f, "DayOfWeekRouter"),
539 DeviceType::DateRangeRouter => write!(f, "DateRangeRouter"),
540 DeviceType::ZoneRouter => write!(f, "ZoneRouter"),
541 DeviceType::HuntGroup => write!(f, "HuntGroup"),
542 DeviceType::Client => write!(f, "Client"),
543 DeviceType::Teams => write!(f, "Teams"),
544 DeviceType::SipExtension => write!(f, "SipExtension"),
545 DeviceType::SipGateway => write!(f, "SipGateway"),
546 DeviceType::Remote => write!(f, "Remote"),
547 DeviceType::Plugin => write!(f, "Plugin"),
548 DeviceType::Play => write!(f, "Play"),
549 DeviceType::Say => write!(f, "Say"),
550 DeviceType::Voicemail => write!(f, "Voicemail"),
551 DeviceType::Script => write!(f, "Script"),
552 DeviceType::Queue => write!(f, "Queue"),
553 DeviceType::Sms => write!(f, "Sms"),
554 DeviceType::Email => write!(f, "Email"),
555 DeviceType::Tag => write!(f, "Tag"),
556 DeviceType::TagRouter => write!(f, "TagRouter"),
557 DeviceType::MessagePlugin => write!(f, "MessagePlugin"),
558 DeviceType::MessageText => write!(f, "MessageText"),
559 DeviceType::MessageButtons => write!(f, "MessageButtons"),
560 DeviceType::MessageTemplate => write!(f, "MessageTemplate"),
561 DeviceType::MessageAniRouter => write!(f, "MessageAniRouter"),
562 DeviceType::Service => write!(f, "Service"),
563 }
564 }
565}
566
567
568
569impl Debug for Device {
571 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
572 match self {
573 Device::InboundFlow(_) => write!(f, "Device::InboundFlow"),
574 Device::OutboundFlow(_) => write!(f, "Device::OutboundFlow"),
575 Device::WhatsAppFlow(_) => write!(f, "Device::WhatsAppFlow"),
576 Device::AppFlow(_) => write!(f, "Device::AppFlow"),
577 Device::AniRouter(_) => write!(f, "Device::AniRouter"),
578 Device::DnisRouter(_) => write!(f, "Device::DnisRouter"),
579 Device::DigitRouter(_) => write!(f, "Device::DigitRouter"),
580 Device::TimeRangeRouter(_) => write!(f, "Device::TimeRangeRouter"),
581 Device::DayOfWeekRouter(_) => write!(f, "Device::DayOfWeekRouter"),
582 Device::DateRangeRouter(_) => write!(f, "Device::DateRangeRouter"),
583 Device::ZoneRouter(_) => write!(f, "Device::ZoneRouter"),
584 Device::HuntGroup(_) => write!(f, "Device::HuntGroup"),
585 Device::Client(_) => write!(f, "Device::Client"),
586 Device::Teams(_) => write!(f, "Device::Teams"),
587 Device::SipExtension(_) => write!(f, "Device::SipExtension"),
588 Device::SipGateway(_) => write!(f, "Device::SipGateway"),
589 Device::Remote(_) => write!(f, "Device::Remote"),
590 Device::Plugin(_) => write!(f, "Device::Plugin"),
591 Device::Play(_) => write!(f, "Device::Play"),
592 Device::Say(_) => write!(f, "Device::Say"),
593 Device::Voicemail(_) => write!(f, "Device::Voicemail"),
594 Device::Script(_) => write!(f, "Device::Script"),
595 Device::Queue(_) => write!(f, "Device::Queue"),
596 Device::Sms(_) => write!(f, "Device::Sms"),
597 Device::Email(_) => write!(f, "Device::Email"),
598 Device::Tag(_) => write!(f, "Device::Tag"),
599 Device::TagRouter(_) => write!(f, "Device::TagRouter"),
600 Device::MessagePlugin(_) => write!(f, "Device::MessagePlugin"),
601 Device::MessageButtons(_) => write!(f, "Device::MessageButtons"),
602 Device::MessageText(_) => write!(f, "Device::MessageText"),
603 Device::MessageTemplate(_) => write!(f, "Device::MessageTemplate"),
604 Device::MessageAniRouter(_) => write!(f, "Device::MessageAniRouter"),
605 Device::Service(_) => write!(f, "Device::Service"),
606 }
607 }
608}
609
610impl Debug for DeviceStruct {
612 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
613 f.debug_struct("DeviceStruct")
614 .field("id", &self.id)
615 .field("device_type", &self.device_type)
616 .field("name", &self.name)
617 .field("extension", &self.extension)
618 .finish_non_exhaustive()
619 }
620}
621
622impl Debug for TagType {
624 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
625 match self {
626 TagType::Session => write!(f, "Session"),
627 TagType::Global => write!(f, "Global"),
628 }
629 }
630}
631
632impl Debug for DeviceTag {
634 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
635 f.debug_struct("DeviceTag")
636 .field("tag_type", &self.tag_type)
637 .field("name", &self.name)
638 .field("value", &self.value)
639 .finish()
640 }
641}
642
643
644
645
646
647impl Debug for RecordOptions {
649 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
650 f.debug_struct("RecordOptions")
651 .field("enabled", &self.enabled)
652 .field("retention", &self.retention)
653 .field("mix_type", &self.mix_type)
654 .field("sample_rate", &self.sample_rate)
655 .finish()
656 }
657}
658
659impl Debug for TranscribeOptions {
661 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
662 f.debug_struct("TranscribeOptions")
663 .field("enabled", &self.enabled)
664 .field("language", &self.language)
665 .finish()
666 }
667}
668
669impl Debug for AsrVendor {
671 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
672
673 match self {
674 AsrVendor::Google => write!(f, "Google"),
675 AsrVendor::Deepgram => write!(f, "DeepGram"),
676 AsrVendor::Microsoft => write!(f, "Microsoft"),
677 AsrVendor::Aws => write!(f, "Aws"),
678 AsrVendor::Ibm => write!(f, "Ibm"),
679 AsrVendor::Nuance => write!(f, "Nuance"),
680 AsrVendor::Nvidia =>write!(f, "Nvidia"),
681 AsrVendor::Soniox => write!(f, "Soniox"),
682 }
683 }
684}