1#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct ParseEventHeaderError(pub String);
6
7impl std::fmt::Display for ParseEventHeaderError {
8 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9 write!(f, "unknown event header: {}", self.0)
10 }
11}
12
13impl std::error::Error for ParseEventHeaderError {}
14
15sip_header::define_header_enum! {
16 error_type: ParseEventHeaderError,
17 pub enum EventHeader {
23 EventName => "Event-Name",
24 EventSubclass => "Event-Subclass",
25 UniqueId => "Unique-ID",
26 CallerUniqueId => "Caller-Unique-ID",
27 OtherLegUniqueId => "Other-Leg-Unique-ID",
28 ChannelCallUuid => "Channel-Call-UUID",
29 JobUuid => "Job-UUID",
30 ChannelName => "Channel-Name",
31 ChannelState => "Channel-State",
32 ChannelStateNumber => "Channel-State-Number",
33 ChannelCallState => "Channel-Call-State",
34 AnswerState => "Answer-State",
35 CallDirection => "Call-Direction",
36 HangupCause => "Hangup-Cause",
37 CallerCallerIdName => "Caller-Caller-ID-Name",
38 CallerCallerIdNumber => "Caller-Caller-ID-Number",
39 CallerOrigCallerIdName => "Caller-Orig-Caller-ID-Name",
40 CallerOrigCallerIdNumber => "Caller-Orig-Caller-ID-Number",
41 CallerCalleeIdName => "Caller-Callee-ID-Name",
42 CallerCalleeIdNumber => "Caller-Callee-ID-Number",
43 CallerDestinationNumber => "Caller-Destination-Number",
44 CallerContext => "Caller-Context",
45 CallerDirection => "Caller-Direction",
46 CallerNetworkAddr => "Caller-Network-Addr",
47 CoreUuid => "Core-UUID",
48 DtmfDigit => "DTMF-Digit",
49 Priority => "priority",
50 LogLevel => "Log-Level",
51 PlData => "pl_data",
53 SipEvent => "event",
55 SipContentType => "sip_content_type",
57 GatewayName => "gateway_name",
59
60 ChannelReadCodecName => "Channel-Read-Codec-Name",
63 ChannelReadCodecRate => "Channel-Read-Codec-Rate",
64 ChannelReadCodecBitRate => "Channel-Read-Codec-Bit-Rate",
65 ChannelReportedReadCodecRate => "Channel-Reported-Read-Codec-Rate",
67 ChannelWriteCodecName => "Channel-Write-Codec-Name",
69 ChannelWriteCodecRate => "Channel-Write-Codec-Rate",
70 ChannelWriteCodecBitRate => "Channel-Write-Codec-Bit-Rate",
71 ChannelReportedWriteCodecRate => "Channel-Reported-Write-Codec-Rate",
73 ChannelVideoReadCodecName => "Channel-Video-Read-Codec-Name",
75 ChannelVideoReadCodecRate => "Channel-Video-Read-Codec-Rate",
76 ChannelVideoWriteCodecName => "Channel-Video-Write-Codec-Name",
77 ChannelVideoWriteCodecRate => "Channel-Video-Write-Codec-Rate",
78 SessionCount => "Session-Count",
80 FreeswitchHostname => "FreeSWITCH-Hostname",
81 FreeswitchSwitchname => "FreeSWITCH-Switchname",
82 FreeswitchIpv4 => "FreeSWITCH-IPv4",
83 FreeswitchIpv6 => "FreeSWITCH-IPv6",
84 FreeswitchVersion => "FreeSWITCH-Version",
85 FreeswitchDomain => "FreeSWITCH-Domain",
86 FreeswitchUser => "FreeSWITCH-User",
87
88 Application => "Application",
90 ApplicationData => "Application-Data",
91 ApplicationResponse => "Application-Response",
92 ApplicationUuid => "Application-UUID",
93
94 EventDateLocal => "Event-Date-Local",
96 EventDateGmt => "Event-Date-GMT",
97 EventDateTimestamp => "Event-Date-Timestamp",
98 EventCallingFile => "Event-Calling-File",
99 EventCallingFunction => "Event-Calling-Function",
100 EventCallingLineNumber => "Event-Calling-Line-Number",
101 EventSequence => "Event-Sequence",
102
103 ChannelPresenceId => "Channel-Presence-ID",
105 ChannelPresenceData => "Channel-Presence-Data",
106 PresenceDataCols => "Presence-Data-Cols",
107 PresenceCallDirection => "Presence-Call-Direction",
108 ChannelHitDialplan => "Channel-HIT-Dialplan",
109 SessionExternalId => "Session-External-ID",
110 OtherType => "Other-Type",
112
113 ChannelCallStateNumber => "Channel-Call-State-Number",
115 OriginalChannelCallState => "Original-Channel-Call-State",
116
117 DtmfDuration => "DTMF-Duration",
119 DtmfSource => "DTMF-Source",
120
121 CallerLogicalDirection => "Caller-Logical-Direction",
123 CallerUsername => "Caller-Username",
124 CallerDialplan => "Caller-Dialplan",
125 CallerAni => "Caller-ANI",
126 CallerAniii => "Caller-ANI-II",
127 CallerSource => "Caller-Source",
128 CallerTransferSource => "Caller-Transfer-Source",
129 CallerRdnis => "Caller-RDNIS",
130 CallerChannelName => "Caller-Channel-Name",
131 CallerProfileIndex => "Caller-Profile-Index",
132 CallerScreenBit => "Caller-Screen-Bit",
133 CallerPrivacyHideName => "Caller-Privacy-Hide-Name",
134 CallerPrivacyHideNumber => "Caller-Privacy-Hide-Number",
135
136 OtherLegDirection => "Other-Leg-Direction",
138 OtherLegLogicalDirection => "Other-Leg-Logical-Direction",
139 OtherLegUsername => "Other-Leg-Username",
140 OtherLegDialplan => "Other-Leg-Dialplan",
141 OtherLegCallerIdName => "Other-Leg-Caller-ID-Name",
142 OtherLegCallerIdNumber => "Other-Leg-Caller-ID-Number",
143 OtherLegOrigCallerIdName => "Other-Leg-Orig-Caller-ID-Name",
144 OtherLegOrigCallerIdNumber => "Other-Leg-Orig-Caller-ID-Number",
145 OtherLegCalleeIdName => "Other-Leg-Callee-ID-Name",
146 OtherLegCalleeIdNumber => "Other-Leg-Callee-ID-Number",
147 OtherLegNetworkAddr => "Other-Leg-Network-Addr",
148 OtherLegAni => "Other-Leg-ANI",
149 OtherLegAniii => "Other-Leg-ANI-II",
150 OtherLegDestinationNumber => "Other-Leg-Destination-Number",
151 OtherLegSource => "Other-Leg-Source",
152 OtherLegTransferSource => "Other-Leg-Transfer-Source",
153 OtherLegContext => "Other-Leg-Context",
154 OtherLegRdnis => "Other-Leg-RDNIS",
155 OtherLegChannelName => "Other-Leg-Channel-Name",
156 OtherLegProfileIndex => "Other-Leg-Profile-Index",
157 OtherLegScreenBit => "Other-Leg-Screen-Bit",
158 OtherLegPrivacyHideName => "Other-Leg-Privacy-Hide-Name",
159 OtherLegPrivacyHideNumber => "Other-Leg-Privacy-Hide-Number",
160
161 UpTime => "Up-Time",
164 UptimeMsec => "Uptime-msec",
166 MaxSessions => "Max-Sessions",
167 SessionPeakMax => "Session-Peak-Max",
168 SessionPeakFiveMin => "Session-Peak-FiveMin",
169 SessionPerSec => "Session-Per-Sec",
170 SessionPerSecFiveMin => "Session-Per-Sec-FiveMin",
171 SessionPerSecMax => "Session-Per-Sec-Max",
172 SessionPerSecLast => "Session-Per-Sec-Last",
173 SessionSinceStartup => "Session-Since-Startup",
174 IdleCpu => "Idle-CPU",
175 HeartbeatInterval => "Heartbeat-Interval",
176 EventInfo => "Event-Info",
177
178 LogData => "Log-Data",
180 LogFile => "Log-File",
181 LogFunction => "Log-Function",
182 LogLine => "Log-Line",
183 UserData => "User-Data",
184
185 ApplicationUuidName => "Application-UUID-Name",
187
188 Gateway => "Gateway",
190 State => "State",
191 PingStatus => "Ping-Status",
192 Phrase => "Phrase",
193 ProfileName => "profile-name",
194 Status => "Status",
196 }
197}
198
199pub fn normalize_header_key(raw: &str) -> String {
216 if let Ok(eh) = raw.parse::<EventHeader>() {
217 return eh
218 .as_str()
219 .to_string();
220 }
221 if raw.contains('_') {
222 raw.to_string()
223 } else {
224 title_case_dashes(raw)
225 }
226}
227
228fn title_case_dashes(s: &str) -> String {
229 let mut result = String::with_capacity(s.len());
230 let mut capitalize_next = true;
231 for c in s.chars() {
232 if c == '-' {
233 result.push('-');
234 capitalize_next = true;
235 } else if capitalize_next {
236 result.push(c.to_ascii_uppercase());
237 capitalize_next = false;
238 } else {
239 result.push(c.to_ascii_lowercase());
240 }
241 }
242 result
243}
244
245#[cfg(test)]
246mod tests {
247 use super::*;
248
249 #[test]
250 fn display_round_trip() {
251 assert_eq!(EventHeader::UniqueId.to_string(), "Unique-ID");
252 assert_eq!(
253 EventHeader::ChannelCallState.to_string(),
254 "Channel-Call-State"
255 );
256 assert_eq!(
257 EventHeader::CallerCallerIdName.to_string(),
258 "Caller-Caller-ID-Name"
259 );
260 assert_eq!(EventHeader::Priority.to_string(), "priority");
261 }
262
263 #[test]
264 fn as_ref_str() {
265 let h: &str = EventHeader::UniqueId.as_ref();
266 assert_eq!(h, "Unique-ID");
267 }
268
269 #[test]
270 fn from_str_case_insensitive() {
271 assert_eq!(
272 "unique-id".parse::<EventHeader>(),
273 Ok(EventHeader::UniqueId)
274 );
275 assert_eq!(
276 "UNIQUE-ID".parse::<EventHeader>(),
277 Ok(EventHeader::UniqueId)
278 );
279 assert_eq!(
280 "Unique-ID".parse::<EventHeader>(),
281 Ok(EventHeader::UniqueId)
282 );
283 assert_eq!(
284 "channel-call-state".parse::<EventHeader>(),
285 Ok(EventHeader::ChannelCallState)
286 );
287 }
288
289 #[test]
290 fn from_str_unknown() {
291 let err = "X-Custom-Not-In-Enum".parse::<EventHeader>();
292 assert!(err.is_err());
293 assert_eq!(
294 err.unwrap_err()
295 .to_string(),
296 "unknown event header: X-Custom-Not-In-Enum"
297 );
298 }
299
300 #[test]
308 fn normalize_known_enum_variants_return_canonical_form() {
309 assert_eq!(normalize_header_key("unique-id"), "Unique-ID");
311 assert_eq!(normalize_header_key("UNIQUE-ID"), "Unique-ID");
312 assert_eq!(normalize_header_key("Unique-ID"), "Unique-ID");
313 assert_eq!(normalize_header_key("dtmf-digit"), "DTMF-Digit");
314 assert_eq!(normalize_header_key("DTMF-DIGIT"), "DTMF-Digit");
315 assert_eq!(
316 normalize_header_key("channel-call-uuid"),
317 "Channel-Call-UUID"
318 );
319 assert_eq!(normalize_header_key("event-name"), "Event-Name");
320 }
321
322 #[test]
323 fn normalize_known_underscore_variants_return_canonical_form() {
324 assert_eq!(normalize_header_key("priority"), "priority");
326 assert_eq!(normalize_header_key("PRIORITY"), "priority");
327 assert_eq!(normalize_header_key("pl_data"), "pl_data");
328 assert_eq!(normalize_header_key("PL_DATA"), "pl_data");
329 assert_eq!(normalize_header_key("sip_content_type"), "sip_content_type");
330 assert_eq!(normalize_header_key("gateway_name"), "gateway_name");
331 assert_eq!(normalize_header_key("event"), "event");
332 assert_eq!(normalize_header_key("EVENT"), "event");
333 }
334
335 #[test]
336 fn normalize_codec_headers_from_switch_core_codec() {
337 assert_eq!(
340 normalize_header_key("channel-read-codec-bit-rate"),
341 "Channel-Read-Codec-Bit-Rate"
342 );
343 assert_eq!(
344 normalize_header_key("Channel-Read-Codec-Bit-Rate"),
345 "Channel-Read-Codec-Bit-Rate"
346 );
347 assert_eq!(
349 normalize_header_key("Channel-Write-codec-bit-rate"),
350 "Channel-Write-Codec-Bit-Rate"
351 );
352 assert_eq!(
353 normalize_header_key("channel-video-read-codec-name"),
354 "Channel-Video-Read-Codec-Name"
355 );
356 }
357
358 #[test]
359 fn normalize_unknown_underscore_keys_passthrough() {
360 assert_eq!(
362 normalize_header_key("variable_sip_call_id"),
363 "variable_sip_call_id"
364 );
365 assert_eq!(
366 normalize_header_key("variable_sip_h_X-My-CUSTOM-Header"),
367 "variable_sip_h_X-My-CUSTOM-Header"
368 );
369 assert_eq!(
370 normalize_header_key("variable_sip_h_Diversion"),
371 "variable_sip_h_Diversion"
372 );
373 }
374
375 #[test]
376 fn normalize_unknown_dash_keys_title_case() {
377 assert_eq!(normalize_header_key("content-type"), "Content-Type");
379 assert_eq!(normalize_header_key("Content-Type"), "Content-Type");
380 assert_eq!(normalize_header_key("CONTENT-TYPE"), "Content-Type");
381 assert_eq!(normalize_header_key("x-custom-header"), "X-Custom-Header");
382 assert_eq!(
383 normalize_header_key("Content-Disposition"),
384 "Content-Disposition"
385 );
386 assert_eq!(normalize_header_key("reply-text"), "Reply-Text");
387 }
388
389 #[test]
390 fn normalize_idempotent_for_all_enum_variants() {
391 let variants = [
393 EventHeader::EventName,
394 EventHeader::UniqueId,
395 EventHeader::ChannelCallUuid,
396 EventHeader::DtmfDigit,
397 EventHeader::Priority,
398 EventHeader::PlData,
399 EventHeader::SipEvent,
400 EventHeader::GatewayName,
401 EventHeader::SipContentType,
402 EventHeader::ChannelReadCodecBitRate,
403 EventHeader::ChannelVideoWriteCodecRate,
404 EventHeader::LogLevel,
405 ];
406 for v in variants {
407 let canonical = v.as_str();
408 assert_eq!(
409 normalize_header_key(canonical),
410 canonical,
411 "normalization not idempotent for {canonical}"
412 );
413 }
414 }
415
416 #[test]
417 fn parse_missing_event_default_headers() {
418 assert!("Event-Date-Local"
420 .parse::<EventHeader>()
421 .is_ok());
422 assert!("Event-Date-GMT"
423 .parse::<EventHeader>()
424 .is_ok());
425 assert!("Event-Date-Timestamp"
426 .parse::<EventHeader>()
427 .is_ok());
428 assert!("Event-Calling-File"
429 .parse::<EventHeader>()
430 .is_ok());
431 assert!("Event-Calling-Function"
432 .parse::<EventHeader>()
433 .is_ok());
434 assert!("Event-Calling-Line-Number"
435 .parse::<EventHeader>()
436 .is_ok());
437 assert!("Event-Sequence"
438 .parse::<EventHeader>()
439 .is_ok());
440 }
441
442 #[test]
443 fn parse_missing_channel_basic_data_headers() {
444 assert!("Channel-Presence-ID"
446 .parse::<EventHeader>()
447 .is_ok());
448 assert!("Channel-Presence-Data"
449 .parse::<EventHeader>()
450 .is_ok());
451 assert!("Presence-Data-Cols"
452 .parse::<EventHeader>()
453 .is_ok());
454 assert!("Presence-Call-Direction"
455 .parse::<EventHeader>()
456 .is_ok());
457 assert!("Channel-HIT-Dialplan"
458 .parse::<EventHeader>()
459 .is_ok());
460 assert!("Session-External-ID"
461 .parse::<EventHeader>()
462 .is_ok());
463 assert!("Other-Type"
464 .parse::<EventHeader>()
465 .is_ok());
466 }
467
468 #[test]
469 fn parse_missing_callstate_and_dtmf_headers() {
470 assert!("Channel-Call-State-Number"
472 .parse::<EventHeader>()
473 .is_ok());
474 assert!("Original-Channel-Call-State"
475 .parse::<EventHeader>()
476 .is_ok());
477 assert!("DTMF-Duration"
479 .parse::<EventHeader>()
480 .is_ok());
481 assert!("DTMF-Source"
482 .parse::<EventHeader>()
483 .is_ok());
484 }
485
486 #[test]
487 fn parse_missing_caller_profile_headers() {
488 assert!("Caller-Logical-Direction"
490 .parse::<EventHeader>()
491 .is_ok());
492 assert!("Caller-Username"
493 .parse::<EventHeader>()
494 .is_ok());
495 assert!("Caller-Dialplan"
496 .parse::<EventHeader>()
497 .is_ok());
498 assert!("Caller-ANI"
499 .parse::<EventHeader>()
500 .is_ok());
501 assert!("Caller-ANI-II"
502 .parse::<EventHeader>()
503 .is_ok());
504 assert!("Caller-Source"
505 .parse::<EventHeader>()
506 .is_ok());
507 assert!("Caller-Transfer-Source"
508 .parse::<EventHeader>()
509 .is_ok());
510 assert!("Caller-RDNIS"
511 .parse::<EventHeader>()
512 .is_ok());
513 assert!("Caller-Channel-Name"
514 .parse::<EventHeader>()
515 .is_ok());
516 assert!("Caller-Profile-Index"
517 .parse::<EventHeader>()
518 .is_ok());
519 assert!("Caller-Screen-Bit"
520 .parse::<EventHeader>()
521 .is_ok());
522 assert!("Caller-Privacy-Hide-Name"
523 .parse::<EventHeader>()
524 .is_ok());
525 assert!("Caller-Privacy-Hide-Number"
526 .parse::<EventHeader>()
527 .is_ok());
528 }
529
530 #[test]
531 fn parse_heartbeat_headers() {
532 assert!("Up-Time"
533 .parse::<EventHeader>()
534 .is_ok());
535 assert!("Uptime-msec"
536 .parse::<EventHeader>()
537 .is_ok());
538 assert!("Max-Sessions"
539 .parse::<EventHeader>()
540 .is_ok());
541 assert!("Session-Peak-Max"
542 .parse::<EventHeader>()
543 .is_ok());
544 assert!("Session-Peak-FiveMin"
545 .parse::<EventHeader>()
546 .is_ok());
547 assert!("Session-Per-Sec"
548 .parse::<EventHeader>()
549 .is_ok());
550 assert!("Session-Per-Sec-FiveMin"
551 .parse::<EventHeader>()
552 .is_ok());
553 assert!("Session-Per-Sec-Max"
554 .parse::<EventHeader>()
555 .is_ok());
556 assert!("Session-Per-Sec-Last"
557 .parse::<EventHeader>()
558 .is_ok());
559 assert!("Session-Since-Startup"
560 .parse::<EventHeader>()
561 .is_ok());
562 assert!("Idle-CPU"
563 .parse::<EventHeader>()
564 .is_ok());
565 assert!("Heartbeat-Interval"
566 .parse::<EventHeader>()
567 .is_ok());
568 assert!("Event-Info"
569 .parse::<EventHeader>()
570 .is_ok());
571 }
572
573 #[test]
574 fn parse_log_headers() {
575 assert!("Log-Data"
576 .parse::<EventHeader>()
577 .is_ok());
578 assert!("Log-File"
579 .parse::<EventHeader>()
580 .is_ok());
581 assert!("Log-Function"
582 .parse::<EventHeader>()
583 .is_ok());
584 assert!("Log-Line"
585 .parse::<EventHeader>()
586 .is_ok());
587 assert!("User-Data"
588 .parse::<EventHeader>()
589 .is_ok());
590 }
591
592 #[test]
593 fn parse_application_uuid_name() {
594 assert!("Application-UUID-Name"
595 .parse::<EventHeader>()
596 .is_ok());
597 }
598
599 #[test]
600 fn parse_sofia_event_headers() {
601 assert_eq!("Gateway".parse::<EventHeader>(), Ok(EventHeader::Gateway));
602 assert_eq!("State".parse::<EventHeader>(), Ok(EventHeader::State));
603 assert_eq!(
604 "Ping-Status".parse::<EventHeader>(),
605 Ok(EventHeader::PingStatus)
606 );
607 assert_eq!("Phrase".parse::<EventHeader>(), Ok(EventHeader::Phrase));
608 assert_eq!(
609 "profile-name".parse::<EventHeader>(),
610 Ok(EventHeader::ProfileName)
611 );
612 }
613
614 #[test]
615 fn parse_missing_other_leg_headers() {
616 assert!("Other-Leg-Direction"
618 .parse::<EventHeader>()
619 .is_ok());
620 assert!("Other-Leg-Logical-Direction"
621 .parse::<EventHeader>()
622 .is_ok());
623 assert!("Other-Leg-Username"
624 .parse::<EventHeader>()
625 .is_ok());
626 assert!("Other-Leg-Dialplan"
627 .parse::<EventHeader>()
628 .is_ok());
629 assert!("Other-Leg-Caller-ID-Name"
630 .parse::<EventHeader>()
631 .is_ok());
632 assert!("Other-Leg-Caller-ID-Number"
633 .parse::<EventHeader>()
634 .is_ok());
635 assert!("Other-Leg-Orig-Caller-ID-Name"
636 .parse::<EventHeader>()
637 .is_ok());
638 assert!("Other-Leg-Orig-Caller-ID-Number"
639 .parse::<EventHeader>()
640 .is_ok());
641 assert!("Other-Leg-Callee-ID-Name"
642 .parse::<EventHeader>()
643 .is_ok());
644 assert!("Other-Leg-Callee-ID-Number"
645 .parse::<EventHeader>()
646 .is_ok());
647 assert!("Other-Leg-Network-Addr"
648 .parse::<EventHeader>()
649 .is_ok());
650 assert!("Other-Leg-ANI"
651 .parse::<EventHeader>()
652 .is_ok());
653 assert!("Other-Leg-ANI-II"
654 .parse::<EventHeader>()
655 .is_ok());
656 assert!("Other-Leg-Destination-Number"
657 .parse::<EventHeader>()
658 .is_ok());
659 assert!("Other-Leg-Source"
660 .parse::<EventHeader>()
661 .is_ok());
662 assert!("Other-Leg-Transfer-Source"
663 .parse::<EventHeader>()
664 .is_ok());
665 assert!("Other-Leg-Context"
666 .parse::<EventHeader>()
667 .is_ok());
668 assert!("Other-Leg-RDNIS"
669 .parse::<EventHeader>()
670 .is_ok());
671 assert!("Other-Leg-Channel-Name"
672 .parse::<EventHeader>()
673 .is_ok());
674 assert!("Other-Leg-Profile-Index"
675 .parse::<EventHeader>()
676 .is_ok());
677 assert!("Other-Leg-Screen-Bit"
678 .parse::<EventHeader>()
679 .is_ok());
680 assert!("Other-Leg-Privacy-Hide-Name"
681 .parse::<EventHeader>()
682 .is_ok());
683 assert!("Other-Leg-Privacy-Hide-Number"
684 .parse::<EventHeader>()
685 .is_ok());
686 }
687
688 #[test]
689 fn from_str_round_trip_all_variants() {
690 let variants = [
691 EventHeader::EventName,
692 EventHeader::EventSubclass,
693 EventHeader::UniqueId,
694 EventHeader::CallerUniqueId,
695 EventHeader::OtherLegUniqueId,
696 EventHeader::ChannelCallUuid,
697 EventHeader::JobUuid,
698 EventHeader::ChannelName,
699 EventHeader::ChannelState,
700 EventHeader::ChannelStateNumber,
701 EventHeader::ChannelCallState,
702 EventHeader::AnswerState,
703 EventHeader::CallDirection,
704 EventHeader::HangupCause,
705 EventHeader::CallerCallerIdName,
706 EventHeader::CallerCallerIdNumber,
707 EventHeader::CallerOrigCallerIdName,
708 EventHeader::CallerOrigCallerIdNumber,
709 EventHeader::CallerCalleeIdName,
710 EventHeader::CallerCalleeIdNumber,
711 EventHeader::CallerDestinationNumber,
712 EventHeader::CallerContext,
713 EventHeader::CallerDirection,
714 EventHeader::CallerNetworkAddr,
715 EventHeader::CoreUuid,
716 EventHeader::DtmfDigit,
717 EventHeader::Priority,
718 EventHeader::LogLevel,
719 EventHeader::PlData,
720 EventHeader::SipEvent,
721 EventHeader::SipContentType,
722 EventHeader::GatewayName,
723 EventHeader::ChannelReadCodecName,
724 EventHeader::ChannelReadCodecRate,
725 EventHeader::ChannelReadCodecBitRate,
726 EventHeader::ChannelReportedReadCodecRate,
727 EventHeader::ChannelWriteCodecName,
728 EventHeader::ChannelWriteCodecRate,
729 EventHeader::ChannelWriteCodecBitRate,
730 EventHeader::ChannelReportedWriteCodecRate,
731 EventHeader::ChannelVideoReadCodecName,
732 EventHeader::ChannelVideoReadCodecRate,
733 EventHeader::ChannelVideoWriteCodecName,
734 EventHeader::ChannelVideoWriteCodecRate,
735 EventHeader::Application,
736 EventHeader::ApplicationData,
737 EventHeader::ApplicationResponse,
738 EventHeader::ApplicationUuid,
739 EventHeader::EventDateLocal,
740 EventHeader::EventDateGmt,
741 EventHeader::EventDateTimestamp,
742 EventHeader::EventCallingFile,
743 EventHeader::EventCallingFunction,
744 EventHeader::EventCallingLineNumber,
745 EventHeader::EventSequence,
746 EventHeader::ChannelPresenceId,
747 EventHeader::ChannelPresenceData,
748 EventHeader::PresenceDataCols,
749 EventHeader::PresenceCallDirection,
750 EventHeader::ChannelHitDialplan,
751 EventHeader::SessionExternalId,
752 EventHeader::OtherType,
753 EventHeader::ChannelCallStateNumber,
754 EventHeader::OriginalChannelCallState,
755 EventHeader::DtmfDuration,
756 EventHeader::DtmfSource,
757 EventHeader::CallerLogicalDirection,
758 EventHeader::CallerUsername,
759 EventHeader::CallerDialplan,
760 EventHeader::CallerAni,
761 EventHeader::CallerAniii,
762 EventHeader::CallerSource,
763 EventHeader::CallerTransferSource,
764 EventHeader::CallerRdnis,
765 EventHeader::CallerChannelName,
766 EventHeader::CallerProfileIndex,
767 EventHeader::CallerScreenBit,
768 EventHeader::CallerPrivacyHideName,
769 EventHeader::CallerPrivacyHideNumber,
770 EventHeader::OtherLegDirection,
771 EventHeader::OtherLegLogicalDirection,
772 EventHeader::OtherLegUsername,
773 EventHeader::OtherLegDialplan,
774 EventHeader::OtherLegCallerIdName,
775 EventHeader::OtherLegCallerIdNumber,
776 EventHeader::OtherLegOrigCallerIdName,
777 EventHeader::OtherLegOrigCallerIdNumber,
778 EventHeader::OtherLegCalleeIdName,
779 EventHeader::OtherLegCalleeIdNumber,
780 EventHeader::OtherLegNetworkAddr,
781 EventHeader::OtherLegAni,
782 EventHeader::OtherLegAniii,
783 EventHeader::OtherLegDestinationNumber,
784 EventHeader::OtherLegSource,
785 EventHeader::OtherLegTransferSource,
786 EventHeader::OtherLegContext,
787 EventHeader::OtherLegRdnis,
788 EventHeader::OtherLegChannelName,
789 EventHeader::OtherLegProfileIndex,
790 EventHeader::OtherLegScreenBit,
791 EventHeader::OtherLegPrivacyHideName,
792 EventHeader::OtherLegPrivacyHideNumber,
793 EventHeader::UpTime,
794 EventHeader::UptimeMsec,
795 EventHeader::MaxSessions,
796 EventHeader::SessionPeakMax,
797 EventHeader::SessionPeakFiveMin,
798 EventHeader::SessionPerSec,
799 EventHeader::SessionPerSecFiveMin,
800 EventHeader::SessionPerSecMax,
801 EventHeader::SessionPerSecLast,
802 EventHeader::SessionSinceStartup,
803 EventHeader::IdleCpu,
804 EventHeader::HeartbeatInterval,
805 EventHeader::EventInfo,
806 EventHeader::LogData,
807 EventHeader::LogFile,
808 EventHeader::LogFunction,
809 EventHeader::LogLine,
810 EventHeader::UserData,
811 EventHeader::ApplicationUuidName,
812 EventHeader::Gateway,
813 EventHeader::State,
814 EventHeader::PingStatus,
815 EventHeader::Phrase,
816 EventHeader::ProfileName,
817 EventHeader::Status,
818 ];
819 for v in variants {
820 let wire = v.to_string();
821 let parsed: EventHeader = wire
822 .parse()
823 .unwrap();
824 assert_eq!(parsed, v, "round-trip failed for {wire}");
825 }
826 }
827}