freeswitch_types/
lossy_values.rs1use std::fmt;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct LossyValue {
12 key: String,
13 raw_value: String,
14}
15
16impl LossyValue {
17 pub fn new(key: String, raw_value: String) -> Self {
19 Self { key, raw_value }
20 }
21
22 pub fn key(&self) -> &str {
24 &self.key
25 }
26
27 pub fn raw_value(&self) -> &str {
29 &self.raw_value
30 }
31}
32
33#[derive(Debug, Clone, Default, PartialEq, Eq)]
39#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
40#[cfg_attr(feature = "serde", serde(transparent))]
41pub struct LossyValues(Vec<LossyValue>);
42
43impl LossyValues {
44 pub fn is_empty(&self) -> bool {
46 self.0
47 .is_empty()
48 }
49
50 pub fn iter(&self) -> impl Iterator<Item = &LossyValue> {
52 self.0
53 .iter()
54 }
55
56 pub fn push(&mut self, v: LossyValue) {
58 self.0
59 .push(v);
60 }
61}
62
63impl fmt::Display for LossyValues {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 let keys: Vec<&str> = self
66 .0
67 .iter()
68 .map(|v| v.key())
69 .collect();
70 write!(f, "{}", keys.join(", "))
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn lossy_values_display_keys_only() {
80 let mut lossy = LossyValues::default();
81 lossy.push(LossyValue::new(
82 "variable_dp_match".to_string(),
83 "%E9foo".to_string(),
84 ));
85 lossy.push(LossyValue::new(
86 "another_key".to_string(),
87 "%FFbar".to_string(),
88 ));
89
90 let display = lossy.to_string();
91 assert_eq!(display, "variable_dp_match, another_key");
92 assert!(!display.contains("%E9"));
93 assert!(!display.contains("foo"));
94 }
95
96 #[test]
97 fn lossy_values_empty() {
98 let lossy = LossyValues::default();
99 assert!(lossy.is_empty());
100 assert_eq!(
101 lossy
102 .iter()
103 .count(),
104 0
105 );
106 }
107
108 #[cfg(feature = "serde")]
109 #[test]
110 fn serde_roundtrip() {
111 let mut lossy = LossyValues::default();
112 lossy.push(LossyValue::new("key1".to_string(), "%E9value".to_string()));
113
114 let json = serde_json::to_string(&lossy).unwrap();
115 let deserialized: LossyValues = serde_json::from_str(&json).unwrap();
116
117 assert_eq!(lossy, deserialized);
118 assert_eq!(
119 deserialized
120 .iter()
121 .next()
122 .unwrap()
123 .key(),
124 "key1"
125 );
126 assert_eq!(
127 deserialized
128 .iter()
129 .next()
130 .unwrap()
131 .raw_value(),
132 "%E9value"
133 );
134 }
135
136 #[cfg(feature = "serde")]
137 #[test]
138 fn serde_old_json_without_field() {
139 let json = "[]";
140 let lossy: LossyValues = serde_json::from_str(json).unwrap();
141 assert!(lossy.is_empty());
142 }
143}