asterisk_ari/ws/
models.rs

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/// BaseEvent
12#[derive(Clone, Debug, PartialEq, Deserialize)]
13pub struct BaseEvent<T> {
14    /// The unique ID for the Asterisk instance that raised this event.
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub asterisk_id: Option<String>,
17
18    /// Name of the application receiving the event.
19    pub application: String,
20
21    /// Time at which this event was created. E.g. 2020-11-22T20:12:51.214+0000
22    pub timestamp: DateTime<Utc>,
23
24    /// The event data.
25    #[serde(flatten)]
26    pub data: T,
27}
28
29/// ApplicationMoveFailed
30/// Notification that trying to move a channel to another Stasis application failed.
31#[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/// ApplicationMoveFailed
42/// Notification that another WebSocket has taken over for an application.
43#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
44pub struct ApplicationReplaced {}
45
46/// BridgeAttendedTransfer
47/// Notification that an attended transfer has occurred.
48#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
49pub struct BridgeAttendedTransfer {
50    /// First leg of the transferer
51    #[serde(rename = "transferer_first_leg")]
52    pub transferer_first_leg: Channel,
53    /// Second leg of the transferer
54    #[serde(rename = "transferer_second_leg")]
55    pub transferer_second_leg: Channel,
56
57    /// The channel that is replacing transferer_first_leg in the swap
58    #[serde(rename = "replace_channel")]
59    pub replace_channel: Option<Channel>,
60
61    /// The channel that is being transferred
62    #[serde(rename = "transferee")]
63    pub transferee: Option<Channel>,
64
65    /// The channel that is being transferred to
66    #[serde(rename = "transfer_target")]
67    pub transfer_target: Option<Channel>,
68
69    /// The result of the transfer attempt
70    #[serde(rename = "result")]
71    pub result: String,
72
73    /// Whether the transfer was externally initiated or not
74    #[serde(rename = "is_external")]
75    pub is_external: bool,
76
77    /// Bridge the transferer first leg is in
78    #[serde(rename = "transferer_first_leg_bridge")]
79    pub transferer_first_leg_bridge: Option<Bridge>,
80
81    /// Bridge the transferer second leg is in
82    #[serde(rename = "transferer_second_leg_bridge")]
83    pub transferer_second_leg_bridge: Option<Bridge>,
84
85    /// How the transfer was accomplished
86    #[serde(rename = "destination_type")]
87    pub destination_type: String,
88
89    /// Bridge that survived the merge result
90    #[serde(rename = "destination_bridge")]
91    pub destination_bridge: Option<String>,
92
93    /// Application that has been transferred into
94    #[serde(rename = "destination_application")]
95    pub destination_application: Option<String>,
96
97    /// First leg of a link transfer result
98    #[serde(rename = "destination_link_first_leg")]
99    pub destination_link_first_leg: Option<Channel>,
100
101    /// Second leg of a link transfer result
102    #[serde(rename = "destination_link_second_leg")]
103    pub destination_link_second_leg: Option<Channel>,
104
105    /// Transferer channel that survived the threeway result
106    #[serde(rename = "destination_threeway_channel")]
107    pub destination_threeway_channel: Option<Channel>,
108
109    /// Bridge that survived the threeway result
110    #[serde(rename = "destination_threeway_bridge")]
111    pub destination_threeway_bridge: Option<Bridge>,
112}
113
114/// BridgeBlindTransfer :
115/// Notification that a blind transfer has occurred.
116#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
117pub struct BridgeBlindTransfer {
118    /// The channel performing the blind transfer
119    #[serde(rename = "channel")]
120    pub channel: Channel,
121
122    /// The channel that is replacing transferer when the transferee(s) can not be transferred directly
123    #[serde(rename = "replace_channel")]
124    pub replace_channel: Option<Channel>,
125
126    /// The channel that is being transferred
127    #[serde(rename = "transferee")]
128    pub transferee: Option<Channel>,
129
130    /// The extension transferred to
131    #[serde(rename = "exten")]
132    pub exten: String,
133    /// The context transferred to
134    #[serde(rename = "context")]
135    pub context: String,
136    /// The result of the transfer attempt
137    #[serde(rename = "result")]
138    pub result: String,
139    /// Whether the transfer was externally initiated or not
140    #[serde(rename = "is_external")]
141    pub is_external: bool,
142
143    /// The bridge being transferred
144    #[serde(rename = "bridge")]
145    pub bridge: Option<Bridge>,
146}
147
148/// Notification that a bridge has been created.
149#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
150pub struct BridgeCreated {
151    #[serde(rename = "bridge")]
152    pub bridge: Bridge,
153}
154
155/// Notification that a bridge has been destroyed.
156#[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/// Notification that the source of video in a bridge has changed.
171#[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/// Channel changed Caller ID.
180#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
181pub struct ChannelCallerId {
182    /// The integer representation of the Caller Presentation value.
183    #[serde(rename = "caller_presentation")]
184    pub caller_presentation: u32,
185
186    /// The text representation of the Caller Presentation value.
187    #[serde(rename = "caller_presentation_txt")]
188    pub caller_presentation_txt: String,
189
190    /// The channel that changed Caller ID.
191    #[serde(rename = "channel")]
192    pub channel: Channel,
193}
194
195/// Channel changed Connected Line.
196#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
197pub struct ChannelConnectedLine {
198    /// The channel whose connected line has changed.
199    #[serde(rename = "channel")]
200    pub channel: Channel,
201}
202
203/// ChannelCreated: Notification that a channel has been created.
204#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
205pub struct ChannelCreated {
206    #[serde(rename = "channel")]
207    pub channel: Channel,
208}
209
210/// Notification that a channel has been destroyed.
211#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
212pub struct ChannelDestroyed {
213    #[serde(rename = "cause")]
214    pub cause: u32,
215    /// Text representation of the cause of the hangup
216    #[serde(rename = "cause_txt")]
217    /// Text representation of the cause of the hangup
218    pub cause_txt: String,
219    #[serde(rename = "channel")]
220    pub channel: Channel,
221}
222/// Channel changed location in the dialplan.
223#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
224pub struct ChannelDialplan {
225    /// The channel that changed dialplan location.
226    #[serde(rename = "channel")]
227    pub channel: Channel,
228    /// The application about to be executed.
229    #[serde(rename = "dialplan_app")]
230    pub dialplan_app: String,
231    /// The data to be passed to the application.
232    #[serde(rename = "dialplan_app_data")]
233    pub dialplan_app_data: String,
234}
235
236/// ChannelDtmfReceived :
237/// DTMF received on a channel.  
238/// This event is sent when the DTMF ends. There is no notification about the start of DTMF
239#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
240pub struct ChannelDtmfReceived {
241    /// DTMF digit received (0-9, A-E, # or *)
242    #[serde(rename = "digit")]
243    pub digit: String,
244    /// Number of milliseconds DTMF was received
245    #[serde(rename = "duration_ms")]
246    pub duration_ms: u32,
247    /// The channel on which DTMF was received
248    #[serde(rename = "channel")]
249    pub channel: Channel,
250}
251
252/// Notification that a channel has entered a bridge.
253#[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/// A hangup was requested on the channel.
262#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
263pub struct ChannelHangupRequest {
264    /// Integer representation of the cause of the hangup.
265    #[serde(rename = "cause")]
266    pub cause: u32,
267    /// Whether the hangup request was a soft hangup request.
268    #[serde(rename = "soft")]
269    pub soft: Option<bool>,
270    /// The channel on which the hangup was requested.
271    #[serde(rename = "channel")]
272    pub channel: Channel,
273}
274
275/// A channel initiated a media hold.
276#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
277pub struct ChannelHold {
278    #[serde(rename = "channel")]
279    pub channel: Channel,
280    /// The music on hold class that the initiator requested.
281    #[serde(rename = "musicclass")]
282    pub musicclass: Option<String>,
283}
284
285/// Notification that a channel has left a bridge.
286#[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/// Notification of a channel's state change.
295#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
296pub struct ChannelStateChange {
297    #[serde(rename = "channel")]
298    pub channel: Channel,
299}
300
301/// Talking is no longer detected on the channel.
302#[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/// Talking was detected on the channel.
311#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
312pub struct ChannelTalkingStarted {
313    #[serde(rename = "channel")]
314    pub channel: Channel,
315}
316
317/// Tone was detected on the channel.
318#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
319pub struct ChannelToneDetected {
320    #[serde(rename = "channel")]
321    pub channel: Channel,
322}
323
324/// A channel initiated a media unhold.
325#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
326pub struct ChannelUnhold {
327    #[serde(rename = "channel")]
328    pub channel: Channel,
329}
330
331/// User-generated event with additional user-defined fields in the object.
332#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
333pub struct ChannelUserEvent {
334    /// The name of the user event.
335    #[serde(rename = "eventname")]
336    pub event_name: String,
337
338    ///  A channel that is signaled with the user event.
339    #[serde(rename = "channel")]
340    pub channel: Option<Channel>,
341    /// A bridge that is signaled with the user event.
342    #[serde(rename = "bridge")]
343    pub bridge: Option<Bridge>,
344    /// A endpoint that is signaled with the user event.
345    #[serde(rename = "endpoint")]
346    pub endpoint: Option<Endpoint>,
347    /// Custom Userevent data
348    #[serde(rename = "userevent")]
349    pub user_event: Option<serde_json::Value>,
350}
351
352/// Channel variable changed.
353#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
354pub struct ChannelVarSet {
355    /// The variable that changed.
356    #[serde(rename = "variable")]
357    pub variable: String,
358    /// The new value of the variable.
359    #[serde(rename = "value")]
360    pub value: String,
361    /// The channel on which the variable was set.
362    /// If missing, the variable is a global variable.
363    #[serde(rename = "channel")]
364    pub channel: Option<Channel>,
365}
366
367/// Detailed information about a contact on an endpoint.
368#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
369pub struct ContactInfo {
370    /// The location of the contact.
371    #[serde(rename = "uri")]
372    pub uri: String,
373    /// The current status of the contact.
374    #[serde(rename = "contact_status")]
375    pub contact_status: String,
376    /// The Address of Record this contact belongs to.
377    #[serde(rename = "aor")]
378    pub aor: String,
379    /// Current round trip time, in microseconds, for the contact.
380    // todo: change this to duration?
381    #[serde(rename = "roundtrip_usec")]
382    pub roundtrip_usec: Option<String>,
383}
384
385/// The state of a contact on an endpoint has changed.
386#[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/// Notification that a device state has changed.
395#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
396pub struct DeviceStateChanged {
397    /// Device state object
398    #[serde(rename = "device_state")]
399    pub device_state: DeviceState,
400}
401
402/// Dialing state has changed.
403#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
404pub struct Dial {
405    /// The calling channel.
406    #[serde(rename = "caller")]
407    pub caller: Option<Channel>,
408
409    /// The dialed channel.
410    #[serde(rename = "peer")]
411    pub peer: Option<Channel>,
412    /// Forwarding target requested by the original dialed channel.
413    #[serde(rename = "forward")]
414    pub forward: Option<String>,
415    #[serde(rename = "forwarded")]
416    pub forwarded: Option<Channel>,
417    /// The dial string for calling the peer channel.
418    #[serde(rename = "dialstring")]
419    pub dialstring: Option<String>,
420    /// Current status of the dialing attempt to the peer.
421    #[serde(rename = "dialstatus")]
422    pub dialstatus: String,
423}
424
425/// Endpoint state changed.
426#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
427pub struct EndpointStateChange {
428    #[serde(rename = "endpoint")]
429    pub endpoint: Endpoint,
430}
431
432/// Error event sent when required params are missing.
433#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
434pub struct MissingParams {
435    /// A list of the missing parameters
436    #[serde(rename = "params")]
437    pub params: Vec<String>,
438}
439
440/// Detailed information about a remote peer that communicates with Asterisk.
441#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
442pub struct Peer {
443    /// The current state of the peer. Note that the values of the status are dependent on the underlying peer technology.
444    #[serde(rename = "peer_status")]
445    pub peer_status: String,
446    /// An optional reason associated with the change in peer_status.
447    #[serde(rename = "cause")]
448    pub cause: Option<String>,
449    /// The IP address of the peer.
450    #[serde(rename = "address")]
451    pub address: Option<String>,
452    /// The port of the peer.
453    #[serde(rename = "port")]
454    pub port: Option<String>,
455    /// The last known time the peer was contacted.
456    #[serde(rename = "time")]
457    pub time: Option<String>,
458}
459
460/// The state of a peer associated with an endpoint has changed.
461#[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/// Event showing the continuation of a media playback operation from one media URI to the next in the list.
470#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
471pub struct PlaybackContinuing {
472    /// Playback control object
473    #[serde(rename = "playback")]
474    pub playback: Playback,
475}
476
477/// Event showing the completion of a media playback operation.
478#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
479pub struct PlaybackFinished {
480    /// Playback control object
481    #[serde(rename = "playback")]
482    pub playback: Playback,
483}
484
485/// Event showing the start of a media playback operation.
486#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
487pub struct PlaybackStarted {
488    #[serde(rename = "playback")]
489    pub playback: Playback,
490}
491
492/// Event showing failure of a recording operation.
493#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
494pub struct RecordingFailed {
495    /// Recording control object
496    #[serde(rename = "recording")]
497    pub recording: LiveRecording,
498}
499
500/// Event showing the completion of a recording operation.
501#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
502pub struct RecordingFinished {
503    #[serde(rename = "recording")]
504    pub recording: LiveRecording,
505}
506
507/// Event showing the start of a recording operation.
508#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
509pub struct RecordingStarted {
510    #[serde(rename = "recording")]
511    pub recording: LiveRecording,
512}
513
514/// Notification that a channel has left a Stasis application.
515#[derive(Clone, Default, Debug, PartialEq, Deserialize)]
516pub struct StasisEnd {
517    #[serde(rename = "channel")]
518    pub channel: Channel,
519}
520
521/// Notification that a channel has entered a Stasis application.
522#[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/// A text message was received from an endpoint.
533#[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 the Timezone conversion
663    #[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    // cargo test --package asterisk-ari-client -- --show-output test_parse_channel_state_change
678    #[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}