// Protocol Buffers - Google's data interchange format // Copyright 2023 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //! Items specific to `optional` fields. #![allow(dead_code)] #![allow(unused)] use crate::__internal::Private; use crate::{Mut, MutProxy, Proxied, SettableValue, View, ViewProxy}; use std::convert::{AsMut, AsRef}; use std::fmt::{self, Debug}; /// The type that will go here is not yet defined. pub type Todo = (std::marker::PhantomData, std::convert::Infallible); /// A protobuf value from a field that may not be set. /// /// This can be pattern matched with `match` or `if let` to determine if the /// field is set and access the field data. /// /// [`FieldEntry`], a specific type alias for `Optional`, provides much of the /// functionality for this type. /// /// Two `Optional`s are equal if they match both presence and the field values. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Optional { /// The field is present. It can be accessed through this `T`. /// /// - For an `_opt()` accessor, this contains a `View`. /// - For a `_mut()` accessor, this contains a [`PresentField`]. Set(SetVal), /// The field is unset. /// /// - For an `_opt()` accessor, this contains a `View` with /// the default value. /// - For a `_mut()` accessor, this contains an [`AbsentField`] that can be /// used to access the default or set a new value. Unset(UnsetVal), } impl Optional { /// Gets the field value, ignoring whether it was set or not. pub fn into_inner(self) -> T { match self { Optional::Set(x) | Optional::Unset(x) => x, } } } impl Optional { /// Converts into an `Option` of the set value, ignoring any unset value. pub fn into_option(self) -> Option { if let Optional::Set(x) = self { Some(x) } else { None } } /// Returns if the field is set. pub fn is_set(&self) -> bool { matches!(self, Optional::Set(_)) } /// Returns if the field is unset. pub fn is_unset(&self) -> bool { matches!(self, Optional::Unset(_)) } } impl From> for Option { fn from(x: Optional) -> Option { x.into_option() } } /// A mutable view into the value of an optional field, which may be set or /// unset. pub type FieldEntry<'a, T> = Optional, AbsentField<'a, T>>; /// Methods for `_mut()` accessors of optional types. /// /// The most common methods are [`set`] and [`or_default`]. impl<'msg, T: Proxied + ?Sized + 'msg> FieldEntry<'msg, T> { // is_set() is provided by `impl Optional` /// Gets a mutator for this field. Sets to the default value if not set. pub fn or_default(self) -> Mut<'msg, T> { match self { Optional::Set(x) => x.into_mut(), Optional::Unset(x) => x.set_default().into_mut(), } } /// Sets the value of this field to `val`. /// /// Equivalent to `self.or_default().set(val)`. pub fn set(&mut self, val: impl SettableValue) { match self { Optional::Set(x) => x.set(val), Optional::Unset(x) => todo!(), } } /// Clears the field; `is_set()` will return `false`. pub fn clear(&mut self) { todo!("b/285308646: Requires a trait method") } /// Gets an immutable view of this field, using its default value if not /// set. /// /// This has a shorter lifetime than the `field_name()` message accessor; /// `into_view` provides that lifetime. pub fn get(self) -> View<'msg, T> { self.into_view() } } impl<'msg, T: Proxied + ?Sized + 'msg> ViewProxy<'msg> for FieldEntry<'msg, T> { type Proxied = T; fn as_view(&self) -> View<'_, T> { match self { Optional::Set(x) => x.as_view(), Optional::Unset(x) => x.as_view(), } } fn into_view<'shorter>(self) -> View<'shorter, T> where 'msg: 'shorter, { match self { Optional::Set(x) => x.into_view(), Optional::Unset(x) => x.into_view(), } } } // `MutProxy` not implemented for `FieldEntry` since the field may not be set, // and `as_mut`/`into_mut` should not insert. /// A field mutator capable of clearing that is statically known to point to a /// set field. pub struct PresentField<'msg, T> where T: Proxied + ?Sized + 'msg, { inner: Todo>, } impl<'msg, T: Proxied + ?Sized + 'msg> Debug for PresentField<'msg, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { todo!() } } impl<'msg, T: Proxied + ?Sized + 'msg> PresentField<'msg, T> { pub fn get(self) -> View<'msg, T> { self.into_view() } pub fn set(&mut self, val: impl SettableValue) { val.set_on(Private, self.as_mut()) } /// See [`FieldEntry::clear`]. pub fn clear(self) -> AbsentField<'msg, T> { todo!("b/285308646: Requires a trait method") } // This cannot provide `reborrow` - `clear` consumes after setting the field // because it would violate a condition of `PresentField` - the field being set. } impl<'msg, T> ViewProxy<'msg> for PresentField<'msg, T> where T: Proxied + ?Sized + 'msg, { type Proxied = T; fn as_view(&self) -> View<'_, T> { todo!("b/285308646: Requires a trait method") } fn into_view<'shorter>(self) -> View<'shorter, T> where 'msg: 'shorter, { todo!("b/285308646: Requires a trait method") } } impl<'msg, T> MutProxy<'msg> for PresentField<'msg, T> where T: Proxied + ?Sized + 'msg, { fn as_mut(&mut self) -> Mut<'_, T> { todo!("b/285308646: Requires a trait method") } fn into_mut<'shorter>(self) -> Mut<'shorter, T> where 'msg: 'shorter, { todo!("b/285308646: Requires a trait method") } } /// A field mutator capable of setting that is statically known to point to a /// non-set field. pub struct AbsentField<'a, T> where T: Proxied + ?Sized + 'a, { inner: Todo>>, } impl<'msg, T: Proxied + ?Sized + 'msg> Debug for AbsentField<'msg, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { todo!() } } impl<'msg, T: Proxied + ?Sized> AbsentField<'msg, T> { /// Gets the default value for this unset field. /// /// This is the same value that the primitive accessor would provide. pub fn default_value(self) -> View<'msg, T> { self.into_view() } /// See [`FieldEntry::set`]. Note that this consumes and returns a /// `PresentField`. pub fn set(self, val: impl SettableValue) -> PresentField<'msg, T> { todo!("b/285308646: Requires a trait method") } /// Sets this absent field to its default value. pub fn set_default(self) -> PresentField<'msg, T> { todo!("b/285308646: Requires a trait method") } // This cannot provide `reborrow` - `set` consumes after setting the field // because it would violate a condition of `AbsentField` - the field being // unset. } impl<'msg, T> ViewProxy<'msg> for AbsentField<'msg, T> where T: Proxied + ?Sized + 'msg, { type Proxied = T; fn as_view(&self) -> View<'_, T> { todo!("b/285308646: Requires a trait method") } fn into_view<'shorter>(self) -> View<'shorter, T> where 'msg: 'shorter, { todo!("b/285308646: Requires a trait method") } }