protobuf/reflect/acc/v2/
repeated.rs

1use std::fmt;
2use std::marker;
3
4use crate::message_dyn::MessageDyn;
5use crate::message_full::MessageFull;
6use crate::reflect::acc::v2::AccessorV2;
7use crate::reflect::acc::FieldAccessor;
8use crate::reflect::repeated::ReflectRepeated;
9use crate::reflect::repeated::ReflectRepeatedMut;
10use crate::reflect::repeated::ReflectRepeatedRef;
11use crate::reflect::runtime_types::RuntimeTypeTrait;
12use crate::reflect::ProtobufValue;
13use crate::reflect::RuntimeType;
14
15pub(crate) trait RepeatedFieldAccessor: Send + Sync + 'static {
16    fn get_repeated<'a>(&self, m: &'a dyn MessageDyn) -> ReflectRepeatedRef<'a>;
17    fn mut_repeated<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectRepeatedMut<'a>;
18    fn _element_type(&self) -> RuntimeType;
19}
20
21pub(crate) struct RepeatedFieldAccessorHolder {
22    pub accessor: Box<dyn RepeatedFieldAccessor>,
23}
24
25impl<'a> fmt::Debug for RepeatedFieldAccessorHolder {
26    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27        f.debug_struct("RepeatedFieldAccessorHolder").finish()
28    }
29}
30
31trait RepeatedFieldGetMut<M, R: ?Sized>: Send + Sync + 'static
32where
33    M: MessageFull + 'static,
34{
35    fn get_field<'a>(&self, message: &'a M) -> &'a R;
36    fn mut_field<'a>(&self, message: &'a mut M) -> &'a mut R;
37}
38
39struct RepeatedFieldGetMutImpl<M, L>
40where
41    M: MessageFull + 'static,
42{
43    get_field: for<'a> fn(&'a M) -> &'a L,
44    mut_field: for<'a> fn(&'a mut M) -> &'a mut L,
45}
46
47impl<M, V> RepeatedFieldGetMut<M, dyn ReflectRepeated> for RepeatedFieldGetMutImpl<M, Vec<V>>
48where
49    M: MessageFull + 'static,
50    V: ProtobufValue,
51{
52    fn get_field<'a>(&self, m: &'a M) -> &'a dyn ReflectRepeated {
53        (self.get_field)(m) as &dyn ReflectRepeated
54    }
55
56    fn mut_field<'a>(&self, m: &'a mut M) -> &'a mut dyn ReflectRepeated {
57        (self.mut_field)(m) as &mut dyn ReflectRepeated
58    }
59}
60
61struct RepeatedFieldAccessorImpl<M, V>
62where
63    M: MessageFull,
64    V: ProtobufValue,
65{
66    fns: Box<dyn RepeatedFieldGetMut<M, dyn ReflectRepeated>>,
67    _marker: marker::PhantomData<V>,
68}
69
70impl<M, V> RepeatedFieldAccessor for RepeatedFieldAccessorImpl<M, V>
71where
72    M: MessageFull,
73    V: ProtobufValue,
74{
75    fn get_repeated<'a>(&self, m: &'a dyn MessageDyn) -> ReflectRepeatedRef<'a> {
76        let m = m.downcast_ref().unwrap();
77        let repeated = self.fns.get_field(m);
78        ReflectRepeatedRef::new(repeated)
79    }
80
81    fn mut_repeated<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectRepeatedMut<'a> {
82        let m = m.downcast_mut().unwrap();
83        let repeated = self.fns.mut_field(m);
84        ReflectRepeatedMut::new(repeated)
85    }
86
87    fn _element_type(&self) -> RuntimeType {
88        V::RuntimeType::runtime_type_box()
89    }
90}
91
92/// Make accessor for `Vec` field
93pub fn make_vec_simpler_accessor<M, V>(
94    name: &'static str,
95    get_vec: for<'a> fn(&'a M) -> &'a Vec<V>,
96    mut_vec: for<'a> fn(&'a mut M) -> &'a mut Vec<V>,
97) -> FieldAccessor
98where
99    M: MessageFull + 'static,
100    V: ProtobufValue,
101{
102    FieldAccessor::new(
103        name,
104        AccessorV2::Repeated(RepeatedFieldAccessorHolder {
105            accessor: Box::new(RepeatedFieldAccessorImpl::<M, V> {
106                fns: Box::new(RepeatedFieldGetMutImpl::<M, Vec<V>> {
107                    get_field: get_vec,
108                    mut_field: mut_vec,
109                }),
110                _marker: marker::PhantomData::<V>,
111            }),
112        }),
113    )
114}