Skip to main content

buffa_reflect/
enumeration.rs

1//! [`EnumDescriptor`] and [`EnumValueDescriptor`].
2
3use buffa_descriptor::generated::descriptor::EnumDescriptorProto;
4
5use crate::{
6    file::FileDescriptor,
7    message::MessageDescriptor,
8    pool::{DescriptorPool, EnumIndex},
9};
10
11/// Handle to one enum declaration in a [`DescriptorPool`].
12#[derive(Clone, Debug)]
13pub struct EnumDescriptor {
14    pub(crate) pool: DescriptorPool,
15    pub(crate) index: EnumIndex,
16}
17
18impl EnumDescriptor {
19    fn entry(&self) -> &crate::pool::EnumEntry {
20        &self.pool.inner.enums[self.index as usize]
21    }
22
23    /// Fully-qualified name (`<package>.<...>.<EnumName>`, no leading dot).
24    #[must_use]
25    pub fn full_name(&self) -> &str {
26        &self.entry().full_name
27    }
28
29    /// Leaf name.
30    #[must_use]
31    pub fn name(&self) -> &str {
32        &self.entry().name
33    }
34
35    /// Owning file.
36    #[must_use]
37    pub fn parent_file(&self) -> FileDescriptor {
38        FileDescriptor {
39            pool: self.pool.clone(),
40            index: self.entry().file,
41        }
42    }
43
44    /// Containing message, when this enum is nested.
45    #[must_use]
46    pub fn parent_message(&self) -> Option<MessageDescriptor> {
47        self.entry().parent.map(|idx| MessageDescriptor {
48            pool: self.pool.clone(),
49            index: idx,
50        })
51    }
52
53    /// Iterate over the declared variants.
54    pub fn values(&self) -> impl ExactSizeIterator<Item = EnumValueDescriptor> + '_ {
55        let pool = self.pool.clone();
56        let owner = self.index;
57        let len = self.entry().values.len() as u32;
58        (0..len).map(move |vi| EnumValueDescriptor {
59            pool: pool.clone(),
60            owner,
61            index: vi,
62        })
63    }
64
65    /// Lookup a variant by its proto name.
66    #[must_use]
67    pub fn get_value_by_name(&self, name: &str) -> Option<EnumValueDescriptor> {
68        let entry = self.entry();
69        entry.by_name.get(name).map(|vi| EnumValueDescriptor {
70            pool: self.pool.clone(),
71            owner: self.index,
72            index: *vi,
73        })
74    }
75
76    /// Lookup a variant by its number.
77    #[must_use]
78    pub fn get_value_by_number(&self, number: i32) -> Option<EnumValueDescriptor> {
79        let entry = self.entry();
80        entry.by_number.get(&number).map(|vi| EnumValueDescriptor {
81            pool: self.pool.clone(),
82            owner: self.index,
83            index: *vi,
84        })
85    }
86
87    /// Raw [`EnumDescriptorProto`] for advanced use.
88    #[must_use]
89    pub fn descriptor_proto(&self) -> &EnumDescriptorProto {
90        let entry = self.entry();
91        let file = &self.pool.inner.files[entry.file as usize];
92        crate::pool_build::resolve_enum_proto(&file.proto, &entry.proto_path)
93    }
94}
95
96impl PartialEq for EnumDescriptor {
97    fn eq(&self, other: &Self) -> bool {
98        std::sync::Arc::ptr_eq(&self.pool.inner, &other.pool.inner) && self.index == other.index
99    }
100}
101
102impl Eq for EnumDescriptor {}
103
104/// Handle to one variant of an [`EnumDescriptor`].
105#[derive(Clone, Debug)]
106pub struct EnumValueDescriptor {
107    pub(crate) pool: DescriptorPool,
108    pub(crate) owner: EnumIndex,
109    pub(crate) index: u32,
110}
111
112impl EnumValueDescriptor {
113    fn entry(&self) -> &crate::pool::EnumValueEntry {
114        &self.pool.inner.enums[self.owner as usize].values[self.index as usize]
115    }
116
117    /// Variant name as written in the .proto.
118    #[must_use]
119    pub fn name(&self) -> &str {
120        &self.entry().name
121    }
122
123    /// `<enum.full_name>.<variant>`, no leading dot.
124    #[must_use]
125    pub fn full_name(&self) -> &str {
126        &self.entry().full_name
127    }
128
129    /// Numeric value of the variant.
130    #[must_use]
131    pub fn number(&self) -> i32 {
132        self.entry().number
133    }
134
135    /// Owning enum.
136    #[must_use]
137    pub fn parent_enum(&self) -> EnumDescriptor {
138        EnumDescriptor {
139            pool: self.pool.clone(),
140            index: self.owner,
141        }
142    }
143}
144
145impl PartialEq for EnumValueDescriptor {
146    fn eq(&self, other: &Self) -> bool {
147        std::sync::Arc::ptr_eq(&self.pool.inner, &other.pool.inner)
148            && self.owner == other.owner
149            && self.index == other.index
150    }
151}
152
153impl Eq for EnumValueDescriptor {}