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