• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 use crate::__internal::Private;
9 use std::{
10     error::Error,
11     fmt::{Debug, Display},
12     marker::PhantomData,
13 };
14 
15 /// Implemented by all generated enum types.
16 ///
17 /// # Safety
18 /// - A `RepeatedView<Self>` or `RepeatedMut<Self>` must have the same internal
19 ///   representation as erased enums in the runtime.
20 ///   - For C++, this is `proto2::RepeatedField<c_int>`
21 ///   - For UPB, this is an array compatible with `int32`
22 pub unsafe trait Enum: TryFrom<i32> {
23     /// The name of the enum.
24     const NAME: &'static str;
25 
26     /// Returns `true` if the given numeric value matches one of the `Self`'s
27     /// defined values.
28     ///
29     /// If `Self` is a closed enum, then `TryFrom<i32>` for `value` succeeds if
30     /// and only if this function returns `true`.
is_known(value: i32) -> bool31     fn is_known(value: i32) -> bool;
32 }
33 
34 /// An integer value wasn't known for an enum while converting.
35 pub struct UnknownEnumValue<T>(i32, PhantomData<T>);
36 
37 impl<T> UnknownEnumValue<T> {
38     #[doc(hidden)]
new(_private: Private, unknown_value: i32) -> Self39     pub fn new(_private: Private, unknown_value: i32) -> Self {
40         Self(unknown_value, PhantomData)
41     }
42 }
43 
44 impl<T> Debug for UnknownEnumValue<T> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result45     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46         f.debug_tuple("UnknownEnumValue").field(&self.0).finish()
47     }
48 }
49 
50 impl<T: Enum> Display for UnknownEnumValue<T> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result51     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52         let val = self.0;
53         let enum_name = T::NAME;
54         write!(f, "{val} is not a known value for {enum_name}")
55     }
56 }
57 
58 impl<T: Enum> Error for UnknownEnumValue<T> {}
59