use std::option::Option;
use protobuf::descriptor;
pub trait ItemDescriptorGetter {
fn get_message_descriptor_proto(&self, name: &str) -> Option<&descriptor::DescriptorProto>;
fn get_enum_descriptor_proto(&self, name: &str) -> Option<&descriptor::EnumDescriptorProto>;
fn get_service_descriptor_proto(
&self,
name: &str,
) -> Option<&descriptor::ServiceDescriptorProto>;
}
impl ItemDescriptorGetter for descriptor::FileDescriptorProto {
fn get_message_descriptor_proto(&self, name: &str) -> Option<&descriptor::DescriptorProto> {
if name.is_empty() {
return None;
}
self.message_type.iter().find(|s| s.name() == name)
}
fn get_enum_descriptor_proto(&self, name: &str) -> Option<&descriptor::EnumDescriptorProto> {
if name.is_empty() {
return None;
}
self.enum_type.iter().find(|s| s.name() == name)
}
fn get_service_descriptor_proto(
&self,
name: &str,
) -> Option<&descriptor::ServiceDescriptorProto> {
if name.is_empty() {
return None;
}
self.service.iter().find(|s| s.name() == name)
}
}
pub trait FieldDescriptorGetter {
fn get_field_descriptor_proto(&self, name: &str) -> Option<&descriptor::FieldDescriptorProto>;
fn get_oneof_descriptor_proto(&self, name: &str) -> Option<&descriptor::OneofDescriptorProto>;
fn get_enum_descriptor_proto(&self, name: &str) -> Option<&descriptor::EnumDescriptorProto>;
fn get_message_descriptor_proto(&self, name: &str) -> Option<&descriptor::DescriptorProto>;
}
impl FieldDescriptorGetter for descriptor::DescriptorProto {
fn get_field_descriptor_proto(&self, name: &str) -> Option<&descriptor::FieldDescriptorProto> {
if name.is_empty() {
return None;
}
self.field.iter().find(|s| s.name() == name)
}
fn get_oneof_descriptor_proto(&self, name: &str) -> Option<&descriptor::OneofDescriptorProto> {
if name.is_empty() {
return None;
}
self.oneof_decl.iter().find(|s| s.name() == name)
}
fn get_enum_descriptor_proto(&self, name: &str) -> Option<&descriptor::EnumDescriptorProto> {
if name.is_empty() {
return None;
}
self.enum_type.iter().find(|s| s.name() == name)
}
fn get_message_descriptor_proto(&self, name: &str) -> Option<&descriptor::DescriptorProto> {
if name.is_empty() {
return None;
}
self.nested_type.iter().find(|s| s.name() == name)
}
}
#[cfg(test)]
mod tests {
use protobuf::descriptor;
use super::*;
fn make_file_with_items() -> descriptor::FileDescriptorProto {
let mut f = descriptor::FileDescriptorProto::new();
let mut m = descriptor::DescriptorProto::new();
m.name = Some("Foo".to_string());
f.message_type.push(m);
let mut e = descriptor::EnumDescriptorProto::new();
e.name = Some("Bar".to_string());
f.enum_type.push(e);
let mut s = descriptor::ServiceDescriptorProto::new();
s.name = Some("Baz".to_string());
f.service.push(s);
f
}
#[test]
fn test_get_message_descriptor_proto_found_and_missing() {
let f = make_file_with_items();
let got = f.get_message_descriptor_proto("Foo");
assert!(got.is_some());
assert_eq!(got.unwrap().name.as_deref(), Some("Foo"));
assert!(f.get_message_descriptor_proto("NotExist").is_none());
assert!(f.get_message_descriptor_proto("").is_none());
}
#[test]
fn test_get_enum_descriptor_proto_found_and_missing() {
let f = make_file_with_items();
let got = f.get_enum_descriptor_proto("Bar");
assert!(got.is_some());
assert_eq!(got.unwrap().name.as_deref(), Some("Bar"));
assert!(f.get_enum_descriptor_proto("NotExist").is_none());
assert!(f.get_enum_descriptor_proto("").is_none());
}
#[test]
fn test_get_service_descriptor_proto_found_and_missing() {
let f = make_file_with_items();
let got = f.get_service_descriptor_proto("Baz");
assert!(got.is_some());
assert_eq!(got.unwrap().name.as_deref(), Some("Baz"));
assert!(f.get_service_descriptor_proto("NotExist").is_none());
assert!(f.get_service_descriptor_proto("").is_none());
}
#[test]
fn test_get_oneof_descriptor_proto_found_and_missing() {
let mut msg = descriptor::DescriptorProto::new();
msg.name = Some("Container".to_string());
let mut o1 = descriptor::OneofDescriptorProto::new();
o1.name = Some("alpha".to_string());
msg.oneof_decl.push(o1);
let mut o2 = descriptor::OneofDescriptorProto::new();
o2.name = Some("beta".to_string());
msg.oneof_decl.push(o2);
let got = msg.get_oneof_descriptor_proto("alpha");
assert!(got.is_some());
assert_eq!(got.unwrap().name.as_deref(), Some("alpha"));
let got = msg.get_oneof_descriptor_proto("beta");
assert!(got.is_some());
assert_eq!(got.unwrap().name.as_deref(), Some("beta"));
assert!(msg.get_oneof_descriptor_proto("gamma").is_none());
assert!(msg.get_oneof_descriptor_proto("").is_none());
}
#[test]
fn test_get_field_descriptor_proto_found_and_missing() {
let mut msg = descriptor::DescriptorProto::new();
msg.name = Some("Container".to_string());
let mut f1 = descriptor::FieldDescriptorProto::new();
f1.name = Some("id".to_string());
msg.field.push(f1);
let mut f2 = descriptor::FieldDescriptorProto::new();
f2.name = Some("name".to_string());
msg.field.push(f2);
let got = msg.get_field_descriptor_proto("id");
assert!(got.is_some());
assert_eq!(got.unwrap().name.as_deref(), Some("id"));
let got = msg.get_field_descriptor_proto("name");
assert!(got.is_some());
assert_eq!(got.unwrap().name.as_deref(), Some("name"));
assert!(msg.get_field_descriptor_proto("age").is_none());
assert!(msg.get_field_descriptor_proto("").is_none());
}
#[test]
fn test_get_enum_descriptor_proto_in_descriptor_proto_found_and_missing() {
let mut msg = descriptor::DescriptorProto::new();
msg.name = Some("Container".to_string());
let mut e = descriptor::EnumDescriptorProto::new();
e.name = Some("Color".to_string());
msg.enum_type.push(e);
let got = msg.get_enum_descriptor_proto("Color");
assert!(got.is_some());
assert_eq!(got.unwrap().name.as_deref(), Some("Color"));
assert!(msg.get_enum_descriptor_proto("Size").is_none());
assert!(msg.get_enum_descriptor_proto("").is_none());
}
#[test]
fn test_get_message_descriptor_proto_in_descriptor_proto_found_and_missing() {
let mut msg = descriptor::DescriptorProto::new();
msg.name = Some("Container".to_string());
let mut m = descriptor::DescriptorProto::new();
m.name = Some("Item".to_string());
msg.nested_type.push(m);
let got = msg.get_message_descriptor_proto("Item");
assert!(got.is_some());
assert_eq!(got.unwrap().name.as_deref(), Some("Item"));
assert!(msg.get_message_descriptor_proto("Detail").is_none());
assert!(msg.get_message_descriptor_proto("").is_none());
}
}