freeswitch_types/variables/
esl_array.rs1use std::fmt;
2
3const ARRAY_HEADER: &str = "ARRAY::";
4const ARRAY_SEPARATOR: &str = "|:";
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct EslArray(Vec<String>);
10
11impl EslArray {
12 pub fn parse(s: &str) -> Option<Self> {
14 let body = s.strip_prefix(ARRAY_HEADER)?;
15 let items = body
16 .split(ARRAY_SEPARATOR)
17 .map(String::from)
18 .collect();
19 Some(Self(items))
20 }
21
22 pub fn new(items: Vec<String>) -> Self {
24 Self(items)
25 }
26
27 pub fn push(&mut self, value: String) {
29 self.0
30 .push(value);
31 }
32
33 pub fn unshift(&mut self, value: String) {
35 self.0
36 .insert(0, value);
37 }
38
39 pub fn items(&self) -> &[String] {
41 &self.0
42 }
43
44 pub fn len(&self) -> usize {
46 self.0
47 .len()
48 }
49
50 pub fn is_empty(&self) -> bool {
52 self.0
53 .is_empty()
54 }
55}
56
57impl<'a> IntoIterator for &'a EslArray {
58 type Item = &'a String;
59 type IntoIter = std::slice::Iter<'a, String>;
60
61 fn into_iter(self) -> Self::IntoIter {
62 self.0
63 .iter()
64 }
65}
66
67impl IntoIterator for EslArray {
68 type Item = String;
69 type IntoIter = std::vec::IntoIter<String>;
70
71 fn into_iter(self) -> Self::IntoIter {
72 self.0
73 .into_iter()
74 }
75}
76
77impl fmt::Display for EslArray {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 f.write_str(ARRAY_HEADER)?;
80 for (i, item) in self
81 .0
82 .iter()
83 .enumerate()
84 {
85 if i > 0 {
86 f.write_str(ARRAY_SEPARATOR)?;
87 }
88 f.write_str(item)?;
89 }
90 Ok(())
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn parse_single_item() {
100 let arr = EslArray::parse("ARRAY::hello").unwrap();
101 assert_eq!(arr.items(), &["hello"]);
102 assert_eq!(arr.len(), 1);
103 }
104
105 #[test]
106 fn parse_multiple_items() {
107 let arr = EslArray::parse("ARRAY::one|:two|:three").unwrap();
108 assert_eq!(arr.items(), &["one", "two", "three"]);
109 assert_eq!(arr.len(), 3);
110 }
111
112 #[test]
113 fn parse_non_array_returns_none() {
114 assert!(EslArray::parse("not an array").is_none());
115 assert!(EslArray::parse("").is_none());
116 assert!(EslArray::parse("ARRAY:").is_none());
117 }
118
119 #[test]
120 fn display_round_trip() {
121 let input = "ARRAY::one|:two|:three";
122 let arr = EslArray::parse(input).unwrap();
123 assert_eq!(arr.to_string(), input);
124 }
125
126 #[test]
127 fn display_single_item() {
128 let arr = EslArray::parse("ARRAY::only").unwrap();
129 assert_eq!(arr.to_string(), "ARRAY::only");
130 }
131
132 #[test]
133 fn empty_items_in_array() {
134 let arr = EslArray::parse("ARRAY::|:|:stuff").unwrap();
135 assert_eq!(arr.items(), &["", "", "stuff"]);
136 }
137
138 #[test]
139 fn test_new() {
140 let arr = EslArray::new(vec!["a".into(), "b".into(), "c".into()]);
141 assert_eq!(arr.items(), &["a", "b", "c"]);
142 assert_eq!(arr.len(), 3);
143 }
144
145 #[test]
146 fn test_push() {
147 let mut arr = EslArray::new(vec!["first".into()]);
148 arr.push("second".into());
149 arr.push("third".into());
150 assert_eq!(arr.items(), &["first", "second", "third"]);
151 assert_eq!(arr.to_string(), "ARRAY::first|:second|:third");
152 }
153
154 #[test]
155 fn test_unshift() {
156 let mut arr = EslArray::new(vec!["last".into()]);
157 arr.unshift("middle".into());
158 arr.unshift("first".into());
159 assert_eq!(arr.items(), &["first", "middle", "last"]);
160 assert_eq!(arr.to_string(), "ARRAY::first|:middle|:last");
161 }
162
163 #[test]
164 fn parse_sip_uris_with_colons() {
165 let input = "ARRAY::sip:alice@atlanta.example.com|:sip:bob@biloxi.example.com";
166 let arr = EslArray::parse(input).unwrap();
167 assert_eq!(
168 arr.items(),
169 &[
170 "sip:alice@atlanta.example.com",
171 "sip:bob@biloxi.example.com"
172 ]
173 );
174 assert_eq!(arr.to_string(), input);
175 }
176
177 #[test]
178 fn parse_sip_uris_with_angle_brackets_and_params() {
179 let input = "ARRAY::<sip:+15551234567@gw.example.com;user=phone>|:<tel:+15559876543>";
180 let arr = EslArray::parse(input).unwrap();
181 assert_eq!(arr.len(), 2);
182 assert_eq!(
183 arr.items()[0],
184 "<sip:+15551234567@gw.example.com;user=phone>"
185 );
186 assert_eq!(arr.items()[1], "<tel:+15559876543>");
187 assert_eq!(arr.to_string(), input);
188 }
189}