1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
use num_enum::TryFromPrimitive; use std::convert::TryFrom; #[derive(Debug, Eq, PartialEq, TryFromPrimitive)] #[repr(u32)] enum WireType { Varint = 0, Bits64 = 1, LengthDelimited = 2, Bits32 = 5 } pub struct Encoder { pub encoded: Vec<u8> } impl Encoder { fn write_tagged_varint(&mut self, field_number: u32, wire_type: WireType, value: u64) { if value > 0 { self.write_tag(field_number, wire_type); self.write_varint(value); } } fn write_tag(&mut self, field_number: u32, wire_type: WireType) { self.write_varint((field_number << 3 | wire_type as u32) as u64); } fn write_varint(&mut self, mut value: u64) { loop { let item = value as u8; value >>= 7; if value == 0 { self.encoded.push(item); break; } else { self.encoded.push(item | 0x80); } } } pub fn write_length_delimited(&mut self, field_number: u32, value: u64) { self.write_tag(field_number, WireType::LengthDelimited); self.write_varint(value); } pub fn write_string(&mut self, field_number: u32, value: &String) { self.write_tagged_varint(field_number, WireType::LengthDelimited, value.len() as u64); self.encoded.extend(value.as_bytes()); } pub fn write_int32(&mut self, field_number: u32, value: i32) { self.write_tagged_varint(field_number, WireType::Varint, value as i64 as u64); } } pub struct Decoder { pub pos: usize, pub encoded: Vec<u8> } impl Decoder { pub fn available(&self) -> bool { self.pos < self.encoded.len() } pub fn read_tag(&mut self) -> (u32, u32) { if self.pos < self.encoded.len() { self.pos += 1; (1, self.encoded[self.pos - 1] as u32) } else { (0, 0) } } pub fn read_varint(&mut self) -> u64 { 5 } pub fn read_length_delimited(&mut self) -> u64{ 3 } pub fn read_string(&mut self, _wire_type: u32) -> String { String::from("koko") } pub fn read_int32(&mut self, _wire_type: u32) -> i32 { 5 } pub fn seek(&mut self, offset: u32) { self.pos += offset as usize; } pub fn skip_field(&mut self, wire_type: u32) { match WireType::try_from(wire_type) { Ok(WireType::Varint) => { self.read_varint(); }, Ok(WireType::Bits64) => self.seek(8), Ok(WireType::LengthDelimited) => { self.read_length_delimited(); }, Ok(WireType::Bits32) => self.seek(4), Err(message) => panic!("{}", message) }; } }