1 use crate::descriptor::DescriptorProto;
2 use crate::descriptor::EnumDescriptorProto;
3 use crate::descriptor::FileDescriptorProto;
4
5 pub(crate) enum MessageOrEnum<'a> {
6 Message(&'a DescriptorProto),
7 Enum(&'a EnumDescriptorProto),
8 }
9
10 impl<'a> MessageOrEnum<'a> {
from_two_options( m: Option<&'a DescriptorProto>, e: Option<&'a EnumDescriptorProto>, ) -> MessageOrEnum<'a>11 fn from_two_options(
12 m: Option<&'a DescriptorProto>,
13 e: Option<&'a EnumDescriptorProto>,
14 ) -> MessageOrEnum<'a> {
15 match (m, e) {
16 (Some(_), Some(_)) => panic!("enum and message with the same name"),
17 (Some(m), None) => MessageOrEnum::Message(m),
18 (None, Some(e)) => MessageOrEnum::Enum(e),
19 (None, None) => panic!("not found"),
20 }
21 }
22 }
23
find_message_or_enum<'a>( file: &'a FileDescriptorProto, name_to_package: &str, ) -> (String, MessageOrEnum<'a>)24 pub(crate) fn find_message_or_enum<'a>(
25 file: &'a FileDescriptorProto,
26 name_to_package: &str,
27 ) -> (String, MessageOrEnum<'a>) {
28 let mut path = name_to_package.split('.');
29 let first = path.next().unwrap();
30 let child_message = file
31 .get_message_type()
32 .iter()
33 .find(|m| m.get_name() == first);
34 let child_enum = file.get_enum_type().iter().find(|e| e.get_name() == first);
35
36 let mut package_to_name = String::new();
37 let mut me = MessageOrEnum::from_two_options(child_message, child_enum);
38
39 for name in path {
40 let message = match me {
41 MessageOrEnum::Message(m) => m,
42 MessageOrEnum::Enum(_) => panic!("enum has no children"),
43 };
44
45 if !package_to_name.is_empty() {
46 package_to_name.push_str(".");
47 }
48 package_to_name.push_str(message.get_name());
49
50 let child_message = message
51 .get_nested_type()
52 .iter()
53 .find(|m| m.get_name() == name);
54 let child_enum = message
55 .get_enum_type()
56 .iter()
57 .find(|e| e.get_name() == name);
58 me = MessageOrEnum::from_two_options(child_message, child_enum)
59 }
60
61 (package_to_name, me)
62 }
63