//! Serialization constants. // TODO: temporary pub use self::WireType::*; /// Tag occupies 3 bits pub const TAG_TYPE_BITS: u32 = 3; /// Tag mask pub const TAG_TYPE_MASK: u32 = (1u32 << TAG_TYPE_BITS) - 1; /// Max possible field number pub const FIELD_NUMBER_MAX: u32 = 0x1fffffff; /// One of six defined protobuf wire types #[derive(PartialEq, Eq, Clone, Debug)] pub enum WireType { /// Varint (e. g. `int32` or `sint64`) WireTypeVarint = 0, /// Fixed size 64 bit (e. g. `fixed64` or `double`) WireTypeFixed64 = 1, /// Length-delimited (e. g. `message` or `string`) WireTypeLengthDelimited = 2, /// Groups are not supported by rust-protobuf WireTypeStartGroup = 3, /// Groups are not supported by rust-protobuf WireTypeEndGroup = 4, /// Fixed size 64 bit (e. g. `fixed32` or `float`) WireTypeFixed32 = 5, } impl Copy for WireType {} impl WireType { /// Parse wire type pub fn new(n: u32) -> Option { match n { 0 => Some(WireTypeVarint), 1 => Some(WireTypeFixed64), 2 => Some(WireTypeLengthDelimited), 3 => Some(WireTypeStartGroup), 4 => Some(WireTypeEndGroup), 5 => Some(WireTypeFixed32), _ => None, } } } /// Parsed protobuf tag, which is a pair of field number and wire type #[derive(Clone)] pub struct Tag { field_number: u32, wire_type: WireType, } impl Copy for Tag {} impl Tag { /// Pack a tag to integer pub fn value(self) -> u32 { (self.field_number << TAG_TYPE_BITS) | (self.wire_type as u32) } /// Parse integer into `Tag` object // TODO: should return Result instead of Option pub fn new(value: u32) -> Option { let wire_type = WireType::new(value & TAG_TYPE_MASK); if wire_type.is_none() { return None; } let field_number = value >> TAG_TYPE_BITS; if field_number == 0 { return None; } Some(Tag { field_number: field_number, wire_type: wire_type.unwrap(), }) } /// Create a tag from a field number and wire type. /// /// # Panics /// /// If field number is outside of allowed range. pub fn make(field_number: u32, wire_type: WireType) -> Tag { assert!(field_number > 0 && field_number <= FIELD_NUMBER_MAX); Tag { field_number: field_number, wire_type: wire_type, } } /// Tag as pair of (field number, wire type) pub fn unpack(self) -> (u32, WireType) { (self.field_number(), self.wire_type()) } fn wire_type(self) -> WireType { self.wire_type } /// Protobuf field number pub fn field_number(self) -> u32 { self.field_number } }