protobuf/reflect/acc/v2/
map.rs
1use std::collections::BTreeMap;
2use std::collections::HashMap;
3use std::fmt;
4use std::hash::Hash;
5
6use crate::message_dyn::MessageDyn;
7use crate::message_full::MessageFull;
8use crate::reflect::acc::v2::AccessorV2;
9use crate::reflect::acc::FieldAccessor;
10use crate::reflect::map::ReflectMapMut;
11use crate::reflect::map::ReflectMapRef;
12use crate::reflect::runtime_types::RuntimeTypeMapKey;
13use crate::reflect::runtime_types::RuntimeTypeTrait;
14use crate::reflect::ProtobufValue;
15use crate::reflect::RuntimeType;
16
17pub(crate) trait MapFieldAccessor: Send + Sync + 'static {
18 fn get_reflect<'a>(&self, m: &'a dyn MessageDyn) -> ReflectMapRef<'a>;
19 fn mut_reflect<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectMapMut<'a>;
20 fn _element_type(&self) -> (RuntimeType, RuntimeType);
21}
22
23pub(crate) struct MapFieldAccessorHolder {
24 pub accessor: Box<dyn MapFieldAccessor>,
25}
26
27impl<'a> fmt::Debug for MapFieldAccessorHolder {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 f.debug_struct("MapFieldAccessorHolder").finish()
30 }
31}
32
33struct MapFieldAccessorImpl<M, T>
34where
35 M: MessageFull,
36{
37 get_field: fn(&M) -> &T,
38 mut_field: fn(&mut M) -> &mut T,
39}
40
41impl<M, K, V> MapFieldAccessor for MapFieldAccessorImpl<M, HashMap<K, V>>
42where
43 M: MessageFull,
44 K: ProtobufValue + Eq + Hash,
45 K::RuntimeType: RuntimeTypeMapKey,
46 V: ProtobufValue,
47{
48 fn get_reflect<'a>(&self, m: &'a dyn MessageDyn) -> ReflectMapRef<'a> {
49 let m = m.downcast_ref().unwrap();
50 let map = (self.get_field)(m);
51 ReflectMapRef::new(map)
52 }
53
54 fn mut_reflect<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectMapMut<'a> {
55 let m = m.downcast_mut().unwrap();
56 let map = (self.mut_field)(m);
57 ReflectMapMut::new(map)
58 }
59
60 fn _element_type(&self) -> (RuntimeType, RuntimeType) {
61 (
62 K::RuntimeType::runtime_type_box(),
63 V::RuntimeType::runtime_type_box(),
64 )
65 }
66}
67
68impl<M, K, V> MapFieldAccessor for MapFieldAccessorImpl<M, BTreeMap<K, V>>
69where
70 M: MessageFull,
71 K: ProtobufValue + Ord,
72 K::RuntimeType: RuntimeTypeMapKey,
73 V: ProtobufValue,
74{
75 fn get_reflect<'a>(&self, m: &'a dyn MessageDyn) -> ReflectMapRef<'a> {
76 let m = m.downcast_ref().unwrap();
77 let map = (self.get_field)(m);
78 ReflectMapRef::new(map)
79 }
80
81 fn mut_reflect<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectMapMut<'a> {
82 let m = m.downcast_mut().unwrap();
83 let map = (self.mut_field)(m);
84 ReflectMapMut::new(map)
85 }
86
87 fn _element_type(&self) -> (RuntimeType, RuntimeType) {
88 (
89 K::RuntimeType::runtime_type_box(),
90 V::RuntimeType::runtime_type_box(),
91 )
92 }
93}
94
95pub fn make_map_simpler_accessor<M, K, V>(
98 name: &'static str,
99 get_field: for<'a> fn(&'a M) -> &'a HashMap<K, V>,
100 mut_field: for<'a> fn(&'a mut M) -> &'a mut HashMap<K, V>,
101) -> FieldAccessor
102where
103 M: MessageFull + 'static,
104 K: ProtobufValue + Hash + Eq,
105 K::RuntimeType: RuntimeTypeMapKey,
106 V: ProtobufValue,
107{
108 make_map_simpler_accessor_new(name, get_field, mut_field)
109}
110
111#[allow(private_bounds)]
115pub fn make_map_simpler_accessor_new<M, T>(
116 name: &'static str,
117 get_field: for<'a> fn(&'a M) -> &'a T,
118 mut_field: for<'a> fn(&'a mut M) -> &'a mut T,
119) -> FieldAccessor
120where
121 M: MessageFull,
122 MapFieldAccessorImpl<M, T>: MapFieldAccessor,
123{
124 FieldAccessor::new(
125 name,
126 AccessorV2::Map(MapFieldAccessorHolder {
127 accessor: Box::new(MapFieldAccessorImpl::<M, T> {
128 get_field,
129 mut_field,
130 }),
131 }),
132 )
133}