1use serde::de::{self, MapAccess, SeqAccess, Visitor};
4use serde::ser::SerializeSeq;
5use serde::{Deserialize, Deserializer, Serialize, Serializer};
6
7use super::value::{FieldValue, Inspected};
8use crate::db::DbValue;
9
10#[derive(Debug, Clone, Default, PartialEq, Eq)]
43pub struct KeyValues(Vec<(String, String)>);
44
45impl KeyValues {
46 pub fn new() -> Self {
48 Self::default()
49 }
50
51 pub fn get(&self, key: &str) -> Option<&str> {
53 self.0
54 .iter()
55 .find(|(k, _)| k == key)
56 .map(|(_, v)| v.as_str())
57 }
58
59 pub fn insert(&mut self, key: impl Into<String>, value: impl Into<String>) {
61 let (key, value) = (key.into(), value.into());
62 match self.0.iter_mut().find(|(k, _)| *k == key) {
63 Some(pair) => pair.1 = value,
64 None => self.0.push((key, value)),
65 }
66 }
67
68 pub fn iter(&self) -> impl Iterator<Item = (&str, &str)> {
70 self.0.iter().map(|(k, v)| (k.as_str(), v.as_str()))
71 }
72
73 pub fn len(&self) -> usize {
75 self.0.len()
76 }
77
78 pub fn is_empty(&self) -> bool {
80 self.0.is_empty()
81 }
82
83 pub fn into_vec(self) -> Vec<(String, String)> {
85 self.0
86 }
87}
88
89impl<K: Into<String>, V: Into<String>> FromIterator<(K, V)> for KeyValues {
90 fn from_iter<I: IntoIterator<Item = (K, V)>>(pairs: I) -> Self {
91 let mut all = KeyValues::new();
92 for (key, value) in pairs {
93 all.insert(key, value);
94 }
95 all
96 }
97}
98
99impl Serialize for KeyValues {
100 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
101 let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
102 for pair in &self.0 {
103 seq.serialize_element(pair)?;
104 }
105 seq.end()
106 }
107}
108
109#[derive(Deserialize)]
112#[serde(untagged)]
113enum Row {
114 Form {
115 #[serde(default)]
116 key: Option<String>,
117 #[serde(default)]
118 value: Option<String>,
119 },
120 Pair(String, String),
121}
122
123impl<'de> Deserialize<'de> for KeyValues {
124 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
125 struct Pairs;
126
127 impl<'de> Visitor<'de> for Pairs {
128 type Value = KeyValues;
129
130 fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
131 f.write_str("rows of key and value, or an object")
132 }
133
134 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<KeyValues, A::Error> {
136 let mut all = KeyValues::new();
137 while let Some(row) = seq.next_element::<Row>()? {
138 let (key, value) = match row {
139 Row::Form { key, value } => {
140 (key.unwrap_or_default(), value.unwrap_or_default())
141 }
142 Row::Pair(key, value) => (key, value),
143 };
144 let key = key.trim();
145 if !key.is_empty() {
146 all.insert(key, value);
147 }
148 }
149 Ok(all)
150 }
151
152 fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<KeyValues, A::Error> {
154 let mut all = KeyValues::new();
155 while let Some((key, value)) = map.next_entry::<String, String>()? {
156 all.insert(key, value);
157 }
158 Ok(all)
159 }
160
161 fn visit_str<E: de::Error>(self, value: &str) -> Result<KeyValues, E> {
163 if value.trim().is_empty() {
164 Ok(KeyValues::new())
165 } else {
166 Err(E::invalid_type(de::Unexpected::Str(value), &self))
167 }
168 }
169
170 fn visit_unit<E: de::Error>(self) -> Result<KeyValues, E> {
171 Ok(KeyValues::new())
172 }
173 }
174
175 deserializer.deserialize_any(Pairs)
176 }
177}
178
179impl FieldValue for KeyValues {
180 fn inspect(&self) -> Inspected {
181 if self.is_empty() {
182 Inspected::Missing
183 } else {
184 Inspected::Items(self.len())
185 }
186 }
187
188 fn db_value(&self) -> DbValue {
189 DbValue::Null
190 }
191}
192
193#[cfg(test)]
194mod tests {
195 use super::*;
196 use crate::validation::nested::{Node, deserialize};
197
198 #[test]
199 fn reads_form_rows_and_saved_objects() {
200 #[derive(Deserialize)]
201 struct Form {
202 meta: KeyValues,
203 }
204 let pairs: Vec<(String, String)> = [
205 ("meta[0][key]", "Color"),
206 ("meta[0][value]", "Red"),
207 ("meta[1][key]", ""),
208 ("meta[1][value]", "ignored"),
209 ("meta[2][key]", " Size "),
210 ("meta[2][value]", "L"),
211 ("meta[3][key]", "Color"),
212 ("meta[3][value]", "Blue"),
213 ]
214 .iter()
215 .map(|(k, v)| ((*k).to_owned(), (*v).to_owned()))
216 .collect();
217 let form: Form = deserialize(Node::build(&pairs)).unwrap();
218 assert_eq!(
219 form.meta.iter().collect::<Vec<_>>(),
220 [("Color", "Blue"), ("Size", "L")]
221 );
222 let json = serde_json::to_string(&form.meta).unwrap();
223 assert_eq!(json, r#"[["Color","Blue"],["Size","L"]]"#);
224 let back: KeyValues = serde_json::from_str(&json).unwrap();
225 assert_eq!(back, form.meta);
226 assert_eq!(back.get("Size"), Some("L"));
227 let object: KeyValues = serde_json::from_str(r#"{"Size":"L","Color":"Blue"}"#).unwrap();
228 assert_eq!(
229 object.iter().collect::<Vec<_>>(),
230 [("Size", "L"), ("Color", "Blue")]
231 );
232 let empty: KeyValues = serde_json::from_str(r#""""#).unwrap();
233 assert!(empty.is_empty());
234 }
235
236 #[test]
237 fn text_that_isnt_empty_and_null_are_handled() {
238 let err = serde_json::from_str::<KeyValues>(r#""colour=red""#).unwrap_err();
240 assert!(
241 err.to_string()
242 .contains("expected rows of key and value, or an object"),
243 "{err}"
244 );
245 assert!(
247 serde_json::from_str::<KeyValues>(r#"" ""#)
248 .unwrap()
249 .is_empty()
250 );
251 assert!(
252 serde_json::from_str::<KeyValues>("null")
253 .unwrap()
254 .is_empty()
255 );
256 let pairs: KeyValues =
257 serde_json::from_str(r#"[["a", "1"], {"key": " b ", "value": "2"}, {"key": ""}]"#)
258 .unwrap();
259 assert_eq!(
260 pairs.into_vec(),
261 [
262 ("a".to_owned(), "1".to_owned()),
263 ("b".to_owned(), "2".to_owned())
264 ]
265 );
266 }
267}