blob: 7ee39159b1bb95cd11c65ca32508a708489e2f7a [file] [log] [blame]
use crate::descriptor::DescriptorProto;
use crate::descriptor::EnumDescriptorProto;
use crate::descriptor::FileDescriptorProto;
pub(crate) enum MessageOrEnum<'a> {
Message(&'a DescriptorProto),
Enum(&'a EnumDescriptorProto),
}
impl<'a> MessageOrEnum<'a> {
fn from_two_options(
m: Option<&'a DescriptorProto>,
e: Option<&'a EnumDescriptorProto>,
) -> MessageOrEnum<'a> {
match (m, e) {
(Some(_), Some(_)) => panic!("enum and message with the same name"),
(Some(m), None) => MessageOrEnum::Message(m),
(None, Some(e)) => MessageOrEnum::Enum(e),
(None, None) => panic!("not found"),
}
}
}
pub(crate) fn find_message_or_enum<'a>(
file: &'a FileDescriptorProto,
name_to_package: &str,
) -> (String, MessageOrEnum<'a>) {
let mut path = name_to_package.split('.');
let first = path.next().unwrap();
let child_message = file
.get_message_type()
.iter()
.find(|m| m.get_name() == first);
let child_enum = file.get_enum_type().iter().find(|e| e.get_name() == first);
let mut package_to_name = String::new();
let mut me = MessageOrEnum::from_two_options(child_message, child_enum);
for name in path {
let message = match me {
MessageOrEnum::Message(m) => m,
MessageOrEnum::Enum(_) => panic!("enum has no children"),
};
if !package_to_name.is_empty() {
package_to_name.push_str(".");
}
package_to_name.push_str(message.get_name());
let child_message = message
.get_nested_type()
.iter()
.find(|m| m.get_name() == name);
let child_enum = message
.get_enum_type()
.iter()
.find(|e| e.get_name() == name);
me = MessageOrEnum::from_two_options(child_message, child_enum)
}
(package_to_name, me)
}