protobuf 2.16.0

Rust implementation of Google protocol buffers
Documentation
use descriptor::{FieldDescriptorProto, FieldDescriptorProto_Label};
use reflect::accessor::FieldAccessor;
use reflect::map::ReflectMap;
use reflect::repeated::ReflectRepeated;
use reflect::{EnumValueDescriptor, ReflectValueRef};
use Message;

/// Reference to a value stored in a field, optional, repeated or map.
// TODO: implement Eq
pub enum ReflectFieldRef<'a> {
    /// Singular field, optional or required in proto3 and just plain field in proto3
    Optional(Option<ReflectValueRef<'a>>),
    /// Repeated field
    Repeated(&'a ReflectRepeated),
    /// Map field
    Map(&'a ReflectMap),
}

/// Field descriptor.
///
/// Can be used for runtime reflection.
pub struct FieldDescriptor {
    proto: &'static FieldDescriptorProto,
    accessor: Box<FieldAccessor + 'static>,
}

impl FieldDescriptor {
    pub(crate) fn new(
        accessor: Box<FieldAccessor + 'static>,
        proto: &'static FieldDescriptorProto,
    ) -> FieldDescriptor {
        assert_eq!(proto.get_name(), accessor.name_generic());
        FieldDescriptor { proto, accessor }
    }

    /// Get `.proto` description of field
    pub fn proto(&self) -> &'static FieldDescriptorProto {
        self.proto
    }

    /// Field name as specified in `.proto` file
    pub fn name(&self) -> &'static str {
        self.proto.get_name()
    }

    /// If this field repeated?
    pub fn is_repeated(&self) -> bool {
        self.proto.get_label() == FieldDescriptorProto_Label::LABEL_REPEATED
    }

    /// Check if field is set in given message.
    ///
    /// For repeated field or map field return `true` if
    /// collection is not empty.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type.
    pub fn has_field(&self, m: &Message) -> bool {
        self.accessor.has_field_generic(m)
    }

    /// Return length of repeated field.
    ///
    /// For singualar field return `1` if field is set and `0` otherwise.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type.
    pub fn len_field(&self, m: &dyn Message) -> usize {
        self.accessor.len_field_generic(m)
    }

    /// Get message field or default instance if field is unset.
    ///
    /// # Panics
    /// If this field belongs to a different message type or
    /// field type is not message.
    pub fn get_message<'a>(&self, m: &'a dyn Message) -> &'a dyn Message {
        self.accessor.get_message_generic(m)
    }

    /// Get `enum` field.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type
    /// or field type is not singular `enum`.
    pub fn get_enum(&self, m: &dyn Message) -> &'static EnumValueDescriptor {
        self.accessor.get_enum_generic(m)
    }

    /// Get `string` field.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type
    /// or field type is not singular `string`.
    pub fn get_str<'a>(&self, m: &'a dyn Message) -> &'a str {
        self.accessor.get_str_generic(m)
    }

    /// Get `bytes` field.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type
    /// or field type is not singular `bytes`.
    pub fn get_bytes<'a>(&self, m: &'a dyn Message) -> &'a [u8] {
        self.accessor.get_bytes_generic(m)
    }

    /// Get `u32` field.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type
    /// or field type is not singular `u32`.
    pub fn get_u32(&self, m: &dyn Message) -> u32 {
        self.accessor.get_u32_generic(m)
    }

    /// Get `u64` field.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type
    /// or field type is not singular `u64`.
    pub fn get_u64(&self, m: &dyn Message) -> u64 {
        self.accessor.get_u64_generic(m)
    }

    /// Get `i32` field.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type
    /// or field type is not singular `i32`.
    pub fn get_i32(&self, m: &dyn Message) -> i32 {
        self.accessor.get_i32_generic(m)
    }

    /// Get `i64` field.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type
    /// or field type is not singular `i64`.
    pub fn get_i64(&self, m: &dyn Message) -> i64 {
        self.accessor.get_i64_generic(m)
    }

    /// Get `bool` field.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type or
    /// field type is not singular `bool`.
    pub fn get_bool(&self, m: &dyn Message) -> bool {
        self.accessor.get_bool_generic(m)
    }

    /// Get `float` field.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type or
    /// field type is not singular `float`.
    pub fn get_f32(&self, m: &dyn Message) -> f32 {
        self.accessor.get_f32_generic(m)
    }

    /// Get `double` field.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type
    /// or field type is not singular `double`.
    pub fn get_f64(&self, m: &dyn Message) -> f64 {
        self.accessor.get_f64_generic(m)
    }

    /// Get field of any type.
    ///
    /// # Panics
    ///
    /// If this field belongs to a different message type.
    pub fn get_reflect<'a>(&self, m: &'a dyn Message) -> ReflectFieldRef<'a> {
        self.accessor.get_reflect(m)
    }
}