bcp_encoder/
block_writer.rs1pub struct BlockWriter {
25 buf: Vec<u8>,
26}
27
28impl BlockWriter {
29 #[must_use]
31 pub fn new() -> Self {
32 Self { buf: Vec::new() }
33 }
34
35 #[must_use]
40 pub fn with_capacity(capacity: usize) -> Self {
41 Self {
42 buf: Vec::with_capacity(capacity),
43 }
44 }
45
46 pub fn write_varint_field(&mut self, field_id: u64, value: u64) {
50 bcp_types::fields::encode_varint_field(&mut self.buf, field_id, value);
51 }
52
53 pub fn write_bytes_field(&mut self, field_id: u64, value: &[u8]) {
60 bcp_types::fields::encode_bytes_field(&mut self.buf, field_id, value);
61 }
62
63 pub fn write_nested_field(&mut self, field_id: u64, nested: &[u8]) {
71 bcp_types::fields::encode_nested_field(&mut self.buf, field_id, nested);
72 }
73
74 #[must_use]
80 pub fn finish(self) -> Vec<u8> {
81 self.buf
82 }
83}
84
85impl Default for BlockWriter {
86 fn default() -> Self {
87 Self::new()
88 }
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn empty_writer_produces_empty_bytes() {
97 let writer = BlockWriter::new();
98 assert!(writer.finish().is_empty());
99 }
100
101 #[test]
102 fn single_varint_field() {
103 let mut writer = BlockWriter::new();
104 writer.write_varint_field(1, 42);
105 let bytes = writer.finish();
106 assert!(!bytes.is_empty());
107
108 let (header, n) = bcp_types::fields::decode_field_header(&bytes).unwrap();
110 assert_eq!(header.field_id, 1);
111 assert_eq!(header.wire_type, bcp_types::fields::FieldWireType::Varint);
112 let (val, m) = bcp_types::fields::decode_varint_value(&bytes[n..]).unwrap();
113 assert_eq!(val, 42);
114 assert_eq!(n + m, bytes.len());
115 }
116
117 #[test]
118 fn single_bytes_field() {
119 let mut writer = BlockWriter::new();
120 writer.write_bytes_field(2, b"hello");
121 let bytes = writer.finish();
122
123 let (header, n) = bcp_types::fields::decode_field_header(&bytes).unwrap();
124 assert_eq!(header.field_id, 2);
125 assert_eq!(header.wire_type, bcp_types::fields::FieldWireType::Bytes);
126 let (data, m) = bcp_types::fields::decode_bytes_value(&bytes[n..]).unwrap();
127 assert_eq!(data, b"hello");
128 assert_eq!(n + m, bytes.len());
129 }
130
131 #[test]
132 fn nested_field_roundtrip() {
133 let mut inner = BlockWriter::new();
134 inner.write_varint_field(1, 99);
135 let inner_bytes = inner.finish();
136
137 let mut outer = BlockWriter::new();
138 outer.write_nested_field(3, &inner_bytes);
139 let bytes = outer.finish();
140
141 let (header, n) = bcp_types::fields::decode_field_header(&bytes).unwrap();
142 assert_eq!(header.field_id, 3);
143 assert_eq!(header.wire_type, bcp_types::fields::FieldWireType::Nested);
144 let (nested, m) = bcp_types::fields::decode_bytes_value(&bytes[n..]).unwrap();
145 assert_eq!(n + m, bytes.len());
146
147 let (inner_header, k) = bcp_types::fields::decode_field_header(nested).unwrap();
149 assert_eq!(inner_header.field_id, 1);
150 let (val, _) = bcp_types::fields::decode_varint_value(&nested[k..]).unwrap();
151 assert_eq!(val, 99);
152 }
153
154 #[test]
155 fn multiple_fields_sequential() {
156 let mut writer = BlockWriter::new();
157 writer.write_varint_field(1, 7);
158 writer.write_bytes_field(2, b"world");
159 writer.write_varint_field(3, 256);
160 let bytes = writer.finish();
161
162 let mut cursor = 0;
164
165 let (h, n) = bcp_types::fields::decode_field_header(&bytes[cursor..]).unwrap();
166 cursor += n;
167 assert_eq!(h.field_id, 1);
168 let (v, n) = bcp_types::fields::decode_varint_value(&bytes[cursor..]).unwrap();
169 cursor += n;
170 assert_eq!(v, 7);
171
172 let (h, n) = bcp_types::fields::decode_field_header(&bytes[cursor..]).unwrap();
173 cursor += n;
174 assert_eq!(h.field_id, 2);
175 let (data, n) = bcp_types::fields::decode_bytes_value(&bytes[cursor..]).unwrap();
176 cursor += n;
177 assert_eq!(data, b"world");
178
179 let (h, n) = bcp_types::fields::decode_field_header(&bytes[cursor..]).unwrap();
180 cursor += n;
181 assert_eq!(h.field_id, 3);
182 let (v, n) = bcp_types::fields::decode_varint_value(&bytes[cursor..]).unwrap();
183 cursor += n;
184 assert_eq!(v, 256);
185
186 assert_eq!(cursor, bytes.len());
187 }
188}