1use crate::apis::bridges::models::Bridge;
2use crate::apis::channels::models::Channel;
3use crate::apis::device_stats::models::DeviceState;
4use crate::apis::endpoints::models::{Endpoint, TextMessage};
5use crate::apis::playbacks::models::Playback;
6use crate::apis::recordings::models::LiveRecording;
7use chrono::{DateTime, Utc};
8use serde::Deserialize;
9use std::fmt;
10
11#[derive(Clone, Debug, PartialEq, Deserialize)]
13pub struct BaseEvent<T> {
14 #[serde(skip_serializing_if = "Option::is_none")]
16 pub asterisk_id: Option<String>,
17
18 pub application: String,
20
21 pub timestamp: DateTime<Utc>,
23
24 #[serde(flatten)]
26 pub data: T,
27}
28
29#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
32pub struct ApplicationMoveFailed {
33 #[serde(rename = "channel")]
34 pub channel: Channel,
35 #[serde(rename = "destination")]
36 pub destination: String,
37 #[serde(rename = "args")]
38 pub args: Vec<String>,
39}
40
41#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
44pub struct ApplicationReplaced {}
45
46#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
49pub struct BridgeAttendedTransfer {
50 #[serde(rename = "transferer_first_leg")]
52 pub transferer_first_leg: Channel,
53 #[serde(rename = "transferer_second_leg")]
55 pub transferer_second_leg: Channel,
56
57 #[serde(rename = "replace_channel")]
59 pub replace_channel: Option<Channel>,
60
61 #[serde(rename = "transferee")]
63 pub transferee: Option<Channel>,
64
65 #[serde(rename = "transfer_target")]
67 pub transfer_target: Option<Channel>,
68
69 #[serde(rename = "result")]
71 pub result: String,
72
73 #[serde(rename = "is_external")]
75 pub is_external: bool,
76
77 #[serde(rename = "transferer_first_leg_bridge")]
79 pub transferer_first_leg_bridge: Option<Bridge>,
80
81 #[serde(rename = "transferer_second_leg_bridge")]
83 pub transferer_second_leg_bridge: Option<Bridge>,
84
85 #[serde(rename = "destination_type")]
87 pub destination_type: String,
88
89 #[serde(rename = "destination_bridge")]
91 pub destination_bridge: Option<String>,
92
93 #[serde(rename = "destination_application")]
95 pub destination_application: Option<String>,
96
97 #[serde(rename = "destination_link_first_leg")]
99 pub destination_link_first_leg: Option<Channel>,
100
101 #[serde(rename = "destination_link_second_leg")]
103 pub destination_link_second_leg: Option<Channel>,
104
105 #[serde(rename = "destination_threeway_channel")]
107 pub destination_threeway_channel: Option<Channel>,
108
109 #[serde(rename = "destination_threeway_bridge")]
111 pub destination_threeway_bridge: Option<Bridge>,
112}
113
114#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
117pub struct BridgeBlindTransfer {
118 #[serde(rename = "channel")]
120 pub channel: Channel,
121
122 #[serde(rename = "replace_channel")]
124 pub replace_channel: Option<Channel>,
125
126 #[serde(rename = "transferee")]
128 pub transferee: Option<Channel>,
129
130 #[serde(rename = "exten")]
132 pub exten: String,
133 #[serde(rename = "context")]
135 pub context: String,
136 #[serde(rename = "result")]
138 pub result: String,
139 #[serde(rename = "is_external")]
141 pub is_external: bool,
142
143 #[serde(rename = "bridge")]
145 pub bridge: Option<Bridge>,
146}
147
148#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
150pub struct BridgeCreated {
151 #[serde(rename = "bridge")]
152 pub bridge: Bridge,
153}
154
155#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
157pub struct BridgeDestroyed {
158 #[serde(rename = "bridge")]
159 pub bridge: Bridge,
160}
161
162#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
163pub struct BridgeMerged {
164 #[serde(rename = "bridge")]
165 pub bridge: Bridge,
166 #[serde(rename = "bridge_from")]
167 pub bridge_from: Bridge,
168}
169
170#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
172pub struct BridgeVideoSourceChanged {
173 #[serde(rename = "bridge")]
174 pub bridge: Bridge,
175 #[serde(rename = "old_video_source_id")]
176 pub old_video_source_id: Option<String>,
177}
178
179#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
181pub struct ChannelCallerId {
182 #[serde(rename = "caller_presentation")]
184 pub caller_presentation: u32,
185
186 #[serde(rename = "caller_presentation_txt")]
188 pub caller_presentation_txt: String,
189
190 #[serde(rename = "channel")]
192 pub channel: Channel,
193}
194
195#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
197pub struct ChannelConnectedLine {
198 #[serde(rename = "channel")]
200 pub channel: Channel,
201}
202
203#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
205pub struct ChannelCreated {
206 #[serde(rename = "channel")]
207 pub channel: Channel,
208}
209
210#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
212pub struct ChannelDestroyed {
213 #[serde(rename = "cause")]
214 pub cause: u32,
215 #[serde(rename = "cause_txt")]
217 pub cause_txt: String,
219 #[serde(rename = "channel")]
220 pub channel: Channel,
221}
222#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
224pub struct ChannelDialplan {
225 #[serde(rename = "channel")]
227 pub channel: Channel,
228 #[serde(rename = "dialplan_app")]
230 pub dialplan_app: String,
231 #[serde(rename = "dialplan_app_data")]
233 pub dialplan_app_data: String,
234}
235
236#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
240pub struct ChannelDtmfReceived {
241 #[serde(rename = "digit")]
243 pub digit: String,
244 #[serde(rename = "duration_ms")]
246 pub duration_ms: u32,
247 #[serde(rename = "channel")]
249 pub channel: Channel,
250}
251
252#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
254pub struct ChannelEnteredBridge {
255 #[serde(rename = "bridge")]
256 pub bridge: Bridge,
257 #[serde(rename = "channel")]
258 pub channel: Option<Channel>,
259}
260
261#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
263pub struct ChannelHangupRequest {
264 #[serde(rename = "cause")]
266 pub cause: u32,
267 #[serde(rename = "soft")]
269 pub soft: Option<bool>,
270 #[serde(rename = "channel")]
272 pub channel: Channel,
273}
274
275#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
277pub struct ChannelHold {
278 #[serde(rename = "channel")]
279 pub channel: Channel,
280 #[serde(rename = "musicclass")]
282 pub musicclass: Option<String>,
283}
284
285#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
287pub struct ChannelLeftBridge {
288 #[serde(rename = "bridge")]
289 pub bridge: Bridge,
290 #[serde(rename = "channel")]
291 pub channel: Channel,
292}
293
294#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
296pub struct ChannelStateChange {
297 #[serde(rename = "channel")]
298 pub channel: Channel,
299}
300
301#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
303pub struct ChannelTalkingFinished {
304 #[serde(rename = "channel")]
305 pub channel: Channel,
306 #[serde(rename = "duration")]
307 pub duration: u32,
308}
309
310#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
312pub struct ChannelTalkingStarted {
313 #[serde(rename = "channel")]
314 pub channel: Channel,
315}
316
317#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
319pub struct ChannelToneDetected {
320 #[serde(rename = "channel")]
321 pub channel: Channel,
322}
323
324#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
326pub struct ChannelUnhold {
327 #[serde(rename = "channel")]
328 pub channel: Channel,
329}
330
331#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
333pub struct ChannelUserEvent {
334 #[serde(rename = "eventname")]
336 pub event_name: String,
337
338 #[serde(rename = "channel")]
340 pub channel: Option<Channel>,
341 #[serde(rename = "bridge")]
343 pub bridge: Option<Bridge>,
344 #[serde(rename = "endpoint")]
346 pub endpoint: Option<Endpoint>,
347 #[serde(rename = "userevent")]
349 pub user_event: Option<serde_json::Value>,
350}
351
352#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
354pub struct ChannelVarSet {
355 #[serde(rename = "variable")]
357 pub variable: String,
358 #[serde(rename = "value")]
360 pub value: String,
361 #[serde(rename = "channel")]
364 pub channel: Option<Channel>,
365}
366
367#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
369pub struct ContactInfo {
370 #[serde(rename = "uri")]
372 pub uri: String,
373 #[serde(rename = "contact_status")]
375 pub contact_status: String,
376 #[serde(rename = "aor")]
378 pub aor: String,
379 #[serde(rename = "roundtrip_usec")]
382 pub roundtrip_usec: Option<String>,
383}
384
385#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
387pub struct ContactStatusChange {
388 #[serde(rename = "endpoint")]
389 pub endpoint: Endpoint,
390 #[serde(rename = "contact_info")]
391 pub contact_info: ContactInfo,
392}
393
394#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
396pub struct DeviceStateChanged {
397 #[serde(rename = "device_state")]
399 pub device_state: DeviceState,
400}
401
402#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
404pub struct Dial {
405 #[serde(rename = "caller")]
407 pub caller: Option<Channel>,
408
409 #[serde(rename = "peer")]
411 pub peer: Option<Channel>,
412 #[serde(rename = "forward")]
414 pub forward: Option<String>,
415 #[serde(rename = "forwarded")]
416 pub forwarded: Option<Channel>,
417 #[serde(rename = "dialstring")]
419 pub dialstring: Option<String>,
420 #[serde(rename = "dialstatus")]
422 pub dialstatus: String,
423}
424
425#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
427pub struct EndpointStateChange {
428 #[serde(rename = "endpoint")]
429 pub endpoint: Endpoint,
430}
431
432#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
434pub struct MissingParams {
435 #[serde(rename = "params")]
437 pub params: Vec<String>,
438}
439
440#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
442pub struct Peer {
443 #[serde(rename = "peer_status")]
445 pub peer_status: String,
446 #[serde(rename = "cause")]
448 pub cause: Option<String>,
449 #[serde(rename = "address")]
451 pub address: Option<String>,
452 #[serde(rename = "port")]
454 pub port: Option<String>,
455 #[serde(rename = "time")]
457 pub time: Option<String>,
458}
459
460#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
462pub struct PeerStatusChange {
463 #[serde(rename = "endpoint")]
464 pub endpoint: Endpoint,
465 #[serde(rename = "peer")]
466 pub peer: Peer,
467}
468
469#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
471pub struct PlaybackContinuing {
472 #[serde(rename = "playback")]
474 pub playback: Playback,
475}
476
477#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
479pub struct PlaybackFinished {
480 #[serde(rename = "playback")]
482 pub playback: Playback,
483}
484
485#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
487pub struct PlaybackStarted {
488 #[serde(rename = "playback")]
489 pub playback: Playback,
490}
491
492#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
494pub struct RecordingFailed {
495 #[serde(rename = "recording")]
497 pub recording: LiveRecording,
498}
499
500#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
502pub struct RecordingFinished {
503 #[serde(rename = "recording")]
504 pub recording: LiveRecording,
505}
506
507#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
509pub struct RecordingStarted {
510 #[serde(rename = "recording")]
511 pub recording: LiveRecording,
512}
513
514#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
516pub struct StasisEnd {
517 #[serde(rename = "channel")]
518 pub channel: Channel,
519}
520
521#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
523pub struct StasisStart {
524 #[serde(rename = "args")]
525 pub args: Vec<String>,
526 #[serde(rename = "channel")]
527 pub channel: Channel,
528 #[serde(rename = "replace_channel")]
529 pub replace_channel: Option<Channel>,
530}
531
532#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
534pub struct TextMessageReceived {
535 #[serde(rename = "message")]
536 pub message: TextMessage,
537
538 #[serde(rename = "endpoint")]
539 pub endpoint: Option<Endpoint>,
540}
541
542#[derive(Clone, Debug, Deserialize)]
543#[serde(tag = "type")]
544pub enum Event {
545 ApplicationMoveFailed(BaseEvent<ApplicationMoveFailed>),
546 ApplicationReplaced(BaseEvent<ApplicationReplaced>),
547 BridgeAttendedTransfer(BaseEvent<BridgeAttendedTransfer>),
548 BridgeBlindTransfer(BaseEvent<BridgeBlindTransfer>),
549 BridgeCreated(BaseEvent<BridgeCreated>),
550 BridgeDestroyed(BaseEvent<BridgeDestroyed>),
551 BridgeMerged(BaseEvent<BridgeMerged>),
552 BridgeVideoSourceChanged(BaseEvent<BridgeVideoSourceChanged>),
553 ChannelCallerId(BaseEvent<ChannelCallerId>),
554 ChannelConnectedLine(BaseEvent<ChannelConnectedLine>),
555 ChannelCreated(BaseEvent<ChannelCreated>),
556 ChannelDestroyed(BaseEvent<ChannelDestroyed>),
557 ChannelDialplan(BaseEvent<ChannelDialplan>),
558 ChannelDtmfReceived(BaseEvent<ChannelDtmfReceived>),
559 ChannelEnteredBridge(BaseEvent<ChannelEnteredBridge>),
560 ChannelHangupRequest(BaseEvent<ChannelHangupRequest>),
561 ChannelHold(BaseEvent<ChannelHold>),
562 ChannelLeftBridge(BaseEvent<ChannelLeftBridge>),
563 ChannelStateChange(BaseEvent<ChannelStateChange>),
564 ChannelTalkingFinished(BaseEvent<ChannelTalkingFinished>),
565 ChannelTalkingStarted(BaseEvent<ChannelTalkingStarted>),
566 ChannelToneDetected(BaseEvent<ChannelToneDetected>),
567 ChannelUnhold(BaseEvent<ChannelUnhold>),
568 #[serde(rename = "ChannelUserevent")]
569 ChannelUserEvent(BaseEvent<ChannelUserEvent>),
570 #[serde(rename = "ChannelVarset")]
571 ChannelVarSet(BaseEvent<ChannelVarSet>),
572 ContactInfo(BaseEvent<ContactInfo>),
573 ContactStatusChange(BaseEvent<ContactStatusChange>),
574 DeviceStateChanged(BaseEvent<DeviceStateChanged>),
575 Dial(BaseEvent<Dial>),
576 EndpointStateChange(BaseEvent<EndpointStateChange>),
577 MissingParams(BaseEvent<MissingParams>),
578 Peer(BaseEvent<Peer>),
579 PeerStatusChange(BaseEvent<PeerStatusChange>),
580 PlaybackContinuing(BaseEvent<PlaybackContinuing>),
581 PlaybackFinished(BaseEvent<PlaybackFinished>),
582 PlaybackStarted(BaseEvent<PlaybackStarted>),
583 RecordingFailed(BaseEvent<RecordingFailed>),
584 RecordingFinished(BaseEvent<RecordingFinished>),
585 RecordingStarted(BaseEvent<RecordingStarted>),
586 StasisEnd(BaseEvent<StasisEnd>),
587 StasisStart(BaseEvent<StasisStart>),
588 TextMessageReceived(BaseEvent<TextMessageReceived>),
589
590 #[serde(untagged)]
591 Unknown(serde_json::Value),
592}
593
594impl fmt::Display for Event {
595 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
596 match self {
597 Event::ApplicationMoveFailed(_) => write!(f, "ApplicationMoveFailed"),
598 Event::ApplicationReplaced(_) => write!(f, "ApplicationReplaced"),
599 Event::BridgeAttendedTransfer(_) => write!(f, "BridgeAttendedTransfer"),
600 Event::BridgeBlindTransfer(_) => write!(f, "BridgeBlindTransfer"),
601 Event::BridgeCreated(_) => write!(f, "BridgeCreated"),
602 Event::BridgeDestroyed(_) => write!(f, "BridgeDestroyed"),
603 Event::BridgeMerged(_) => write!(f, "BridgeMerged"),
604 Event::BridgeVideoSourceChanged(_) => write!(f, "BridgeVideoSourceChanged"),
605 Event::ChannelCallerId(_) => write!(f, "ChannelCallerId"),
606 Event::ChannelConnectedLine(_) => write!(f, "ChannelConnectedLine"),
607 Event::ChannelCreated(_) => write!(f, "ChannelCreated"),
608 Event::ChannelDestroyed(_) => write!(f, "ChannelDestroyed"),
609 Event::ChannelDialplan(_) => write!(f, "ChannelDialplan"),
610 Event::ChannelDtmfReceived(_) => write!(f, "ChannelDtmfReceived"),
611 Event::ChannelEnteredBridge(_) => write!(f, "ChannelEnteredBridge"),
612 Event::ChannelHangupRequest(_) => write!(f, "ChannelHangupRequest"),
613 Event::ChannelHold(_) => write!(f, "ChannelHold"),
614 Event::ChannelLeftBridge(_) => write!(f, "ChannelLeftBridge"),
615 Event::ChannelStateChange(_) => write!(f, "ChannelStateChange"),
616 Event::ChannelTalkingFinished(_) => write!(f, "ChannelTalkingFinished"),
617 Event::ChannelTalkingStarted(_) => write!(f, "ChannelTalkingStarted"),
618 Event::ChannelToneDetected(_) => write!(f, "ChannelToneDetected"),
619 Event::ChannelUnhold(_) => write!(f, "ChannelUnhold"),
620 Event::ChannelUserEvent(_) => write!(f, "ChannelUserEvent"),
621 Event::ChannelVarSet(_) => write!(f, "ChannelVarSet"),
622 Event::ContactInfo(_) => write!(f, "ContactInfo"),
623 Event::ContactStatusChange(_) => write!(f, "ContactStatusChange"),
624 Event::DeviceStateChanged(_) => write!(f, "DeviceStateChanged"),
625 Event::Dial(_) => write!(f, "Dial"),
626 Event::EndpointStateChange(_) => write!(f, "EndpointStateChange"),
627 Event::MissingParams(_) => write!(f, "MissingParams"),
628 Event::Peer(_) => write!(f, "Peer"),
629 Event::PeerStatusChange(_) => write!(f, "PeerStatusChange"),
630 Event::PlaybackContinuing(_) => write!(f, "PlaybackContinuing"),
631 Event::PlaybackFinished(_) => write!(f, "PlaybackFinished"),
632 Event::PlaybackStarted(_) => write!(f, "PlaybackStarted"),
633 Event::RecordingFailed(_) => write!(f, "RecordingFailed"),
634 Event::RecordingFinished(_) => write!(f, "RecordingFinished"),
635 Event::RecordingStarted(_) => write!(f, "RecordingStarted"),
636 Event::StasisEnd(_) => write!(f, "StasisEnd"),
637 Event::StasisStart(_) => write!(f, "StasisStart"),
638 Event::TextMessageReceived(_) => write!(f, "TextMessageReceived"),
639 Event::Unknown(_) => write!(f, "Unknown"),
640 }
641 }
642}
643
644#[cfg(test)]
645mod tests {
646 use super::*;
647
648 #[test]
649 fn test_parse_unknown_event() {
650 let e = "{\n \"type\": \"NotKnown\",\n \"timestamp\": \"2021-01-07T22:12:29.571+0100\",\n \"channel\": {\n \"id\": \"1610053949.0\",\n \"name\": \"SIP/1004-00000000\",\n \"state\": \"Up\",\n \"caller\": {\n \"name\": \"Adam\",\n \"number\": \"1004\"\n },\n \"connected\": {\n \"name\": \"\",\n \"number\": \"\"\n },\n \"accountcode\": \"\",\n \"dialplan\": {\n \"context\": \"internal\",\n \"exten\": \"158\",\n \"priority\": 10,\n \"app_name\": \"Stasis\",\n \"app_data\": \"va-voicegw-rs,freight-cs-voice,en-US\"\n },\n \"creationtime\": \"2021-01-07T22:12:29.369+0100\",\n \"language\": \"en\"\n },\n \"asterisk_id\": \"00:50:56:98:74:21\",\n \"application\": \"va-voicegw-rs\"\n}";
651 let ari_event: Event = serde_json::from_str(e).unwrap();
652 assert!(matches!(ari_event, Event::Unknown(_)));
653 }
654
655 #[test]
656 fn test_parse_stasis_start() {
657 let e = "{\n \"type\": \"StasisStart\",\n \"timestamp\": \"2020-11-22T20:17:06.150+0000\",\n \"args\": [\n \"its-va-demo-app\",\n \"en-US\"\n ],\n \"channel\": {\n \"id\": \"1606076223.3\",\n \"name\": \"PJSIP/6001-00000003\",\n \"state\": \"Up\",\n \"caller\": {\n \"name\": \"\",\n \"number\": \"6001\"\n },\n \"connected\": {\n \"name\": \"\",\n \"number\": \"\"\n },\n \"accountcode\": \"\",\n \"dialplan\": {\n \"context\": \"from-internal\",\n \"exten\": \"101\",\n \"priority\": 6,\n \"app_name\": \"Stasis\",\n \"app_data\": \"va-voicegw,its-va-demo-app,en-US\"\n },\n \"creationtime\": \"2020-11-22T20:17:03.741+0000\",\n \"language\": \"en\"\n },\n \"asterisk_id\": \"00:15:5d:01:65:04\",\n \"application\": \"va-voicegw\"\n}";
658 let ari_event: Event = serde_json::from_str(e).unwrap();
659 assert!(matches!(ari_event, Event::StasisStart(_)));
660 }
661
662 #[test]
664 fn test_parse_stasis_start_with_timezone() {
665 let e = "{\n \"type\": \"StasisStart\",\n \"timestamp\": \"2021-01-07T21:12:57.268+0100\",\n \"args\": [\n \"freight-cs-voice\",\n \"en-US\"\n ],\n \"channel\": {\n \"id\": \"1610050377.0\",\n \"name\": \"SIP/1004-00000000\",\n \"state\": \"Ring\",\n \"caller\": {\n \"name\": \"Adam\",\n \"number\": \"1004\"\n },\n \"connected\": {\n \"name\": \"\",\n \"number\": \"\"\n },\n \"accountcode\": \"\",\n \"dialplan\": {\n \"context\": \"internal\",\n \"exten\": \"158\",\n \"priority\": 10,\n \"app_name\": \"Stasis\",\n \"app_data\": \"va-voicegw-rs,freight-cs-voice,en-US\"\n },\n \"creationtime\": \"2021-01-07T21:12:57.267+0100\",\n \"language\": \"en\"\n },\n \"asterisk_id\": \"00:50:56:98:74:21\",\n \"application\": \"va-voicegw-rs\"\n}";
666 let ari_event: Event = serde_json::from_str(e).unwrap();
667 assert!(matches!(ari_event, Event::StasisStart(_)));
668
669 if let Event::StasisStart(base_event) = ari_event {
670 assert_eq!(
671 base_event.timestamp.to_string(),
672 "2021-01-07 20:12:57.268 UTC"
673 );
674 }
675 }
676
677 #[test]
679 fn test_parse_channel_state_change() {
680 let e = "{\n \"type\": \"ChannelStateChange\",\n \"timestamp\": \"2021-01-07T22:12:29.571+0100\",\n \"channel\": {\n \"id\": \"1610053949.0\",\n \"name\": \"SIP/1004-00000000\",\n \"state\": \"Up\",\n \"caller\": {\n \"name\": \"Adam\",\n \"number\": \"1004\"\n },\n \"connected\": {\n \"name\": \"\",\n \"number\": \"\"\n },\n \"accountcode\": \"\",\n \"dialplan\": {\n \"context\": \"internal\",\n \"exten\": \"158\",\n \"priority\": 10,\n \"app_name\": \"Stasis\",\n \"app_data\": \"va-voicegw-rs,freight-cs-voice,en-US\"\n },\n \"creationtime\": \"2021-01-07T22:12:29.369+0100\",\n \"language\": \"en\"\n },\n \"asterisk_id\": \"00:50:56:98:74:21\",\n \"application\": \"va-voicegw-rs\"\n}";
681 let ari_event: Event = serde_json::from_str(e).unwrap();
682 println!("{:#?}", ari_event);
683 }
684}