[][src]Module serde_protobuf::descriptor

Dynamic descriptors for protocol buffer schemata.

The descriptors are optimized for read performance, i.e. to be used by a parser to parse actual protocol buffer data.

They can be constructed either from pre-compiled protocol buffer-serialized descriptors as defined in descriptor.proto, or manually by incrementally building a custom protocol buffer schema.

Pre-compiled schemas

Given a protocol buffer schema schema.proto, it can be compiled into a binary file descriptor set using the protoc tool:

protoc schema.proto -o testdata/descriptors.pb

The binary file descriptor set can then be parsed into a Descriptors instance:

extern crate serde_protobuf;
extern crate protobuf;

use std::fs;
use serde_protobuf::descriptor::Descriptors;

let mut file = fs::File::open("testdata/descriptors.pb")?;
let proto = protobuf::parse_from_reader(&mut file)?;
let descriptors = Descriptors::from_proto(&proto);

Manually built schemas

A descriptor can be built at run-time by incrementally adding new message types and fields:

use serde_protobuf::descriptor::*;

// Create a new message type
let mut m = MessageDescriptor::new(".mypackage.Person");
m.add_field(FieldDescriptor::new("name", 1, FieldLabel::Optional,
                                 InternalFieldType::String, None));
m.add_field(FieldDescriptor::new("age", 2, FieldLabel::Optional,
                                 InternalFieldType::Int32, None));

// Create a new enum type
let mut e = EnumDescriptor::new(".mypackage.Color");
e.add_value(EnumValueDescriptor::new("BLUE", 1));
e.add_value(EnumValueDescriptor::new("RED", 2));

// Add the generated types to a descriptor registry
let mut descriptors = Descriptors::new();
descriptors.add_message(m);
descriptors.add_enum(e);

Exploring descriptors

The descriptors contain various indices that can be used to quickly look up information:

// Given a set of descriptors using one of the above methods:
let descriptors = Descriptors::from_proto(&proto);
assert_eq!(7, descriptors.message_by_name(".protobuf_unittest.TestAllTypes").unwrap()
                         .field_by_name("optional_fixed32").unwrap()
                         .number());

Optimizing reference look-ups

Certain descriptor look-ups require following references that can be quite expensive to look up. Instead, a one-time cost can be payed to resolve these references and make all following look-ups cheaper. This should be done after all needed descriptors have been loaded:

// Load some descriptors as usual:
let mut descriptors = Descriptors::from_proto(&proto);

// Resolve references internally to speed up lookups:
descriptors.resolve_refs();

// This should now be faster
match descriptors.message_by_name(".protobuf_unittest.TestAllTypes").unwrap()
                 .field_by_name("optional_nested_message").unwrap()
                 .field_type(&descriptors) {
  FieldType::Message(m) =>
    assert_eq!(1, m.field_by_name("bb").unwrap()
                   .number()),
  _ => unreachable!(),
}

Structs

Descriptors

A registry for any number of protocol buffer descriptors.

EnumDescriptor

A descriptor for a single protocol buffer enum type.

EnumId

An ID used for internal tracking of resolved enum descriptors.

EnumValueDescriptor

A descriptor for a single protocol buffer enum value.

FieldDescriptor

A descriptor for a single protocol buffer message field.

MessageDescriptor

A descriptor for a single protocol buffer message type.

MessageId

An ID used for internal tracking of resolved message descriptors.

Enums

FieldLabel

A label that a field can be given to indicate its cardinality.

FieldType

The externally visible type of a field.

InternalFieldType

The internally tracked type of a field.