multidict/lib.rs
1//! # multidict
2//!
3//! The `multidict` crate was inspired by Python `MultiDict` library
4//! `multidict` is useful for working with HTTP headers, URL query, form-data args etc
5//! HTTP Headers and URL query string require specific data structure: `multidict`.
6//! It behaves mostly like a regular map but it may have several values for the same key
7//! and preserves insertion ordering
8//!
9//! ## Examples
10//!
11//! Basic `MultiDict` creation and filling with data
12//! ```
13//! use multidict::{MultiDict, MultiElement};
14//!
15//! let mut map = MultiDict::new();
16//! map.add(MultiElement {
17//! key: "some_key".to_string(),
18//! value: "some_value_1".to_string(),
19//! });
20//! println!("{map}"); // MultiDict < "some_key":"some_value_1" >
21//! map.add(MultiElement {
22//! key: "some_key".to_string(),
23//! value: "some_value_2".to_string(),
24//! });
25//! println!("{map}");
26//! // MultiDict < "some_key":"some_value_1", "some_key":"some_value_2" >
27//! ```
28//!
29//! Get **all** key-values pairs for key
30//! ```
31//! use multidict::{MultiDict, MultiElement};
32//!
33//! let mut map = MultiDict::new();
34//! map.add(MultiElement {
35//! key: "some_key".to_string(),
36//! value: "some_value_1".to_string(),
37//! });
38//! map.add(MultiElement {
39//! key: "some_key".to_string(),
40//! value: "some_value_2".to_string(),
41//! });
42//! map.add(MultiElement {
43//! key: "some_other_key".to_string(),
44//! value: "some_value_3".to_string(),
45//! });
46//! println!("{}", map.getall("some_key").unwrap());
47//! // MultiDict < "some_key":"some_value_1", "some_key":"some_value_2" >
48//! ```
49//!
50//! `MultiDict` debug output
51//! ```
52//! use multidict::{MultiDict, MultiElement};
53//!
54//! let mut map = MultiDict::new();
55//! map.add(MultiElement {
56//! key: "some_key".to_string(),
57//! value: "some_value_1".to_string(),
58//! });
59//! map.add(MultiElement {
60//! key: "some_key".to_string(),
61//! value: "some_value_2".to_string(),
62//! });
63//! map.add(MultiElement {
64//! key: "some_other_key".to_string(),
65//! value: "some_value_3".to_string(),
66//! });
67//! println!("{map:?}");
68//! // MultiDict { elements: [
69//! // MultiElement { key: "some_key", value: "some_value_1" },
70//! // MultiElement { key: "some_key", value: "some_value_2" },
71//! // MultiElement { key: "some_other_key", value: "some_value_3" }
72//! // ] }
73//! ```
74use core::slice::Iter;
75use std::fmt;
76
77/// `MultiElement` - element of `MultiDict` structure Vec.
78#[derive(Debug, Clone, Eq, PartialEq)]
79pub struct MultiElement {
80 pub key: String,
81 pub value: String,
82}
83impl fmt::Display for MultiElement {
84 /// `MultiElement` instance formatter
85 ///
86 /// # Examples
87 /// ```
88 /// use multidict::MultiElement;
89 ///
90 /// let element: MultiElement = MultiElement::new(["some_key".to_string(),
91 /// "some_value".to_string()
92 /// ]);
93 /// println!("{element}")
94 /// // MultiElement < "some_key":"some_value_2" >
95 /// ```
96 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97 write!(f, r#"MultiElement < "{}":"{}" >"#, self.key, self.value)
98 }
99}
100impl MultiElement {
101 /// Return new MultiElement instance
102 ///
103 /// # Examples
104 /// ```
105 /// use multidict::MultiElement;
106 ///
107 /// let element: MultiElement = MultiElement::new(["some_key".to_string(),
108 /// "some_value".to_string()
109 /// ]);
110 /// ```
111 pub fn new(new_element: [String; 2]) -> Self {
112 MultiElement {
113 key: new_element[0].clone(),
114 value: new_element[1].clone(),
115 }
116 }
117}
118
119/// `MultiDict` - structure which enable to user store multiple
120/// similar keys with different values in map-like structure.
121///
122/// Was inspired by Python `MultiDict` library
123#[derive(Default, Debug, Clone)]
124pub struct MultiDict {
125 pub elements: Vec<MultiElement>,
126}
127impl fmt::Display for MultiDict {
128 /// `MultiDict` instance formatter
129 ///
130 /// # Examples
131 /// ```
132 /// use multidict::{MultiDict, MultiElement};
133 ///
134 /// let mut map: MultiDict = MultiDict::new();
135 /// map.add(MultiElement {
136 /// key: "some_key".to_string(),
137 /// value: "some_value_1".to_string(),
138 /// });
139 /// map.add(MultiElement {
140 /// key: "some_key".to_string(),
141 /// value: "some_value_2".to_string(),
142 /// });
143 /// println!("{}", map);
144 /// // MultiDict < "some_key":"some_value_1", "some_key":"some_value_2" >
145 /// ```
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 write!(
148 f,
149 "MultiDict < {} >",
150 self.elements
151 .iter()
152 .map(|item| format!(r#""{}":"{}""#, item.key, item.value))
153 .collect::<Vec<_>>()
154 .join(", ")
155 )
156 }
157}
158impl MultiDict {
159 /// Return new MultiDict instance
160 ///
161 /// # Examples
162 /// ```
163 /// use multidict::MultiDict;
164 ///
165 /// let mut map: MultiDict = MultiDict::new();
166 /// ```
167 pub fn new() -> Self {
168 MultiDict {
169 elements: Vec::new(),
170 }
171 }
172
173 /// Return new MultiDict instance with preset capacity
174 ///
175 /// # Examples
176 ///
177 /// Capacity will only prepare Vector with element for future elements,
178 /// but it can expand
179 /// ```
180 /// use multidict::{MultiDict, MultiElement};
181 ///
182 /// let mut map: MultiDict = MultiDict::new_capacity(&2);
183 /// map.add(MultiElement {
184 /// key: "some_key".to_string(),
185 /// value: "some_value_1".to_string(),
186 /// });
187 /// map.add(MultiElement {
188 /// key: "some_key".to_string(),
189 /// value: "some_value_2".to_string(),
190 /// });
191 /// println!("{}", map.len());
192 /// // 2
193 /// ```
194 /// ```
195 /// use multidict::{MultiDict, MultiElement};
196 ///
197 /// let mut map: MultiDict = MultiDict::new_capacity(&2);
198 /// map.add(MultiElement {
199 /// key: "some_key".to_string(),
200 /// value: "some_value_1".to_string(),
201 /// });
202 /// map.add(MultiElement {
203 /// key: "some_key".to_string(),
204 /// value: "some_value_2".to_string(),
205 /// });
206 /// map.add(MultiElement {
207 /// key: "some_other_key".to_string(),
208 /// value: "some_value_3".to_string(),
209 /// });
210 /// println!("{}", map.len());
211 /// // 3
212 /// ```
213 pub fn new_capacity(capacity: &usize) -> Self {
214 MultiDict {
215 elements: Vec::with_capacity(*capacity),
216 }
217 }
218
219 /// Return the number of items in MultiDict
220 ///
221 /// # Examples
222 /// ```
223 /// use multidict::{MultiDict, MultiElement};
224 ///
225 /// let mut map = MultiDict::new();
226 /// map.add(MultiElement {
227 /// key: "some_key".to_string(),
228 /// value: "some_value_1".to_string(),
229 /// });
230 /// map.add(MultiElement {
231 /// key: "some_key".to_string(),
232 /// value: "some_value_2".to_string(),
233 /// });
234 /// println!("{}", map.len());
235 /// // 2
236 /// ```
237 pub fn len(&self) -> usize {
238 self.elements.len()
239 }
240
241 /// Return an iterator over the element.
242 ///
243 /// The iterator yields all items from start to end.
244 ///
245 /// # Examples
246 /// ```
247 /// use multidict::{MultiDict, MultiElement};
248 ///
249 /// let mut map = MultiDict::new();
250 /// map.add(MultiElement {
251 /// key: "some_key".to_string(),
252 /// value: "some_value_1".to_string(),
253 /// });
254 /// map.add(MultiElement {
255 /// key: "some_key".to_string(),
256 /// value: "some_value_2".to_string(),
257 /// });
258 /// for el in map.iter(){
259 /// println!("{el}")
260 /// }
261 /// // MultiElement < "some_key":"some_value_1" >
262 /// // MultiElement < "some_key":"some_value_2" >
263 /// ```
264 ///
265 /// ```
266 /// use multidict::{MultiDict, MultiElement};
267 ///
268 /// let mut map = MultiDict::new();
269 /// map.add(MultiElement {
270 /// key: "some_key".to_string(),
271 /// value: "some_value_1".to_string(),
272 /// });
273 /// map.add(MultiElement {
274 /// key: "some_key".to_string(),
275 /// value: "some_value_2".to_string(),
276 /// });
277 /// let mut iterator = map.iter();
278 /// assert_eq!(iterator.next(), Some(map.elements.iter().nth(0).unwrap()));
279 /// assert_eq!(iterator.next(), Some(&MultiElement {
280 /// key: "some_key".to_string(),
281 /// value: "some_value_2".to_string(),
282 /// })
283 /// );
284 /// ```
285 pub fn iter(&self) -> Iter<MultiElement> {
286 self.elements.iter()
287 }
288
289 /// Return true if `MultiDict` has **no** elements,
290 /// else false
291 ///
292 /// # Examples
293 ///
294 /// When some elements is added
295 /// ```
296 /// use multidict::{MultiDict, MultiElement};
297 ///
298 /// let mut map = MultiDict::new();
299 /// map.add(MultiElement {
300 /// key: "some_key".to_string(),
301 /// value: "some_value_1".to_string(),
302 /// });
303 /// map.add(MultiElement {
304 /// key: "some_key".to_string(),
305 /// value: "some_value_2".to_string(),
306 /// });
307 /// println!("{}", map.is_empty());
308 /// // false
309 /// ```
310 /// ```
311 /// use multidict::{MultiDict, MultiElement};
312 ///
313 /// let mut map = MultiDict::new();
314 /// println!("{}", map.is_empty());
315 /// // true
316 /// ```
317 pub fn is_empty(&self) -> bool {
318 self.elements.is_empty()
319 }
320
321 /// Append (key, value) pair to the MultiDict.
322 ///
323 /// # Examples
324 /// ```
325 /// use multidict::{MultiDict, MultiElement};
326 ///
327 /// let mut map = MultiDict::new();
328 /// map.add(MultiElement {
329 /// key: "some_key".to_string(),
330 /// value: "some_value_1".to_string(),
331 /// });
332 /// println!("{map}");
333 /// // MultiDict < "some_key":"some_value_1" >
334 /// map.add(MultiElement {
335 /// key: "some_key".to_string(),
336 /// value: "some_value_2".to_string(),
337 /// });
338 /// println!("{map}");
339 /// // MultiDict < "some_key":"some_value_1", "some_key":"some_value_2" >
340 /// ```
341 pub fn add(&mut self, new_item: MultiElement) {
342 self.elements.push(new_item);
343 }
344
345 /// Return the **first** key-value pair for key if key is in the MultiDict
346 ///
347 /// # Examples
348 ///
349 /// If key exists
350 /// ```
351 /// use multidict::{MultiDict, MultiElement};
352 ///
353 /// let mut map = MultiDict::new();
354 /// map.add(MultiElement {
355 /// key: "some_key".to_string(),
356 /// value: "some_value_1".to_string(),
357 /// });
358 /// map.add(MultiElement {
359 /// key: "some_key".to_string(),
360 /// value: "some_value_2".to_string(),
361 /// });
362 /// println!("{}", map.get("some_key").unwrap());
363 /// // MultiElement < "some_key":"some_value_1" >
364 /// ```
365 ///
366 /// If key not exists
367 /// ```
368 /// use multidict::{MultiDict, MultiElement};
369 ///
370 /// let mut map = MultiDict::new();
371 /// map.add(MultiElement {
372 /// key: "some_key".to_string(),
373 /// value: "some_value_1".to_string(),
374 /// });
375 /// map.add(MultiElement {
376 /// key: "some_key".to_string(),
377 /// value: "some_value_2".to_string(),
378 /// });
379 /// println!("{:?}", map.get("some_other_key"));
380 /// // Err("No matching key found")
381 /// ```
382 pub fn get(&self, key: &str) -> Result<&MultiElement, &str> {
383 for item in &self.elements {
384 if item.key.eq(key) {
385 return Ok(item);
386 }
387 }
388 Err("No matching key found")
389 }
390
391 /// If key is in the MultiDict, remove it and return its the **first** value,
392 /// else return error text
393 ///
394 /// # Examples
395 ///
396 /// If key exists
397 /// ```
398 /// use multidict::{MultiDict, MultiElement};
399 ///
400 /// let mut map = MultiDict::new();
401 /// map.add(MultiElement {
402 /// key: "some_key".to_string(),
403 /// value: "some_value_1".to_string(),
404 /// });
405 /// map.add(MultiElement {
406 /// key: "some_key".to_string(),
407 /// value: "some_value_2".to_string(),
408 /// });
409 /// println!("{}", map);
410 /// // MultiDict < "some_key":"some_value_1", "some_key":"some_value_2" >
411 /// println!("{}", map.popone("some_key").unwrap());
412 /// // MultiElement < "some_key":"some_value_1" >
413 /// println!("{}", map);
414 /// // MultiDict < "some_key":"some_value_2" >
415 /// ```
416 ///
417 /// If key not exists
418 /// ```
419 /// use multidict::{MultiDict, MultiElement};
420 ///
421 /// let mut map = MultiDict::new();
422 /// map.add(MultiElement {
423 /// key: "some_key".to_string(),
424 /// value: "some_value_1".to_string(),
425 /// });
426 /// map.add(MultiElement {
427 /// key: "some_key".to_string(),
428 /// value: "some_value_2".to_string(),
429 /// });
430 /// println!("{:?}", map.popone("some_other_key"));
431 /// // Err("No matching key found")
432 /// println!("{}", map);
433 /// // MultiDict < "some_key":"some_value_1", "some_key":"some_value_2" >
434 /// ```
435 ///
436 pub fn popone(&mut self, key: &str) -> Result<MultiElement, &str> {
437 for (idx, item) in self.elements.iter().enumerate() {
438 if item.key.eq(key) {
439 return Ok(self.elements.remove(idx));
440 }
441 }
442 Err("No matching key found")
443 }
444
445 /// Return a list of all key-values for key if key is in the MultiDict
446 /// else - return error
447 ///
448 /// # Examples
449 ///
450 /// If key exists
451 /// ```
452 /// use multidict::{MultiDict, MultiElement};
453 ///
454 /// let mut map = MultiDict::new();
455 /// map.add(MultiElement {
456 /// key: "some_key".to_string(),
457 /// value: "some_value_1".to_string(),
458 /// });
459 /// map.add(MultiElement {
460 /// key: "some_key".to_string(),
461 /// value: "some_value_2".to_string(),
462 /// });
463 /// println!("{}", map.getall("some_key").unwrap());
464 /// // MultiDict < "some_key":"some_value_1", "some_key":"some_value_2" >
465 /// ```
466 ///
467 /// If key not exists
468 /// ```
469 /// use multidict::{MultiDict, MultiElement};
470 ///
471 /// let mut map = MultiDict::new();
472 /// map.add(MultiElement {
473 /// key: "some_key".to_string(),
474 /// value: "some_value_1".to_string(),
475 /// });
476 /// map.add(MultiElement {
477 /// key: "some_key".to_string(),
478 /// value: "some_value_2".to_string(),
479 /// });
480 /// println!("{:?}", map.getall("some_other_key")); // Err("No matching key found")
481 /// ```
482 pub fn getall(&self, key: &str) -> Result<MultiDict, &str> {
483 let mut results = MultiDict::new();
484 for item in &self.elements {
485 if item.key.eq(key) {
486 results.add(item.clone());
487 }
488 }
489 if !results.is_empty() {
490 Ok(results)
491 } else {
492 Err("No matching key found")
493 }
494 }
495
496 /// Return True if MultiDict has a key, else False.
497 ///
498 /// # Examples
499 ///
500 /// If key exists
501 /// ```
502 /// use multidict::{MultiDict, MultiElement};
503 ///
504 /// let mut map = MultiDict::new();
505 /// map.add(MultiElement {
506 /// key: "some_key".to_string(),
507 /// value: "some_value_1".to_string(),
508 /// });
509 /// map.add(MultiElement {
510 /// key: "some_key".to_string(),
511 /// value: "some_value_2".to_string(),
512 /// });
513 /// println!("{}", map.contains("some_key"));
514 /// // true
515 /// ```
516 ///
517 /// If key not exists
518 /// ```
519 /// use multidict::{MultiDict, MultiElement};
520 ///
521 /// let mut map = MultiDict::new();
522 /// map.add(MultiElement {
523 /// key: "some_key".to_string(),
524 /// value: "some_value_1".to_string(),
525 /// });
526 /// map.add(MultiElement {
527 /// key: "some_key".to_string(),
528 /// value: "some_value_2".to_string(),
529 /// });
530 /// println!("{}", map.contains("some_other_key"));
531 /// // false
532 /// ```
533 pub fn contains(&self, key: &str) -> bool {
534 for item in &self.elements {
535 if item.key.eq(key) {
536 return true;
537 }
538 }
539 false
540 }
541
542 /// Return Vec of all keys form MultiDict.
543 /// View contains all keys, possibly with duplicates.
544 ///
545 /// # Examples
546 ///
547 /// ```
548 /// use multidict::{MultiDict, MultiElement};
549 ///
550 /// let mut map = MultiDict::new();
551 /// map.add(MultiElement {
552 /// key: "some_key".to_string(),
553 /// value: "some_value_1".to_string(),
554 /// });
555 /// map.add(MultiElement {
556 /// key: "some_key".to_string(),
557 /// value: "some_value_2".to_string(),
558 /// });
559 /// map.add(MultiElement {
560 /// key: "some_other_key".to_string(),
561 /// value: "some_value_3".to_string(),
562 /// });
563 /// println!("{:?}", map.keys());
564 /// // ["some_key", "some_key", "some_other_key"]
565 /// ```
566 pub fn keys(&self) -> Vec<&String> {
567 let mut results: Vec<&String> = Vec::with_capacity(self.elements.len());
568 for item in &self.elements {
569 results.push(&item.key);
570 }
571 results
572 }
573
574 /// Return Vec of all values form MultiDict.
575 ///
576 /// # Examples
577 ///
578 /// ```
579 /// use multidict::{MultiDict, MultiElement};
580 ///
581 /// let mut map = MultiDict::new();
582 /// map.add(MultiElement {
583 /// key: "some_key".to_string(),
584 /// value: "some_value_1".to_string(),
585 /// });
586 /// map.add(MultiElement {
587 /// key: "some_key".to_string(),
588 /// value: "some_value_2".to_string(),
589 /// });
590 /// map.add(MultiElement {
591 /// key: "some_other_key".to_string(),
592 /// value: "some_value_3".to_string(),
593 /// });
594 /// println!("{:?}", map.values());
595 /// // ["some_value_1", "some_value_2", "some_value_3"]
596 /// ```
597 pub fn values(&self) -> Vec<&String> {
598 let mut results: Vec<&String> = Vec::with_capacity(self.elements.len());
599 for item in &self.elements {
600 results.push(&item.value);
601 }
602 results
603 }
604
605 /// Update the MultiDict with the key/value pairs,
606 /// overwriting existing keys/values
607 ///
608 /// # Examples
609 ///
610 /// This function update values **only** for already exists keys
611 /// ```
612 /// use multidict::{MultiDict, MultiElement};
613 ///
614 /// let mut map = MultiDict::new();
615 /// map.add(MultiElement {
616 /// key: "some_key".to_string(),
617 /// value: "some_value_1".to_string(),
618 /// });
619 /// map.add(MultiElement {
620 /// key: "some_other_key".to_string(),
621 /// value: "some_value_2".to_string(),
622 /// });
623 /// println!("{map}");
624 /// // MultiDict < "some_key":"some_value_1", "some_other_key":"some_value_2" >
625 /// map.update(MultiElement {
626 /// key: "some_other_key".to_string(),
627 /// value: "some_value_3".to_string(),
628 /// });
629 /// println!("{map}");
630 /// // MultiDict < "some_key":"some_value_1", "some_other_key":"some_value_3" >
631 /// ```
632 ///
633 /// And it's update all equal keys values
634 /// ```
635 /// use multidict::{MultiDict, MultiElement};
636 ///
637 /// let mut map = MultiDict::new();
638 /// map.add(MultiElement {
639 /// key: "some_key".to_string(),
640 /// value: "some_value_1".to_string(),
641 /// });
642 /// map.add(MultiElement {
643 /// key: "some_key".to_string(),
644 /// value: "some_value_2".to_string(),
645 /// });
646 /// println!("{map}");
647 /// // MultiDict < "some_key":"some_value_1", "some_key":"some_value_2" >
648 /// map.update(MultiElement {
649 /// key: "some_key".to_string(),
650 /// value: "some_value_3".to_string(),
651 /// });
652 /// println!("{map}");
653 /// // MultiDict < "some_key":"some_value_3", "some_key":"some_value_3" >
654 /// ```
655 pub fn update(&mut self, new_item: MultiElement) {
656 let new_item_key = &new_item.key;
657 let mut ids_for_replace = Vec::new();
658
659 for (idx, item) in self.elements.iter().enumerate() {
660 if item.key.eq(new_item_key) {
661 ids_for_replace.push(idx);
662 }
663 }
664 for idx in ids_for_replace {
665 self.elements.remove(idx);
666 self.elements.insert(idx, new_item.clone());
667 }
668 }
669}