1 use std::collections::HashMap;
2 use std::fmt;
3 use std::hash::Hash;
4
5 use crate::message_dyn::MessageDyn;
6 use crate::message_full::MessageFull;
7 use crate::reflect::acc::v2::AccessorV2;
8 use crate::reflect::acc::FieldAccessor;
9 use crate::reflect::map::ReflectMapMut;
10 use crate::reflect::map::ReflectMapRef;
11 use crate::reflect::runtime_types::RuntimeTypeHashable;
12 use crate::reflect::runtime_types::RuntimeTypeTrait;
13 use crate::reflect::ProtobufValue;
14 use crate::reflect::RuntimeType;
15
16 pub(crate) trait MapFieldAccessor: Send + Sync + 'static {
get_reflect<'a>(&self, m: &'a dyn MessageDyn) -> ReflectMapRef<'a>17 fn get_reflect<'a>(&self, m: &'a dyn MessageDyn) -> ReflectMapRef<'a>;
mut_reflect<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectMapMut<'a>18 fn mut_reflect<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectMapMut<'a>;
element_type(&self) -> (RuntimeType, RuntimeType)19 fn element_type(&self) -> (RuntimeType, RuntimeType);
20 }
21
22 pub(crate) struct MapFieldAccessorHolder {
23 pub accessor: Box<dyn MapFieldAccessor>,
24 }
25
26 impl<'a> fmt::Debug for MapFieldAccessorHolder {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 f.debug_struct("MapFieldAccessorHolder").finish()
29 }
30 }
31
32 struct MapFieldAccessorImpl<M, K, V>
33 where
34 M: MessageFull,
35 K: ProtobufValue,
36 V: ProtobufValue,
37 {
38 get_field: fn(&M) -> &HashMap<K, V>,
39 mut_field: fn(&mut M) -> &mut HashMap<K, V>,
40 }
41
42 impl<M, K, V> MapFieldAccessor for MapFieldAccessorImpl<M, K, V>
43 where
44 M: MessageFull,
45 K: ProtobufValue + Eq + Hash,
46 K::RuntimeType: RuntimeTypeHashable,
47 V: ProtobufValue,
48 {
get_reflect<'a>(&self, m: &'a dyn MessageDyn) -> ReflectMapRef<'a>49 fn get_reflect<'a>(&self, m: &'a dyn MessageDyn) -> ReflectMapRef<'a> {
50 let m = m.downcast_ref().unwrap();
51 let map = (self.get_field)(m);
52 ReflectMapRef::new(map)
53 }
54
mut_reflect<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectMapMut<'a>55 fn mut_reflect<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectMapMut<'a> {
56 let m = m.downcast_mut().unwrap();
57 let map = (self.mut_field)(m);
58 ReflectMapMut::new(map)
59 }
60
element_type(&self) -> (RuntimeType, RuntimeType)61 fn element_type(&self) -> (RuntimeType, RuntimeType) {
62 (
63 K::RuntimeType::runtime_type_box(),
64 V::RuntimeType::runtime_type_box(),
65 )
66 }
67 }
68
69 /// Make accessor for map field
make_map_simpler_accessor<M, K, V>( name: &'static str, get_field: for<'a> fn(&'a M) -> &'a HashMap<K, V>, mut_field: for<'a> fn(&'a mut M) -> &'a mut HashMap<K, V>, ) -> FieldAccessor where M: MessageFull + 'static, K: ProtobufValue + Hash + Eq, K::RuntimeType: RuntimeTypeHashable, V: ProtobufValue,70 pub fn make_map_simpler_accessor<M, K, V>(
71 name: &'static str,
72 get_field: for<'a> fn(&'a M) -> &'a HashMap<K, V>,
73 mut_field: for<'a> fn(&'a mut M) -> &'a mut HashMap<K, V>,
74 ) -> FieldAccessor
75 where
76 M: MessageFull + 'static,
77 K: ProtobufValue + Hash + Eq,
78 K::RuntimeType: RuntimeTypeHashable,
79 V: ProtobufValue,
80 {
81 FieldAccessor::new(
82 name,
83 AccessorV2::Map(MapFieldAccessorHolder {
84 accessor: Box::new(MapFieldAccessorImpl::<M, K, V> {
85 get_field,
86 mut_field,
87 }),
88 }),
89 )
90 }
91