protobuf/reflect/acc/v2/singular/
mod.rs

1use std::fmt;
2use std::marker;
3
4use crate::message_dyn::MessageDyn;
5use crate::message_field::MessageField;
6use crate::message_full::MessageFull;
7use crate::reflect::acc::v2::AccessorV2;
8use crate::reflect::acc::FieldAccessor;
9use crate::reflect::runtime_types::RuntimeTypeTrait;
10use crate::reflect::runtime_types::RuntimeTypeWithDeref;
11use crate::reflect::value::value_ref::ReflectValueMut;
12use crate::reflect::ProtobufValue;
13use crate::reflect::ReflectOptionalRef;
14use crate::reflect::ReflectValueBox;
15use crate::reflect::ReflectValueRef;
16use crate::EnumFull;
17use crate::EnumOrUnknown;
18
19pub(crate) mod oneof;
20
21/// This trait should not be used directly, use `FieldDescriptor` instead
22pub(crate) trait SingularFieldAccessor: Send + Sync + 'static {
23    fn get_field<'a>(&self, m: &'a dyn MessageDyn) -> ReflectOptionalRef<'a>;
24    fn mut_field_or_default<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectValueMut<'a>;
25    fn set_field(&self, m: &mut dyn MessageDyn, value: ReflectValueBox);
26    fn clear_field(&self, m: &mut dyn MessageDyn);
27}
28
29pub(crate) struct SingularFieldAccessorHolder {
30    pub accessor: Box<dyn SingularFieldAccessor>,
31}
32
33impl SingularFieldAccessorHolder {
34    fn new<M>(
35        get_field: impl for<'a> Fn(&'a M) -> ReflectOptionalRef<'a> + Send + Sync + 'static,
36        mut_field_or_default: impl for<'a> Fn(&'a mut M) -> ReflectValueMut<'a> + Send + Sync + 'static,
37        set_field: impl Fn(&mut M, ReflectValueBox) + Send + Sync + 'static,
38        clear_field: impl Fn(&mut M) + Send + Sync + 'static,
39    ) -> SingularFieldAccessorHolder
40    where
41        M: MessageFull,
42    {
43        struct Impl<M, G, H, S, C> {
44            get_field: G,
45            mut_field_or_default: H,
46            set_field: S,
47            clear_field: C,
48            _marker: marker::PhantomData<M>,
49        }
50
51        impl<M, G, H, S, C> SingularFieldAccessor for Impl<M, G, H, S, C>
52        where
53            M: MessageFull,
54            G: for<'a> Fn(&'a M) -> ReflectOptionalRef<'a> + Send + Sync + 'static,
55            H: for<'a> Fn(&'a mut M) -> ReflectValueMut<'a> + Send + Sync + 'static,
56            S: Fn(&mut M, ReflectValueBox) + Send + Sync + 'static,
57            C: Fn(&mut M) + Send + Sync + 'static,
58        {
59            fn get_field<'a>(&self, m: &'a dyn MessageDyn) -> ReflectOptionalRef<'a> {
60                (self.get_field)(m.downcast_ref::<M>().unwrap())
61            }
62
63            fn mut_field_or_default<'a>(&self, m: &'a mut dyn MessageDyn) -> ReflectValueMut<'a> {
64                (self.mut_field_or_default)(m.downcast_mut::<M>().unwrap())
65            }
66
67            fn set_field(&self, m: &mut dyn MessageDyn, value: ReflectValueBox) {
68                (self.set_field)(m.downcast_mut::<M>().unwrap(), value);
69            }
70
71            fn clear_field(&self, m: &mut dyn MessageDyn) {
72                (self.clear_field)(m.downcast_mut::<M>().unwrap());
73            }
74        }
75
76        SingularFieldAccessorHolder {
77            accessor: Box::new(Impl {
78                get_field,
79                mut_field_or_default,
80                set_field,
81                clear_field,
82                _marker: marker::PhantomData,
83            }),
84        }
85    }
86
87    fn new_get_mut<M, V>(
88        get_field: for<'a> fn(&'a M) -> &'a V,
89        mut_field: for<'a> fn(&'a mut M) -> &'a mut V,
90    ) -> SingularFieldAccessorHolder
91    where
92        M: MessageFull,
93        V: ProtobufValue,
94    {
95        Self::new(
96            move |m| {
97                let v = (get_field)(m);
98                ReflectOptionalRef::new_filter_non_zero(v)
99            },
100            move |m| V::RuntimeType::as_mut((mut_field)(m)),
101            move |m, value| V::RuntimeType::set_from_value_box((mut_field)(m), value),
102            move |m| {
103                let default_value = V::RuntimeType::default_value_ref().to_box();
104                V::RuntimeType::set_from_value_box((mut_field)(m), default_value);
105            },
106        )
107    }
108
109    fn new_get_option_mut_option<M, V>(
110        get_field: for<'a> fn(&'a M) -> &'a Option<V>,
111        mut_field: for<'a> fn(&'a mut M) -> &'a mut Option<V>,
112    ) -> SingularFieldAccessorHolder
113    where
114        M: MessageFull,
115        V: ProtobufValue,
116    {
117        Self::new(
118            move |m| ReflectOptionalRef::new_from_option((get_field)(m).as_ref()),
119            move |_m| unimplemented!(),
120            move |m, value| {
121                *(mut_field)(m) = Some(V::RuntimeType::from_value_box(value).expect("wrong type"))
122            },
123            move |m| *(mut_field)(m) = None,
124        )
125    }
126
127    fn new_get_mut_message<M, V>(
128        get_field: for<'a> fn(&'a M) -> &'a MessageField<V>,
129        mut_field: for<'a> fn(&'a mut M) -> &'a mut MessageField<V>,
130    ) -> SingularFieldAccessorHolder
131    where
132        M: MessageFull,
133        V: MessageFull,
134    {
135        Self::new(
136            move |m| ReflectOptionalRef::new_from_option((get_field)(m).as_ref()),
137            move |m| {
138                let option = (mut_field)(m);
139                if option.as_ref().is_none() {
140                    *option = MessageField::some(V::default());
141                }
142                V::RuntimeType::as_mut(option.as_mut().unwrap())
143            },
144            move |m, value| {
145                *(mut_field)(m) =
146                    MessageField::some(V::RuntimeType::from_value_box(value).expect("wrong type"))
147            },
148            move |m| {
149                *(mut_field)(m) = MessageField::none();
150            },
151        )
152    }
153
154    pub(crate) fn new_get_option_set_enum<M, E>(
155        get: fn(&M) -> Option<EnumOrUnknown<E>>,
156        set: fn(&mut M, EnumOrUnknown<E>),
157    ) -> SingularFieldAccessorHolder
158    where
159        M: MessageFull,
160        E: EnumFull,
161    {
162        Self::new(
163            move |m| {
164                let value = (get)(m);
165                match value {
166                    Some(v) => ReflectOptionalRef::some(ReflectValueRef::Enum(
167                        E::enum_descriptor(),
168                        v.value(),
169                    )),
170                    None => ReflectOptionalRef::none_from::<EnumOrUnknown<E>>(),
171                }
172            },
173            |_m| panic!("cannot get mutable pointer"),
174            move |m, value| match value {
175                ReflectValueBox::Enum(e, v) => {
176                    assert_eq!(E::enum_descriptor(), e);
177                    (set)(m, EnumOrUnknown::from_i32(v));
178                }
179                _ => panic!("expecting enum value"),
180            },
181            move |m| {
182                (set)(m, EnumOrUnknown::from_i32(0));
183            },
184        )
185    }
186
187    pub(crate) fn new_has_get_set<M, V>(
188        has: fn(&M) -> bool,
189        get: fn(&M) -> V,
190        set: fn(&mut M, V),
191    ) -> SingularFieldAccessorHolder
192    where
193        M: MessageFull,
194        V: ProtobufValue + Copy,
195    {
196        Self::new(
197            move |m| {
198                if (has)(m) {
199                    ReflectOptionalRef::some(V::RuntimeType::into_static_value_ref((get)(m)))
200                } else {
201                    ReflectOptionalRef::none_from::<V>()
202                }
203            },
204            |_m| unimplemented!(),
205            move |m, value| (set)(m, value.downcast::<V>().expect("wrong type")),
206            move |m| {
207                if (has)(m) {
208                    (set)(m, V::default());
209                }
210            },
211        )
212    }
213
214    pub(crate) fn new_has_get_set_deref<M, V>(
215        has: fn(&M) -> bool,
216        get: for<'a> fn(&'a M) -> &'a <V::RuntimeType as RuntimeTypeWithDeref>::DerefTarget,
217        set: fn(&mut M, V),
218    ) -> SingularFieldAccessorHolder
219    where
220        M: MessageFull,
221        V: ProtobufValue,
222        V::RuntimeType: RuntimeTypeWithDeref,
223    {
224        Self::new(
225            move |m| {
226                if (has)(m) {
227                    ReflectOptionalRef::some(
228                        <V::RuntimeType as RuntimeTypeWithDeref>::deref_as_ref((get)(m)),
229                    )
230                } else {
231                    ReflectOptionalRef::none_from::<V>()
232                }
233            },
234            |_m| unimplemented!(),
235            move |m, value| (set)(m, value.downcast::<V>().expect("message")),
236            move |m| {
237                if (has)(m) {
238                    (set)(m, V::default());
239                }
240            },
241        )
242    }
243
244    pub(crate) fn new_has_get_mut_set<M, F>(
245        has_field: fn(&M) -> bool,
246        get_field: for<'a> fn(&'a M) -> &'a F,
247        mut_field: for<'a> fn(&'a mut M) -> &'a mut F,
248        set_field: fn(&mut M, F),
249    ) -> SingularFieldAccessorHolder
250    where
251        M: MessageFull,
252        F: MessageFull,
253    {
254        Self::new(
255            move |m| {
256                if (has_field)(m) {
257                    ReflectOptionalRef::some(F::RuntimeType::as_ref((get_field)(m)))
258                } else {
259                    ReflectOptionalRef::none_from::<F>()
260                }
261            },
262            move |m| F::RuntimeType::as_mut((mut_field)(m)),
263            move |m, value| (set_field)(m, value.downcast::<F>().expect("message")),
264            move |m| {
265                if (has_field)(m) {
266                    (set_field)(m, F::default());
267                }
268            },
269        )
270    }
271}
272
273impl<'a> fmt::Debug for SingularFieldAccessorHolder {
274    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
275        f.debug_struct("SingularFieldAccessorHolder").finish()
276    }
277}
278
279/// Make accessor for `SingularPtrField`
280pub fn make_message_field_accessor<M, V>(
281    name: &'static str,
282    get_field: for<'a> fn(&'a M) -> &'a MessageField<V>,
283    mut_field: for<'a> fn(&'a mut M) -> &'a mut MessageField<V>,
284) -> FieldAccessor
285where
286    M: MessageFull,
287    V: MessageFull,
288{
289    FieldAccessor::new(
290        name,
291        AccessorV2::Singular(SingularFieldAccessorHolder::new_get_mut_message(
292            get_field, mut_field,
293        )),
294    )
295}
296
297/// Make accessor for `Option<C>` field
298pub fn make_option_accessor<M, V>(
299    name: &'static str,
300    get_field: for<'a> fn(&'a M) -> &'a Option<V>,
301    mut_field: for<'a> fn(&'a mut M) -> &'a mut Option<V>,
302) -> FieldAccessor
303where
304    M: MessageFull,
305    V: ProtobufValue,
306{
307    FieldAccessor::new(
308        name,
309        AccessorV2::Singular(SingularFieldAccessorHolder::new_get_option_mut_option(
310            get_field, mut_field,
311        )),
312    )
313}
314
315/// Make accessor for simple field
316pub fn make_simpler_field_accessor<M, V>(
317    name: &'static str,
318    get_field: for<'a> fn(&'a M) -> &'a V,
319    mut_field: for<'a> fn(&'a mut M) -> &'a mut V,
320) -> FieldAccessor
321where
322    M: MessageFull,
323    V: ProtobufValue,
324{
325    FieldAccessor::new(
326        name,
327        AccessorV2::Singular(SingularFieldAccessorHolder::new_get_mut(
328            get_field, mut_field,
329        )),
330    )
331}