oxihuman_export/
protobuf_export.rs1#![allow(dead_code)]
4
5#[allow(dead_code)]
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum WireType {
11 Varint = 0,
12 Bit64 = 1,
13 LenDelimited = 2,
14 Bit32 = 5,
15}
16
17#[allow(dead_code)]
19pub fn encode_tag(field: u32, wire: WireType) -> Vec<u8> {
20 let tag = (field << 3) | wire as u32;
21 encode_varint(tag as u64)
22}
23
24#[allow(dead_code)]
26pub fn encode_varint(mut val: u64) -> Vec<u8> {
27 let mut out = Vec::new();
28 loop {
29 let byte = (val & 0x7F) as u8;
30 val >>= 7;
31 if val == 0 {
32 out.push(byte);
33 break;
34 } else {
35 out.push(byte | 0x80);
36 }
37 }
38 out
39}
40
41#[allow(dead_code)]
43pub fn zigzag32(val: i32) -> u32 {
44 ((val << 1) ^ (val >> 31)) as u32
45}
46
47#[allow(dead_code)]
49pub fn zigzag64(val: i64) -> u64 {
50 ((val << 1) ^ (val >> 63)) as u64
51}
52
53#[allow(dead_code)]
55#[derive(Debug, Clone, Default)]
56pub struct ProtoEncoder {
57 pub buf: Vec<u8>,
58}
59
60impl ProtoEncoder {
61 #[allow(dead_code)]
62 pub fn new() -> Self {
63 ProtoEncoder::default()
64 }
65
66 #[allow(dead_code)]
67 pub fn write_varint_field(&mut self, field: u32, val: u64) {
68 self.buf.extend(encode_tag(field, WireType::Varint));
69 self.buf.extend(encode_varint(val));
70 }
71
72 #[allow(dead_code)]
73 pub fn write_fixed64_field(&mut self, field: u32, val: u64) {
74 self.buf.extend(encode_tag(field, WireType::Bit64));
75 self.buf.extend_from_slice(&val.to_le_bytes());
76 }
77
78 #[allow(dead_code)]
79 pub fn write_fixed32_field(&mut self, field: u32, val: u32) {
80 self.buf.extend(encode_tag(field, WireType::Bit32));
81 self.buf.extend_from_slice(&val.to_le_bytes());
82 }
83
84 #[allow(dead_code)]
85 pub fn write_bytes_field(&mut self, field: u32, data: &[u8]) {
86 self.buf.extend(encode_tag(field, WireType::LenDelimited));
87 self.buf.extend(encode_varint(data.len() as u64));
88 self.buf.extend_from_slice(data);
89 }
90
91 #[allow(dead_code)]
92 pub fn write_string_field(&mut self, field: u32, s: &str) {
93 self.write_bytes_field(field, s.as_bytes());
94 }
95
96 #[allow(dead_code)]
97 pub fn write_f32_field(&mut self, field: u32, val: f32) {
98 self.write_fixed32_field(field, val.to_bits());
99 }
100
101 #[allow(dead_code)]
102 pub fn write_f64_field(&mut self, field: u32, val: f64) {
103 self.write_fixed64_field(field, val.to_bits());
104 }
105
106 #[allow(dead_code)]
107 pub fn as_bytes(&self) -> &[u8] {
108 &self.buf
109 }
110
111 #[allow(dead_code)]
112 pub fn len(&self) -> usize {
113 self.buf.len()
114 }
115
116 #[allow(dead_code)]
117 pub fn is_empty(&self) -> bool {
118 self.buf.is_empty()
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn varint_small_single_byte() {
128 let b = encode_varint(1);
129 assert_eq!(b, vec![0x01]);
130 }
131
132 #[test]
133 fn varint_128_two_bytes() {
134 let b = encode_varint(128);
135 assert_eq!(b.len(), 2);
136 }
137
138 #[test]
139 fn tag_field1_varint() {
140 let t = encode_tag(1, WireType::Varint);
141 assert_eq!(t, vec![0x08]);
142 }
143
144 #[test]
145 fn zigzag32_positive() {
146 assert_eq!(zigzag32(1), 2);
147 }
148
149 #[test]
150 fn zigzag32_negative() {
151 assert_eq!(zigzag32(-1), 1);
152 }
153
154 #[test]
155 fn zigzag64_zero() {
156 assert_eq!(zigzag64(0), 0);
157 }
158
159 #[test]
160 fn write_varint_field() {
161 let mut enc = ProtoEncoder::new();
162 enc.write_varint_field(1, 42);
163 assert!(!enc.is_empty());
164 }
165
166 #[test]
167 fn write_string_field_contains_bytes() {
168 let mut enc = ProtoEncoder::new();
169 enc.write_string_field(1, "hi");
170 let s = &enc.buf;
171 assert!(s.windows(2).any(|w| w == b"hi"));
172 }
173
174 #[test]
175 fn write_f32_field_nine_bytes() {
176 let mut enc = ProtoEncoder::new();
177 enc.write_f32_field(1, 1.0);
178 assert_eq!(enc.len(), 5);
179 }
180
181 #[test]
182 fn write_f64_field_ten_bytes() {
183 let mut enc = ProtoEncoder::new();
184 enc.write_f64_field(1, 1.0);
185 assert_eq!(enc.len(), 9);
186 }
187}