openapiv3/
map.rs

1use indexmap::IndexMap;
2use serde::{Deserialize, Serialize};
3
4use crate::RefOr;
5
6pub type RefOrMap<T> = RefMap<T>;
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
9pub struct RefMap<T>(IndexMap<String, RefOr<T>>);
10
11impl<T> RefOrMap<T> {
12    pub fn new() -> Self {
13        RefMap(IndexMap::new())
14    }
15
16    /// Directly get the inner struct of a RefOr::Item
17    pub fn get2(&self, key: &str) -> Option<&T> {
18        let v = self.0.get(key);
19        v.and_then(|v| v.as_item())
20    }
21
22    /// Directly get_mut the inner struct of a RefOr::Item
23    pub fn get_mut2(&mut self, key: &str) -> Option<&mut T> {
24        let v = self.0.get_mut(key);
25        v.and_then(|v| v.as_mut())
26    }
27
28    /// Directly lookup the inner struct of a RefOr::Item, panicking on not found
29    pub fn index2(&self, key: &str) -> &T {
30        self.get2(key).expect("key not found")
31    }
32
33    /// Directly lookup (mut) the inner struct of a RefOr::Item, panicking on not found
34    pub fn index_mut2(&mut self, key: &str) -> &mut T {
35        self.get_mut2(key).expect("key not found")
36    }
37}
38
39impl<T> std::ops::Deref for RefOrMap<T> {
40    type Target = IndexMap<String, RefOr<T>>;
41
42    fn deref(&self) -> &Self::Target {
43        &self.0
44    }
45}
46
47impl<T> std::ops::DerefMut for RefOrMap<T> {
48    fn deref_mut(&mut self) -> &mut Self::Target {
49        &mut self.0
50    }
51}
52
53impl<T> RefOrMap<T> {
54    pub fn insert(&mut self, key: impl Into<String>, value: impl Into<RefOr<T>>) -> Option<RefOr<T>> {
55        let key = key.into();
56        let value = value.into();
57        self.0.insert(key, value)
58    }
59}
60
61impl<T> std::iter::FromIterator<(String, RefOr<T>)> for RefOrMap<T> {
62    fn from_iter<I: IntoIterator<Item = (String, RefOr<T>)>>(iter: I) -> Self {
63        RefMap(IndexMap::from_iter(iter))
64    }
65}
66
67impl<T> IntoIterator for RefMap<T> {
68    type Item = (String, RefOr<T>);
69    type IntoIter = indexmap::map::IntoIter<String, RefOr<T>>;
70
71    fn into_iter(self) -> Self::IntoIter {
72        self.0.into_iter()
73    }
74}
75
76impl<'a, T> IntoIterator for &'a RefMap<T> {
77    type Item = (&'a String, &'a RefOr<T>);
78    type IntoIter = indexmap::map::Iter<'a, String, RefOr<T>>;
79
80    fn into_iter(self) -> Self::IntoIter {
81        self.0.iter()
82    }
83}
84
85impl<'a, T> IntoIterator for &'a mut RefMap<T> {
86    type Item = (&'a String, &'a mut RefOr<T>);
87    type IntoIter = indexmap::map::IterMut<'a, String, RefOr<T>>;
88
89    fn into_iter(self) -> Self::IntoIter {
90        self.0.iter_mut()
91    }
92}
93
94impl<T> Default for RefMap<T> {
95    fn default() -> Self {
96        RefMap(IndexMap::default())
97    }
98}
99
100impl<T> Into<IndexMap<String, RefOr<T>>> for RefOrMap<T> {
101    fn into(self) -> IndexMap<String, RefOr<T>> {
102        self.0
103    }
104}
105
106impl<T> From<IndexMap<String, RefOr<T>>> for RefMap<T> {
107    fn from(map: IndexMap<String, RefOr<T>>) -> Self {
108        RefMap(map)
109    }
110}
111
112#[cfg(test)]
113mod tests {
114    use super::*;
115
116    #[test]
117    fn test_oa_ref_map_insert_coercion() {
118        let mut s: RefOrMap<usize> = RefMap(IndexMap::new());
119        s.insert("a", 1);
120    }
121}