freeswitch_types/variables/
mod.rs1mod conference;
5mod core;
6mod core_media;
7mod esl_array;
8#[cfg(feature = "esl")]
9mod esl_headers;
10mod loopback;
11mod sip_multipart;
12mod sip_passthrough;
13mod sofia;
14
15pub use self::core::{ChannelVariable, ParseChannelVariableError};
16pub use conference::{ConferenceVariable, ParseConferenceVariableError};
17pub use core_media::{CoreMediaVariable, ParseCoreMediaVariableError, RtpStatUnit};
18pub use esl_array::{EslArray, EslArrayError, MAX_ARRAY_ITEMS};
19#[cfg(feature = "esl")]
20pub use esl_headers::EslHeaders;
21pub use loopback::{
22 LoopbackChannelName, LoopbackHangupCause, LoopbackLeg, LoopbackResignation, LoopbackVariable,
23 ParseLoopbackHangupCauseError, ParseLoopbackLegError, ParseLoopbackVariableError,
24};
25pub use sip_multipart::{MultipartBody, MultipartBodyError, MultipartItem};
26pub use sip_passthrough::{
27 InvalidHeaderName, ParseSipPassthroughError, SipHeaderPrefix, SipPassthroughHeader,
28};
29pub use sofia::{CarriedHeader, ParseSofiaVariableError, SofiaVariable};
30
31pub trait VariableName {
38 fn as_str(&self) -> &str;
40
41 fn header_name(&self) -> String {
48 format!("{}{}", crate::VARIABLE_PREFIX, self.as_str())
49 }
50}
51
52impl VariableName for ChannelVariable {
53 fn as_str(&self) -> &str {
54 ChannelVariable::as_str(self)
55 }
56}
57
58impl VariableName for SofiaVariable {
59 fn as_str(&self) -> &str {
60 SofiaVariable::as_str(self)
61 }
62}
63
64impl VariableName for CoreMediaVariable {
65 fn as_str(&self) -> &str {
66 CoreMediaVariable::as_str(self)
67 }
68}
69
70impl VariableName for LoopbackVariable {
71 fn as_str(&self) -> &str {
72 LoopbackVariable::as_str(self)
73 }
74}
75
76impl VariableName for ConferenceVariable {
77 fn as_str(&self) -> &str {
78 ConferenceVariable::as_str(self)
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use crate::{HeaderLookup, VARIABLE_PREFIX};
86 use sip_header::SipHeader;
87 use std::collections::HashMap;
88
89 #[test]
90 fn header_name_composes_the_wire_key() {
91 assert_eq!(
92 ChannelVariable::ReadCodec.header_name(),
93 "variable_read_codec"
94 );
95 assert_eq!(
96 LoopbackVariable::LoopbackLeg.header_name(),
97 "variable_loopback_leg"
98 );
99 assert!(ChannelVariable::ReadCodec
100 .header_name()
101 .starts_with(VARIABLE_PREFIX));
102 }
103
104 #[test]
107 fn header_name_covers_a_borrowed_as_str() {
108 let h = SipPassthroughHeader::invite(SipHeader::CallInfo);
109 assert_eq!(h.header_name(), "variable_sip_i_call_info");
110 }
111
112 #[test]
114 fn an_external_implementor_supplies_only_as_str() {
115 struct TenantVariable;
116
117 impl VariableName for TenantVariable {
118 fn as_str(&self) -> &str {
119 "tenant_id"
120 }
121 }
122
123 assert_eq!(TenantVariable.header_name(), "variable_tenant_id");
124 }
125
126 #[test]
127 fn header_name_is_the_key_a_header_store_holds() {
128 let mut map: HashMap<String, String> = HashMap::new();
129 map.insert(ChannelVariable::ReadCodec.header_name(), "PCMU".into());
130 assert_eq!(map.variable(ChannelVariable::ReadCodec), Some("PCMU"));
131 }
132}