use crate::reflect::runtime_types::RuntimeTypeTrait; use crate::reflect::ProtobufValue; use crate::reflect::ReflectEq; use crate::reflect::ReflectEqMode; use crate::reflect::ReflectValueRef; use crate::reflect::RuntimeType; enum Impl<'a> { None(RuntimeType), Some(ReflectValueRef<'a>), } /// Singular field field and value type. pub struct ReflectOptionalRef<'a>(Impl<'a>); impl<'a> PartialEq for ReflectOptionalRef<'a> { fn eq(&self, other: &Self) -> bool { self.reflect_eq(other, &ReflectEqMode::default()) } } impl<'a> ReflectEq for ReflectOptionalRef<'a> { fn reflect_eq(&self, that: &Self, mode: &ReflectEqMode) -> bool { match (&self.0, &that.0) { (Impl::None(at), Impl::None(bt)) => at == bt, (Impl::Some(a), Impl::Some(b)) => a.reflect_eq(b, mode), (Impl::None(_), Impl::Some(_)) | (Impl::Some(_), Impl::None(_)) => false, } } } impl<'a> ReflectOptionalRef<'a> { /// No value. pub fn none(elem: RuntimeType) -> ReflectOptionalRef<'a> { ReflectOptionalRef(Impl::None(elem)) } /// Has value. pub fn some(value: ReflectValueRef<'a>) -> ReflectOptionalRef<'a> { ReflectOptionalRef(Impl::Some(value)) } pub(crate) fn none_from() -> ReflectOptionalRef<'a> { ReflectOptionalRef::none(V::RuntimeType::runtime_type_box()) } pub(crate) fn some_from(value: &'a V) -> ReflectOptionalRef<'a> { ReflectOptionalRef::some(V::RuntimeType::as_ref(value)) } pub(crate) fn new_filter_non_zero(v: &'a V) -> ReflectOptionalRef<'a> { if V::RuntimeType::is_non_zero(v) { ReflectOptionalRef::some_from(v) } else { ReflectOptionalRef::none_from::() } } pub(crate) fn new_from_option(v: Option<&'a V>) -> ReflectOptionalRef<'a> { if let Some(v) = v { ReflectOptionalRef::some_from(v) } else { ReflectOptionalRef::none_from::() } } /// Obtain the value, drop the type. pub fn value(&self) -> Option> { match &self.0 { Impl::None(_) => None, Impl::Some(v) => Some(v.clone()), } } }