protobuf/reflect/optional/
mod.rs

1use crate::reflect::runtime_types::RuntimeTypeTrait;
2use crate::reflect::ProtobufValue;
3use crate::reflect::ReflectEq;
4use crate::reflect::ReflectEqMode;
5use crate::reflect::ReflectValueRef;
6use crate::reflect::RuntimeType;
7
8enum Impl<'a> {
9    None(RuntimeType),
10    Some(ReflectValueRef<'a>),
11}
12
13/// Singular field field and value type.
14pub struct ReflectOptionalRef<'a>(Impl<'a>);
15
16impl<'a> PartialEq for ReflectOptionalRef<'a> {
17    fn eq(&self, other: &Self) -> bool {
18        self.reflect_eq(other, &ReflectEqMode::default())
19    }
20}
21
22impl<'a> ReflectEq for ReflectOptionalRef<'a> {
23    fn reflect_eq(&self, that: &Self, mode: &ReflectEqMode) -> bool {
24        match (&self.0, &that.0) {
25            (Impl::None(at), Impl::None(bt)) => at == bt,
26            (Impl::Some(a), Impl::Some(b)) => a.reflect_eq(b, mode),
27            (Impl::None(_), Impl::Some(_)) | (Impl::Some(_), Impl::None(_)) => false,
28        }
29    }
30}
31
32impl<'a> ReflectOptionalRef<'a> {
33    /// No value.
34    pub fn none(elem: RuntimeType) -> ReflectOptionalRef<'a> {
35        ReflectOptionalRef(Impl::None(elem))
36    }
37
38    /// Has value.
39    pub fn some(value: ReflectValueRef<'a>) -> ReflectOptionalRef<'a> {
40        ReflectOptionalRef(Impl::Some(value))
41    }
42
43    pub(crate) fn none_from<V: ProtobufValue>() -> ReflectOptionalRef<'a> {
44        ReflectOptionalRef::none(V::RuntimeType::runtime_type_box())
45    }
46
47    pub(crate) fn some_from<V: ProtobufValue>(value: &'a V) -> ReflectOptionalRef<'a> {
48        ReflectOptionalRef::some(V::RuntimeType::as_ref(value))
49    }
50
51    pub(crate) fn new_filter_non_zero<V: ProtobufValue>(v: &'a V) -> ReflectOptionalRef<'a> {
52        if V::RuntimeType::is_non_zero(v) {
53            ReflectOptionalRef::some_from(v)
54        } else {
55            ReflectOptionalRef::none_from::<V>()
56        }
57    }
58
59    pub(crate) fn new_from_option<V: ProtobufValue>(v: Option<&'a V>) -> ReflectOptionalRef<'a> {
60        if let Some(v) = v {
61            ReflectOptionalRef::some_from(v)
62        } else {
63            ReflectOptionalRef::none_from::<V>()
64        }
65    }
66
67    /// Obtain the value, drop the type.
68    pub fn value(&self) -> Option<ReflectValueRef<'a>> {
69        match &self.0 {
70            Impl::None(_) => None,
71            Impl::Some(v) => Some(v.clone()),
72        }
73    }
74}