1 use crate::reflect::runtime_types::RuntimeTypeTrait; 2 use crate::reflect::ProtobufValue; 3 use crate::reflect::ReflectEq; 4 use crate::reflect::ReflectEqMode; 5 use crate::reflect::ReflectValueRef; 6 use crate::reflect::RuntimeType; 7 8 enum Impl<'a> { 9 None(RuntimeType), 10 Some(ReflectValueRef<'a>), 11 } 12 13 /// Singular field field and value type. 14 pub struct ReflectOptionalRef<'a>(Impl<'a>); 15 16 impl<'a> PartialEq for ReflectOptionalRef<'a> { eq(&self, other: &Self) -> bool17 fn eq(&self, other: &Self) -> bool { 18 self.reflect_eq(other, &ReflectEqMode::default()) 19 } 20 } 21 22 impl<'a> ReflectEq for ReflectOptionalRef<'a> { reflect_eq(&self, that: &Self, mode: &ReflectEqMode) -> bool23 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 32 impl<'a> ReflectOptionalRef<'a> { 33 /// No value. none(elem: RuntimeType) -> ReflectOptionalRef<'a>34 pub fn none(elem: RuntimeType) -> ReflectOptionalRef<'a> { 35 ReflectOptionalRef(Impl::None(elem)) 36 } 37 38 /// Has value. some(value: ReflectValueRef<'a>) -> ReflectOptionalRef<'a>39 pub fn some(value: ReflectValueRef<'a>) -> ReflectOptionalRef<'a> { 40 ReflectOptionalRef(Impl::Some(value)) 41 } 42 none_from<V: ProtobufValue>() -> ReflectOptionalRef<'a>43 pub(crate) fn none_from<V: ProtobufValue>() -> ReflectOptionalRef<'a> { 44 ReflectOptionalRef::none(V::RuntimeType::runtime_type_box()) 45 } 46 some_from<V: ProtobufValue>(value: &'a V) -> ReflectOptionalRef<'a>47 pub(crate) fn some_from<V: ProtobufValue>(value: &'a V) -> ReflectOptionalRef<'a> { 48 ReflectOptionalRef::some(V::RuntimeType::as_ref(value)) 49 } 50 new_filter_non_zero<V: ProtobufValue>(v: &'a V) -> ReflectOptionalRef<'a>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 new_from_option<V: ProtobufValue>(v: Option<&'a V>) -> ReflectOptionalRef<'a>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. value(&self) -> Option<ReflectValueRef<'a>>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 } 75