1use crate::header::MessageHeader;
6
7pub trait SbeEncoder: Sized {
25 const TEMPLATE_ID: u16;
27
28 const SCHEMA_ID: u16;
30
31 const SCHEMA_VERSION: u16;
33
34 const BLOCK_LENGTH: u16;
36
37 fn wrap(buffer: &mut [u8], offset: usize) -> Self;
48
49 fn encoded_length(&self) -> usize;
53
54 #[must_use]
56 fn create_header() -> MessageHeader {
57 MessageHeader {
58 block_length: Self::BLOCK_LENGTH,
59 template_id: Self::TEMPLATE_ID,
60 schema_id: Self::SCHEMA_ID,
61 version: Self::SCHEMA_VERSION,
62 }
63 }
64}
65
66#[derive(Debug)]
71pub struct EncoderBuffer<'a> {
72 buffer: &'a mut [u8],
73 offset: usize,
74 position: usize,
75}
76
77impl<'a> EncoderBuffer<'a> {
78 #[must_use]
84 pub fn new(buffer: &'a mut [u8], offset: usize) -> Self {
85 Self {
86 buffer,
87 offset,
88 position: offset,
89 }
90 }
91
92 #[must_use]
94 pub fn buffer(&self) -> &[u8] {
95 self.buffer
96 }
97
98 pub fn buffer_mut(&mut self) -> &mut [u8] {
100 self.buffer
101 }
102
103 #[must_use]
105 pub const fn offset(&self) -> usize {
106 self.offset
107 }
108
109 #[must_use]
111 pub const fn position(&self) -> usize {
112 self.position
113 }
114
115 #[must_use]
117 pub const fn bytes_written(&self) -> usize {
118 self.position - self.offset
119 }
120
121 #[must_use]
123 pub fn remaining(&self) -> usize {
124 self.buffer.len() - self.position
125 }
126
127 pub fn advance(&mut self, count: usize) {
132 self.position += count;
133 }
134
135 pub fn set_position(&mut self, pos: usize) {
140 self.position = pos;
141 }
142
143 pub fn write_u8(&mut self, value: u8) {
145 self.buffer[self.position] = value;
146 self.position += 1;
147 }
148
149 pub fn write_u16_le(&mut self, value: u16) {
151 let bytes = value.to_le_bytes();
152 self.buffer[self.position..self.position + 2].copy_from_slice(&bytes);
153 self.position += 2;
154 }
155
156 pub fn write_u32_le(&mut self, value: u32) {
158 let bytes = value.to_le_bytes();
159 self.buffer[self.position..self.position + 4].copy_from_slice(&bytes);
160 self.position += 4;
161 }
162
163 pub fn write_u64_le(&mut self, value: u64) {
165 let bytes = value.to_le_bytes();
166 self.buffer[self.position..self.position + 8].copy_from_slice(&bytes);
167 self.position += 8;
168 }
169
170 pub fn write_bytes(&mut self, data: &[u8]) {
172 self.buffer[self.position..self.position + data.len()].copy_from_slice(data);
173 self.position += data.len();
174 }
175
176 pub fn write_zeros(&mut self, count: usize) {
178 self.buffer[self.position..self.position + count].fill(0);
179 self.position += count;
180 }
181}
182
183pub trait GroupEncoder {
187 type Entry<'a>
189 where
190 Self: 'a;
191
192 fn count(&self) -> u16;
194
195 fn next_entry(&mut self) -> Option<Self::Entry<'_>>;
200}
201
202#[cfg(test)]
203mod tests {
204 use super::*;
205
206 #[test]
207 fn test_encoder_buffer_basic() {
208 let mut buf = [0u8; 64];
209 let mut encoder = EncoderBuffer::new(&mut buf, 0);
210
211 assert_eq!(encoder.offset(), 0);
212 assert_eq!(encoder.position(), 0);
213 assert_eq!(encoder.bytes_written(), 0);
214 assert_eq!(encoder.remaining(), 64);
215
216 encoder.write_u8(0xFF);
217 assert_eq!(encoder.position(), 1);
218 assert_eq!(encoder.bytes_written(), 1);
219
220 encoder.write_u16_le(0x1234);
221 assert_eq!(encoder.position(), 3);
222
223 encoder.write_u32_le(0xDEADBEEF);
224 assert_eq!(encoder.position(), 7);
225
226 encoder.write_u64_le(0x123456789ABCDEF0);
227 assert_eq!(encoder.position(), 15);
228 }
229
230 #[test]
231 fn test_encoder_buffer_with_offset() {
232 let mut buf = [0u8; 64];
233 let mut encoder = EncoderBuffer::new(&mut buf, 8);
234
235 assert_eq!(encoder.offset(), 8);
236 assert_eq!(encoder.position(), 8);
237 assert_eq!(encoder.bytes_written(), 0);
238
239 encoder.write_u32_le(0x12345678);
240 assert_eq!(encoder.position(), 12);
241 assert_eq!(encoder.bytes_written(), 4);
242
243 assert_eq!(buf[8], 0x78);
245 assert_eq!(buf[9], 0x56);
246 assert_eq!(buf[10], 0x34);
247 assert_eq!(buf[11], 0x12);
248 }
249
250 #[test]
251 fn test_encoder_buffer_write_bytes() {
252 let mut buf = [0u8; 64];
253 let mut encoder = EncoderBuffer::new(&mut buf, 0);
254
255 encoder.write_bytes(b"Hello");
256 assert_eq!(encoder.position(), 5);
257 assert_eq!(&buf[0..5], b"Hello");
258 }
259
260 #[test]
261 fn test_encoder_buffer_write_zeros() {
262 let mut buf = [0xFFu8; 64];
263 let mut encoder = EncoderBuffer::new(&mut buf, 0);
264
265 encoder.write_zeros(8);
266 assert_eq!(encoder.position(), 8);
267 assert!(buf[0..8].iter().all(|&b| b == 0));
268 assert_eq!(buf[8], 0xFF);
269 }
270
271 #[test]
272 fn test_encoder_buffer_advance() {
273 let mut buf = [0u8; 64];
274 let mut encoder = EncoderBuffer::new(&mut buf, 0);
275
276 encoder.advance(10);
277 assert_eq!(encoder.position(), 10);
278 assert_eq!(encoder.bytes_written(), 10);
279 }
280
281 #[test]
282 fn test_encoder_buffer_set_position() {
283 let mut buf = [0u8; 64];
284 let mut encoder = EncoderBuffer::new(&mut buf, 0);
285
286 encoder.write_u32_le(0x12345678);
287 assert_eq!(encoder.position(), 4);
288
289 encoder.set_position(20);
290 assert_eq!(encoder.position(), 20);
291 }
292
293 #[test]
294 fn test_encoder_buffer_buffer_access() {
295 let mut buf = [0u8; 64];
296 let mut encoder = EncoderBuffer::new(&mut buf, 0);
297
298 encoder.write_u8(0xAB);
299
300 assert_eq!(encoder.buffer()[0], 0xAB);
302
303 encoder.buffer_mut()[1] = 0xCD;
305 assert_eq!(encoder.buffer()[1], 0xCD);
306 }
307
308 #[test]
309 fn test_encoder_buffer_debug() {
310 let mut buf = [0u8; 64];
311 let encoder = EncoderBuffer::new(&mut buf, 0);
312 let debug_str = format!("{:?}", encoder);
313 assert!(debug_str.contains("EncoderBuffer"));
314 }
315
316 struct TestEncoder {
318 offset: usize,
319 len: usize,
320 }
321
322 impl SbeEncoder for TestEncoder {
323 const TEMPLATE_ID: u16 = 1;
324 const SCHEMA_ID: u16 = 100;
325 const SCHEMA_VERSION: u16 = 1;
326 const BLOCK_LENGTH: u16 = 16;
327
328 fn wrap(_buffer: &mut [u8], offset: usize) -> TestEncoder {
329 TestEncoder {
330 offset,
331 len: MessageHeader::ENCODED_LENGTH + Self::BLOCK_LENGTH as usize,
332 }
333 }
334
335 fn encoded_length(&self) -> usize {
336 self.len
337 }
338 }
339
340 #[test]
341 fn test_sbe_encoder_create_header() {
342 let header = TestEncoder::create_header();
343 let block_length = header.block_length;
345 let template_id = header.template_id;
346 let schema_id = header.schema_id;
347 let version = header.version;
348
349 assert_eq!(block_length, 16);
350 assert_eq!(template_id, 1);
351 assert_eq!(schema_id, 100);
352 assert_eq!(version, 1);
353 }
354
355 #[test]
356 fn test_sbe_encoder_wrap() {
357 let mut buf = [0u8; 64];
358 let encoder = TestEncoder::wrap(&mut buf, 0);
359
360 assert_eq!(encoder.offset, 0);
361 assert_eq!(encoder.encoded_length(), 24); }
363}