protobuf/reflect/dynamic/
map.rs
1use std::collections::hash_map;
2use std::collections::HashMap;
3use std::fmt;
4use std::hash::Hash;
5
6use crate::reflect::map::ReflectMap;
7use crate::reflect::map::ReflectMapIter;
8use crate::reflect::map::ReflectMapIterTrait;
9use crate::reflect::runtime_types::RuntimeTypeTrait;
10use crate::reflect::ProtobufValue;
11use crate::reflect::ReflectValueBox;
12use crate::reflect::ReflectValueRef;
13use crate::reflect::RuntimeType;
14
15#[derive(Clone)]
16enum Maps {
17 U32(HashMap<u32, ReflectValueBox>),
18 I32(HashMap<i32, ReflectValueBox>),
19 U64(HashMap<u64, ReflectValueBox>),
20 I64(HashMap<i64, ReflectValueBox>),
21 Bool(HashMap<bool, ReflectValueBox>),
22 String(HashMap<String, ReflectValueBox>),
23}
24
25impl fmt::Debug for Maps {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 match self {
28 Maps::U32(map) => fmt::Debug::fmt(map, f),
29 Maps::I32(map) => fmt::Debug::fmt(map, f),
30 Maps::U64(map) => fmt::Debug::fmt(map, f),
31 Maps::I64(map) => fmt::Debug::fmt(map, f),
32 Maps::Bool(map) => fmt::Debug::fmt(map, f),
33 Maps::String(map) => fmt::Debug::fmt(map, f),
34 }
35 }
36}
37
38impl Maps {
39 fn len(&self) -> usize {
40 match self {
41 Maps::U32(m) => m.len(),
42 Maps::I32(m) => m.len(),
43 Maps::U64(m) => m.len(),
44 Maps::I64(m) => m.len(),
45 Maps::Bool(m) => m.len(),
46 Maps::String(m) => m.len(),
47 }
48 }
49
50 fn is_empty(&self) -> bool {
51 match self {
52 Maps::U32(m) => m.is_empty(),
53 Maps::I32(m) => m.is_empty(),
54 Maps::U64(m) => m.is_empty(),
55 Maps::I64(m) => m.is_empty(),
56 Maps::Bool(m) => m.is_empty(),
57 Maps::String(m) => m.is_empty(),
58 }
59 }
60
61 fn clear(&mut self) {
62 match self {
63 Maps::U32(m) => m.clear(),
64 Maps::I32(m) => m.clear(),
65 Maps::U64(m) => m.clear(),
66 Maps::I64(m) => m.clear(),
67 Maps::Bool(m) => m.clear(),
68 Maps::String(m) => m.clear(),
69 }
70 }
71
72 fn key_type(&self) -> RuntimeType {
73 match self {
74 Maps::U32(..) => RuntimeType::U32,
75 Maps::I32(..) => RuntimeType::I32,
76 Maps::U64(..) => RuntimeType::U64,
77 Maps::I64(..) => RuntimeType::I64,
78 Maps::Bool(..) => RuntimeType::Bool,
79 Maps::String(..) => RuntimeType::String,
80 }
81 }
82}
83
84#[derive(Clone)]
85pub(crate) struct DynamicMap {
86 value: RuntimeType,
90 maps: Maps,
91}
92
93impl fmt::Debug for DynamicMap {
94 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
95 fmt::Debug::fmt(&self.maps, f)
96 }
97}
98
99impl DynamicMap {
100 pub fn new(key: RuntimeType, value: RuntimeType) -> DynamicMap {
101 DynamicMap {
102 value,
103 maps: match key {
104 RuntimeType::U32 => Maps::U32(HashMap::new()),
105 RuntimeType::I32 => Maps::I32(HashMap::new()),
106 RuntimeType::U64 => Maps::U64(HashMap::new()),
107 RuntimeType::I64 => Maps::I64(HashMap::new()),
108 RuntimeType::Bool => Maps::Bool(HashMap::new()),
109 RuntimeType::String => Maps::String(HashMap::new()),
110 t => panic!("type cannot be hashmap key: {}", t),
111 },
112 }
113 }
114}
115
116struct DynamicMapIterImpl<'a, K: ProtobufValue + Eq + Hash + 'static> {
117 iter: hash_map::Iter<'a, K, ReflectValueBox>,
118 _value_type: &'a RuntimeType,
119}
120
121impl<'a, K: ProtobufValue + Eq + Hash + 'static> ReflectMapIterTrait<'a>
122 for DynamicMapIterImpl<'a, K>
123{
124 fn next(&mut self) -> Option<(ReflectValueRef<'a>, ReflectValueRef<'a>)> {
125 self.iter
126 .next()
127 .map(|(k, v)| (K::RuntimeType::as_ref(k), v.as_value_ref()))
128 }
129
130 fn _key_type(&self) -> RuntimeType {
131 K::RuntimeType::runtime_type_box()
132 }
133
134 fn _value_type(&self) -> RuntimeType {
135 self._value_type.clone()
136 }
137}
138
139impl ReflectMap for DynamicMap {
140 fn reflect_iter(&self) -> ReflectMapIter {
141 match &self.maps {
142 Maps::U32(m) => ReflectMapIter::new(DynamicMapIterImpl {
143 iter: m.iter(),
144 _value_type: &self.value,
145 }),
146 Maps::I32(m) => ReflectMapIter::new(DynamicMapIterImpl {
147 iter: m.iter(),
148 _value_type: &self.value,
149 }),
150 Maps::U64(m) => ReflectMapIter::new(DynamicMapIterImpl {
151 iter: m.iter(),
152 _value_type: &self.value,
153 }),
154 Maps::I64(m) => ReflectMapIter::new(DynamicMapIterImpl {
155 iter: m.iter(),
156 _value_type: &self.value,
157 }),
158 Maps::Bool(m) => ReflectMapIter::new(DynamicMapIterImpl {
159 iter: m.iter(),
160 _value_type: &self.value,
161 }),
162 Maps::String(m) => ReflectMapIter::new(DynamicMapIterImpl {
163 iter: m.iter(),
164 _value_type: &self.value,
165 }),
166 }
167 }
168
169 fn len(&self) -> usize {
170 self.maps.len()
171 }
172
173 fn is_empty(&self) -> bool {
174 self.maps.is_empty()
175 }
176
177 fn get<'a>(&'a self, key: ReflectValueRef) -> Option<ReflectValueRef<'a>> {
178 match (&self.maps, key) {
179 (Maps::U32(m), ReflectValueRef::U32(v)) => m.get(&v),
180 (Maps::U64(m), ReflectValueRef::U64(v)) => m.get(&v),
181 (Maps::I32(m), ReflectValueRef::I32(v)) => m.get(&v),
182 (Maps::I64(m), ReflectValueRef::I64(v)) => m.get(&v),
183 (Maps::Bool(m), ReflectValueRef::Bool(v)) => m.get(&v),
184 (Maps::String(m), ReflectValueRef::String(v)) => m.get(&*v),
185 _ => None,
186 }
187 .map(ReflectValueBox::as_value_ref)
188 }
189
190 fn insert(&mut self, key: ReflectValueBox, value: ReflectValueBox) {
191 assert!(value.get_type() == self.value);
192 match (&mut self.maps, &key) {
193 (Maps::U32(m), ReflectValueBox::U32(k)) => m.insert(*k, value),
194 (Maps::U64(m), ReflectValueBox::U64(k)) => m.insert(*k, value),
195 (Maps::I32(m), ReflectValueBox::I32(k)) => m.insert(*k, value),
196 (Maps::I64(m), ReflectValueBox::I64(k)) => m.insert(*k, value),
197 (Maps::Bool(m), ReflectValueBox::Bool(k)) => m.insert(*k, value),
198 (Maps::String(m), _) => match key {
199 ReflectValueBox::String(k) => m.insert(k, value),
200 _ => panic!("wrong key type"),
201 },
202 _ => panic!("wrong key type"),
203 };
204 }
205
206 fn clear(&mut self) {
207 self.maps.clear()
208 }
209
210 fn key_type(&self) -> RuntimeType {
211 self.maps.key_type()
212 }
213
214 fn value_type(&self) -> RuntimeType {
215 self.value.clone()
216 }
217}