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 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 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 pub fn index2(&self, key: &str) -> &T {
30 self.get2(key).expect("key not found")
31 }
32
33 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}