1pub use self::WireType::*;
5
6pub const TAG_TYPE_BITS: u32 = 3;
8pub const TAG_TYPE_MASK: u32 = (1u32 << TAG_TYPE_BITS) - 1;
10pub const FIELD_NUMBER_MAX: u32 = 0x1fffffff;
12
13#[derive(PartialEq, Eq, Clone, Debug)]
15pub enum WireType {
16 WireTypeVarint = 0,
18 WireTypeFixed64 = 1,
20 WireTypeLengthDelimited = 2,
22 WireTypeStartGroup = 3,
24 WireTypeEndGroup = 4,
26 WireTypeFixed32 = 5,
28}
29
30impl Copy for WireType {}
31
32impl WireType {
33 pub fn new(n: u32) -> Option<WireType> {
35 match n {
36 0 => Some(WireTypeVarint),
37 1 => Some(WireTypeFixed64),
38 2 => Some(WireTypeLengthDelimited),
39 3 => Some(WireTypeStartGroup),
40 4 => Some(WireTypeEndGroup),
41 5 => Some(WireTypeFixed32),
42 _ => None,
43 }
44 }
45}
46
47#[derive(Clone)]
49pub struct Tag {
50 field_number: u32,
51 wire_type: WireType,
52}
53
54impl Copy for Tag {}
55
56impl Tag {
57 pub fn value(self) -> u32 {
59 (self.field_number << TAG_TYPE_BITS) | (self.wire_type as u32)
60 }
61
62 pub fn new(value: u32) -> Option<Tag> {
65 let wire_type = WireType::new(value & TAG_TYPE_MASK);
66 if wire_type.is_none() {
67 return None;
68 }
69 let field_number = value >> TAG_TYPE_BITS;
70 if field_number == 0 {
71 return None;
72 }
73 Some(Tag {
74 field_number: field_number,
75 wire_type: wire_type.unwrap(),
76 })
77 }
78
79 pub fn make(field_number: u32, wire_type: WireType) -> Tag {
85 assert!(field_number > 0 && field_number <= FIELD_NUMBER_MAX);
86 Tag {
87 field_number: field_number,
88 wire_type: wire_type,
89 }
90 }
91
92 pub fn unpack(self) -> (u32, WireType) {
94 (self.field_number(), self.wire_type())
95 }
96
97 fn wire_type(self) -> WireType {
98 self.wire_type
99 }
100
101 pub fn field_number(self) -> u32 {
103 self.field_number
104 }
105}