• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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