protobuf/reflect/
enums.rs1use std::collections::HashMap;
2
3use crate::descriptor::EnumDescriptorProto;
4use crate::descriptor::EnumValueDescriptorProto;
5use crate::descriptor::FileDescriptorProto;
6use crate::descriptorx::find_enum_by_rust_name;
7use crate::reflect::find_message_or_enum::find_message_or_enum;
8use crate::reflect::find_message_or_enum::MessageOrEnum;
9use crate::ProtobufEnum;
10
11#[derive(Clone, Debug)]
15pub struct EnumValueDescriptor {
16 proto: &'static EnumValueDescriptorProto,
17}
18
19impl Copy for EnumValueDescriptor {}
20
21impl EnumValueDescriptor {
22 pub fn name(&self) -> &'static str {
24 self.proto.get_name()
25 }
26
27 pub fn value(&self) -> i32 {
29 self.proto.get_number()
30 }
31}
32
33pub struct EnumDescriptor {
37 proto: &'static EnumDescriptorProto,
38 values: Vec<EnumValueDescriptor>,
39
40 index_by_name: HashMap<String, usize>,
41 index_by_number: HashMap<i32, usize>,
42}
43
44impl EnumDescriptor {
45 pub fn name(&self) -> &'static str {
47 self.proto.get_name()
48 }
49
50 pub fn for_type<E: ProtobufEnum>() -> &'static EnumDescriptor {
52 E::enum_descriptor_static()
53 }
54
55 #[deprecated(
59 since = "2.12",
60 note = "Please regenerate .rs files from .proto files to use newer APIs"
61 )]
62 pub fn new(rust_name: &'static str, file: &'static FileDescriptorProto) -> EnumDescriptor {
63 let proto = find_enum_by_rust_name(file, rust_name);
64 let mut index_by_name = HashMap::new();
65 let mut index_by_number = HashMap::new();
66 for (i, v) in proto.en.get_value().iter().enumerate() {
67 index_by_number.insert(v.get_number(), i);
68 index_by_name.insert(v.get_name().to_string(), i);
69 }
70 EnumDescriptor {
71 proto: proto.en,
72 values: proto
73 .en
74 .get_value()
75 .iter()
76 .map(|v| EnumValueDescriptor { proto: v })
77 .collect(),
78 index_by_name: index_by_name,
79 index_by_number: index_by_number,
80 }
81 }
82
83 pub fn new_pb_name<E>(
87 name_in_file: &'static str,
88 file: &'static FileDescriptorProto,
89 ) -> EnumDescriptor
90 where
91 E: ProtobufEnum,
92 {
93 let (_path_to_package, proto) = match find_message_or_enum(file, name_in_file) {
94 (path_to_package, MessageOrEnum::Enum(e)) => (path_to_package, e),
95 (_, MessageOrEnum::Message(_)) => panic!("not an enum"),
96 };
97
98 let mut index_by_name = HashMap::new();
99 let mut index_by_number = HashMap::new();
100 for (i, v) in proto.get_value().iter().enumerate() {
101 index_by_number.insert(v.get_number(), i);
102 index_by_name.insert(v.get_name().to_string(), i);
103 }
104 EnumDescriptor {
105 proto,
106 values: proto
107 .get_value()
108 .iter()
109 .map(|v| EnumValueDescriptor { proto: v })
110 .collect(),
111 index_by_name: index_by_name,
112 index_by_number: index_by_number,
113 }
114 }
115
116 pub fn value_by_name<'a>(&'a self, name: &str) -> &'a EnumValueDescriptor {
118 let &index = self.index_by_name.get(&name.to_string()).unwrap();
120 &self.values[index]
121 }
122
123 pub fn value_by_number<'a>(&'a self, number: i32) -> &'a EnumValueDescriptor {
125 let &index = self.index_by_number.get(&number).unwrap();
126 &self.values[index]
127 }
128}