freeswitch_types/
headers.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct ParseEventHeaderError(pub String);
8
9impl std::fmt::Display for ParseEventHeaderError {
10 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11 write!(f, "unknown event header: {}", self.0)
12 }
13}
14
15impl std::error::Error for ParseEventHeaderError {}
16
17define_header_enum! {
18 error_type: ParseEventHeaderError,
19 pub enum EventHeader {
25 EventName => "Event-Name",
26 EventSubclass => "Event-Subclass",
27 UniqueId => "Unique-ID",
28 CallerUniqueId => "Caller-Unique-ID",
29 OtherLegUniqueId => "Other-Leg-Unique-ID",
30 ChannelCallUuid => "Channel-Call-UUID",
31 JobUuid => "Job-UUID",
32 ChannelName => "Channel-Name",
33 ChannelState => "Channel-State",
34 ChannelStateNumber => "Channel-State-Number",
35 ChannelCallState => "Channel-Call-State",
36 AnswerState => "Answer-State",
37 CallDirection => "Call-Direction",
38 HangupCause => "Hangup-Cause",
39 CallerCallerIdName => "Caller-Caller-ID-Name",
40 CallerCallerIdNumber => "Caller-Caller-ID-Number",
41 CallerOrigCallerIdName => "Caller-Orig-Caller-ID-Name",
42 CallerOrigCallerIdNumber => "Caller-Orig-Caller-ID-Number",
43 CallerCalleeIdName => "Caller-Callee-ID-Name",
44 CallerCalleeIdNumber => "Caller-Callee-ID-Number",
45 CallerDestinationNumber => "Caller-Destination-Number",
46 CallerContext => "Caller-Context",
47 CallerDirection => "Caller-Direction",
48 CallerNetworkAddr => "Caller-Network-Addr",
49 CoreUuid => "Core-UUID",
50 DtmfDigit => "DTMF-Digit",
51 Priority => "priority",
52 LogLevel => "Log-Level",
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn display_round_trip() {
62 assert_eq!(EventHeader::UniqueId.to_string(), "Unique-ID");
63 assert_eq!(
64 EventHeader::ChannelCallState.to_string(),
65 "Channel-Call-State"
66 );
67 assert_eq!(
68 EventHeader::CallerCallerIdName.to_string(),
69 "Caller-Caller-ID-Name"
70 );
71 assert_eq!(EventHeader::Priority.to_string(), "priority");
72 }
73
74 #[test]
75 fn as_ref_str() {
76 let h: &str = EventHeader::UniqueId.as_ref();
77 assert_eq!(h, "Unique-ID");
78 }
79
80 #[test]
81 fn from_str_case_insensitive() {
82 assert_eq!(
83 "unique-id".parse::<EventHeader>(),
84 Ok(EventHeader::UniqueId)
85 );
86 assert_eq!(
87 "UNIQUE-ID".parse::<EventHeader>(),
88 Ok(EventHeader::UniqueId)
89 );
90 assert_eq!(
91 "Unique-ID".parse::<EventHeader>(),
92 Ok(EventHeader::UniqueId)
93 );
94 assert_eq!(
95 "channel-call-state".parse::<EventHeader>(),
96 Ok(EventHeader::ChannelCallState)
97 );
98 }
99
100 #[test]
101 fn from_str_unknown() {
102 let err = "X-Custom-Not-In-Enum".parse::<EventHeader>();
103 assert!(err.is_err());
104 assert_eq!(
105 err.unwrap_err()
106 .to_string(),
107 "unknown event header: X-Custom-Not-In-Enum"
108 );
109 }
110
111 #[test]
112 fn from_str_round_trip_all_variants() {
113 let variants = [
114 EventHeader::EventName,
115 EventHeader::EventSubclass,
116 EventHeader::UniqueId,
117 EventHeader::CallerUniqueId,
118 EventHeader::OtherLegUniqueId,
119 EventHeader::ChannelCallUuid,
120 EventHeader::JobUuid,
121 EventHeader::ChannelName,
122 EventHeader::ChannelState,
123 EventHeader::ChannelStateNumber,
124 EventHeader::ChannelCallState,
125 EventHeader::AnswerState,
126 EventHeader::CallDirection,
127 EventHeader::HangupCause,
128 EventHeader::CallerCallerIdName,
129 EventHeader::CallerCallerIdNumber,
130 EventHeader::CallerOrigCallerIdName,
131 EventHeader::CallerOrigCallerIdNumber,
132 EventHeader::CallerCalleeIdName,
133 EventHeader::CallerCalleeIdNumber,
134 EventHeader::CallerDestinationNumber,
135 EventHeader::CallerContext,
136 EventHeader::CallerDirection,
137 EventHeader::CallerNetworkAddr,
138 EventHeader::CoreUuid,
139 EventHeader::DtmfDigit,
140 EventHeader::Priority,
141 EventHeader::LogLevel,
142 ];
143 for v in variants {
144 let wire = v.to_string();
145 let parsed: EventHeader = wire
146 .parse()
147 .unwrap();
148 assert_eq!(parsed, v, "round-trip failed for {wire}");
149 }
150 }
151}