chie_shared/
encoding.rs

1//! Compact binary encoding with versioning
2//!
3//! This module provides efficient binary encoding/decoding for protocol messages
4//! with version support for backward/forward compatibility.
5
6use crate::{ChieError, ChieResult};
7use std::io::{Read, Write};
8
9/// Binary protocol version identifier
10pub const BINARY_PROTOCOL_VERSION: u8 = 1;
11
12/// Magic bytes to identify CHIE protocol messages
13pub const MAGIC_BYTES: &[u8; 4] = b"CHIE";
14
15/// CRC32 polynomial (IEEE 802.3)
16const CRC32_POLYNOMIAL: u32 = 0xEDB8_8320;
17
18/// Calculate CRC32 checksum for data integrity
19#[must_use]
20pub fn calculate_crc32(data: &[u8]) -> u32 {
21    let mut crc: u32 = 0xFFFF_FFFF;
22
23    for &byte in data {
24        crc ^= u32::from(byte);
25        for _ in 0..8 {
26            crc = if (crc & 1) != 0 {
27                (crc >> 1) ^ CRC32_POLYNOMIAL
28            } else {
29                crc >> 1
30            };
31        }
32    }
33
34    crc ^ 0xFFFF_FFFF
35}
36
37/// Verify CRC32 checksum
38#[must_use]
39pub fn verify_crc32(data: &[u8], expected_crc: u32) -> bool {
40    calculate_crc32(data) == expected_crc
41}
42
43/// Compression algorithm trait for pluggable compression
44pub trait CompressionAlgorithm: Send + Sync {
45    /// Compress data
46    ///
47    /// # Errors
48    ///
49    /// Returns error if compression fails
50    fn compress(&self, data: &[u8]) -> ChieResult<Vec<u8>>;
51
52    /// Decompress data
53    ///
54    /// # Errors
55    ///
56    /// Returns error if decompression fails
57    fn decompress(&self, data: &[u8]) -> ChieResult<Vec<u8>>;
58
59    /// Get the compression algorithm identifier (e.g., "none", "gzip", "zstd")
60    fn algorithm_id(&self) -> &str;
61
62    /// Check if data should be compressed based on size threshold
63    #[must_use]
64    fn should_compress(&self, data_len: usize) -> bool {
65        // Default: compress if data is larger than 1KB
66        data_len > 1024
67    }
68}
69
70/// No-op compression (passthrough)
71#[derive(Debug, Clone, Copy, Default)]
72pub struct NoCompression;
73
74impl CompressionAlgorithm for NoCompression {
75    fn compress(&self, data: &[u8]) -> ChieResult<Vec<u8>> {
76        Ok(data.to_vec())
77    }
78
79    fn decompress(&self, data: &[u8]) -> ChieResult<Vec<u8>> {
80        Ok(data.to_vec())
81    }
82
83    fn algorithm_id(&self) -> &str {
84        "none"
85    }
86
87    fn should_compress(&self, _data_len: usize) -> bool {
88        false
89    }
90}
91
92/// Compression configuration
93#[derive(Debug, Clone, Copy)]
94pub struct CompressionConfig {
95    /// Minimum size in bytes before compression is applied
96    pub min_size: usize,
97    /// Enable compression
98    pub enabled: bool,
99}
100
101impl Default for CompressionConfig {
102    fn default() -> Self {
103        Self {
104            min_size: 1024, // 1 KB
105            enabled: true,
106        }
107    }
108}
109
110impl CompressionConfig {
111    /// Create a new compression configuration
112    #[must_use]
113    pub const fn new(min_size: usize, enabled: bool) -> Self {
114        Self { min_size, enabled }
115    }
116
117    /// Check if data should be compressed
118    #[must_use]
119    pub const fn should_compress(&self, data_len: usize) -> bool {
120        self.enabled && data_len >= self.min_size
121    }
122
123    /// Disable compression
124    #[must_use]
125    pub const fn disabled() -> Self {
126        Self {
127            min_size: usize::MAX,
128            enabled: false,
129        }
130    }
131}
132
133/// Binary encoder with versioning support
134pub struct BinaryEncoder<W: Write> {
135    writer: W,
136    version: u8,
137}
138
139impl<W: Write> BinaryEncoder<W> {
140    /// Create a new encoder with the current protocol version
141    pub fn new(writer: W) -> Self {
142        Self {
143            writer,
144            version: BINARY_PROTOCOL_VERSION,
145        }
146    }
147
148    /// Create an encoder with a specific protocol version
149    pub fn with_version(writer: W, version: u8) -> Self {
150        Self { writer, version }
151    }
152
153    /// Write the message header (magic bytes + version)
154    ///
155    /// # Errors
156    ///
157    /// Returns error if writing fails
158    pub fn write_header(&mut self) -> ChieResult<()> {
159        self.writer
160            .write_all(MAGIC_BYTES)
161            .map_err(|e| ChieError::serialization(format!("Failed to write magic bytes: {e}")))?;
162        self.writer
163            .write_all(&[self.version])
164            .map_err(|e| ChieError::serialization(format!("Failed to write version: {e}")))?;
165        Ok(())
166    }
167
168    /// Write a u8 value
169    ///
170    /// # Errors
171    ///
172    /// Returns error if writing fails
173    pub fn write_u8(&mut self, value: u8) -> ChieResult<()> {
174        self.writer
175            .write_all(&[value])
176            .map_err(|e| ChieError::serialization(format!("Failed to write u8: {e}")))
177    }
178
179    /// Write a u32 value (little-endian)
180    ///
181    /// # Errors
182    ///
183    /// Returns error if writing fails
184    pub fn write_u32(&mut self, value: u32) -> ChieResult<()> {
185        self.writer
186            .write_all(&value.to_le_bytes())
187            .map_err(|e| ChieError::serialization(format!("Failed to write u32: {e}")))
188    }
189
190    /// Write a u64 value (little-endian)
191    ///
192    /// # Errors
193    ///
194    /// Returns error if writing fails
195    pub fn write_u64(&mut self, value: u64) -> ChieResult<()> {
196        self.writer
197            .write_all(&value.to_le_bytes())
198            .map_err(|e| ChieError::serialization(format!("Failed to write u64: {e}")))
199    }
200
201    /// Write a variable-length byte array (length prefix + data)
202    ///
203    /// # Errors
204    ///
205    /// Returns error if writing fails
206    pub fn write_bytes(&mut self, bytes: &[u8]) -> ChieResult<()> {
207        let len = u32::try_from(bytes.len())
208            .map_err(|_| ChieError::serialization("Byte array too large"))?;
209        self.write_u32(len)?;
210        self.writer
211            .write_all(bytes)
212            .map_err(|e| ChieError::serialization(format!("Failed to write bytes: {e}")))
213    }
214
215    /// Write a string (UTF-8 encoded with length prefix)
216    ///
217    /// # Errors
218    ///
219    /// Returns error if writing fails
220    pub fn write_string(&mut self, s: &str) -> ChieResult<()> {
221        self.write_bytes(s.as_bytes())
222    }
223
224    /// Write a boolean as a single byte
225    ///
226    /// # Errors
227    ///
228    /// Returns error if writing fails
229    pub fn write_bool(&mut self, value: bool) -> ChieResult<()> {
230        self.write_u8(u8::from(value))
231    }
232
233    /// Write a CRC32 checksum for the given data
234    ///
235    /// # Errors
236    ///
237    /// Returns error if writing fails
238    pub fn write_checksum(&mut self, data: &[u8]) -> ChieResult<()> {
239        let checksum = calculate_crc32(data);
240        self.write_u32(checksum)
241    }
242
243    /// Get a mutable reference to the underlying writer
244    pub fn get_mut(&mut self) -> &mut W {
245        &mut self.writer
246    }
247
248    /// Consume the encoder and return the underlying writer
249    #[must_use]
250    pub fn into_inner(self) -> W {
251        self.writer
252    }
253
254    /// Write large byte array in chunks to avoid excessive memory allocation
255    ///
256    /// # Examples
257    ///
258    /// ```
259    /// use chie_shared::encoding::BinaryEncoder;
260    ///
261    /// let data = vec![1u8; 10_000]; // 10KB of data
262    /// let mut reader = &data[..];
263    /// let mut buf = Vec::new();
264    /// let mut encoder = BinaryEncoder::new(&mut buf);
265    ///
266    /// // Write in 1KB chunks
267    /// encoder.write_bytes_chunked(&mut reader, 10_000, 1024).unwrap();
268    /// ```
269    ///
270    /// # Errors
271    ///
272    /// Returns error if writing fails
273    pub fn write_bytes_chunked<R: Read>(
274        &mut self,
275        reader: &mut R,
276        total_size: u64,
277        chunk_size: usize,
278    ) -> ChieResult<()> {
279        let total_size_u32 = u32::try_from(total_size)
280            .map_err(|_| ChieError::serialization("Total size too large for u32"))?;
281        self.write_u32(total_size_u32)?;
282
283        let mut buffer = vec![0u8; chunk_size];
284        let mut remaining = total_size;
285
286        while remaining > 0 {
287            let to_read = std::cmp::min(remaining, chunk_size as u64) as usize;
288            reader
289                .read_exact(&mut buffer[..to_read])
290                .map_err(|e| ChieError::serialization(format!("Failed to read chunk: {e}")))?;
291
292            self.writer
293                .write_all(&buffer[..to_read])
294                .map_err(|e| ChieError::serialization(format!("Failed to write chunk: {e}")))?;
295
296            remaining -= to_read as u64;
297        }
298
299        Ok(())
300    }
301
302    /// Stream data directly from a reader without buffering entire payload
303    ///
304    /// # Errors
305    ///
306    /// Returns error if copying fails
307    pub fn copy_from_reader<R: Read>(&mut self, reader: &mut R) -> ChieResult<u64> {
308        std::io::copy(reader, &mut self.writer)
309            .map_err(|e| ChieError::serialization(format!("Failed to copy from reader: {e}")))
310    }
311}
312
313/// Binary decoder with versioning support
314pub struct BinaryDecoder<R: Read> {
315    reader: R,
316    version: u8,
317}
318
319impl<R: Read> BinaryDecoder<R> {
320    /// Create a new decoder
321    pub fn new(reader: R) -> Self {
322        Self {
323            reader,
324            version: BINARY_PROTOCOL_VERSION,
325        }
326    }
327
328    /// Read and verify the message header (magic bytes + version)
329    ///
330    /// # Errors
331    ///
332    /// Returns error if header is invalid or unsupported
333    pub fn read_header(&mut self) -> ChieResult<u8> {
334        let mut magic = [0u8; 4];
335        self.reader
336            .read_exact(&mut magic)
337            .map_err(|e| ChieError::serialization(format!("Failed to read magic bytes: {e}")))?;
338
339        if &magic != MAGIC_BYTES {
340            return Err(ChieError::serialization(format!(
341                "Invalid magic bytes: expected {MAGIC_BYTES:?}, got {magic:?}"
342            )));
343        }
344
345        let mut version_buf = [0u8; 1];
346        self.reader
347            .read_exact(&mut version_buf)
348            .map_err(|e| ChieError::serialization(format!("Failed to read version: {e}")))?;
349
350        self.version = version_buf[0];
351
352        // Validate version compatibility
353        if self.version > BINARY_PROTOCOL_VERSION {
354            return Err(ChieError::serialization(format!(
355                "Unsupported protocol version: {}. Current version: {}",
356                self.version, BINARY_PROTOCOL_VERSION
357            )));
358        }
359
360        Ok(self.version)
361    }
362
363    /// Read a u8 value
364    ///
365    /// # Errors
366    ///
367    /// Returns error if reading fails
368    pub fn read_u8(&mut self) -> ChieResult<u8> {
369        let mut buf = [0u8; 1];
370        self.reader
371            .read_exact(&mut buf)
372            .map_err(|e| ChieError::serialization(format!("Failed to read u8: {e}")))?;
373        Ok(buf[0])
374    }
375
376    /// Read a u32 value (little-endian)
377    ///
378    /// # Errors
379    ///
380    /// Returns error if reading fails
381    pub fn read_u32(&mut self) -> ChieResult<u32> {
382        let mut buf = [0u8; 4];
383        self.reader
384            .read_exact(&mut buf)
385            .map_err(|e| ChieError::serialization(format!("Failed to read u32: {e}")))?;
386        Ok(u32::from_le_bytes(buf))
387    }
388
389    /// Read a u64 value (little-endian)
390    ///
391    /// # Errors
392    ///
393    /// Returns error if reading fails
394    pub fn read_u64(&mut self) -> ChieResult<u64> {
395        let mut buf = [0u8; 8];
396        self.reader
397            .read_exact(&mut buf)
398            .map_err(|e| ChieError::serialization(format!("Failed to read u64: {e}")))?;
399        Ok(u64::from_le_bytes(buf))
400    }
401
402    /// Read a variable-length byte array (length prefix + data)
403    ///
404    /// # Errors
405    ///
406    /// Returns error if reading fails or length is invalid
407    pub fn read_bytes(&mut self) -> ChieResult<Vec<u8>> {
408        let len = self.read_u32()?;
409        let mut buf = vec![0u8; len as usize];
410        self.reader
411            .read_exact(&mut buf)
412            .map_err(|e| ChieError::serialization(format!("Failed to read bytes: {e}")))?;
413        Ok(buf)
414    }
415
416    /// Read a string (UTF-8 encoded with length prefix)
417    ///
418    /// # Errors
419    ///
420    /// Returns error if reading fails or string is invalid UTF-8
421    pub fn read_string(&mut self) -> ChieResult<String> {
422        let bytes = self.read_bytes()?;
423        String::from_utf8(bytes)
424            .map_err(|e| ChieError::serialization(format!("Invalid UTF-8 string: {e}")))
425    }
426
427    /// Read a boolean from a single byte
428    ///
429    /// # Errors
430    ///
431    /// Returns error if reading fails
432    pub fn read_bool(&mut self) -> ChieResult<bool> {
433        let value = self.read_u8()?;
434        Ok(value != 0)
435    }
436
437    /// Read and verify CRC32 checksum for the given data
438    ///
439    /// # Errors
440    ///
441    /// Returns error if checksum doesn't match or reading fails
442    pub fn verify_checksum(&mut self, data: &[u8]) -> ChieResult<()> {
443        let expected_checksum = self.read_u32()?;
444        if !verify_crc32(data, expected_checksum) {
445            return Err(ChieError::serialization(format!(
446                "Checksum mismatch: expected {expected_checksum}, got {}",
447                calculate_crc32(data)
448            )));
449        }
450        Ok(())
451    }
452
453    /// Get the protocol version from the header
454    #[must_use]
455    pub fn version(&self) -> u8 {
456        self.version
457    }
458
459    /// Get a mutable reference to the underlying reader
460    pub fn get_mut(&mut self) -> &mut R {
461        &mut self.reader
462    }
463
464    /// Consume the decoder and return the underlying reader
465    #[must_use]
466    pub fn into_inner(self) -> R {
467        self.reader
468    }
469
470    /// Read large byte array in chunks with a callback to process each chunk
471    ///
472    /// # Errors
473    ///
474    /// Returns error if reading fails or callback returns error
475    pub fn read_bytes_chunked<F>(&mut self, chunk_size: usize, mut callback: F) -> ChieResult<u64>
476    where
477        F: FnMut(&[u8]) -> ChieResult<()>,
478    {
479        let total_size = u64::from(self.read_u32()?);
480        let mut buffer = vec![0u8; chunk_size];
481        let mut remaining = total_size;
482        let mut total_read = 0u64;
483
484        while remaining > 0 {
485            let to_read = std::cmp::min(remaining, chunk_size as u64) as usize;
486            self.reader
487                .read_exact(&mut buffer[..to_read])
488                .map_err(|e| ChieError::serialization(format!("Failed to read chunk: {e}")))?;
489
490            callback(&buffer[..to_read])?;
491
492            remaining -= to_read as u64;
493            total_read += to_read as u64;
494        }
495
496        Ok(total_read)
497    }
498
499    /// Stream data directly to a writer without buffering entire payload
500    ///
501    /// # Errors
502    ///
503    /// Returns error if copying fails
504    pub fn copy_to_writer<W: Write>(&mut self, writer: &mut W, size: u64) -> ChieResult<u64> {
505        let mut limited_reader = self.reader.by_ref().take(size);
506        std::io::copy(&mut limited_reader, writer)
507            .map_err(|e| ChieError::serialization(format!("Failed to copy to writer: {e}")))
508    }
509}
510
511/// Trait for types that can be encoded to binary format
512pub trait BinaryEncode {
513    /// Encode to binary format
514    ///
515    /// # Errors
516    ///
517    /// Returns error if encoding fails
518    fn encode<W: Write>(&self, encoder: &mut BinaryEncoder<W>) -> ChieResult<()>;
519
520    /// Convenience method to encode to a byte vector
521    ///
522    /// # Errors
523    ///
524    /// Returns error if encoding fails
525    fn encode_to_vec(&self) -> ChieResult<Vec<u8>> {
526        let mut buf = Vec::new();
527        let mut encoder = BinaryEncoder::new(&mut buf);
528        encoder.write_header()?;
529        self.encode(&mut encoder)?;
530        Ok(buf)
531    }
532}
533
534/// Trait for types that can be decoded from binary format
535pub trait BinaryDecode: Sized {
536    /// Decode from binary format
537    ///
538    /// # Errors
539    ///
540    /// Returns error if decoding fails
541    fn decode<R: Read>(decoder: &mut BinaryDecoder<R>) -> ChieResult<Self>;
542
543    /// Convenience method to decode from a byte slice
544    ///
545    /// # Errors
546    ///
547    /// Returns error if decoding fails
548    fn decode_from_slice(bytes: &[u8]) -> ChieResult<Self> {
549        let mut decoder = BinaryDecoder::new(bytes);
550        decoder.read_header()?;
551        Self::decode(&mut decoder)
552    }
553}
554
555/// Batch encoding utilities for efficient bulk operations
556///
557/// # Examples
558///
559/// ```
560/// use chie_shared::encoding::BatchEncoder;
561///
562/// // Encode multiple strings at once
563/// let strings = vec!["hello", "world", "chie"];
564/// let encoded = BatchEncoder::encode_strings(&strings).unwrap();
565/// assert!(!encoded.is_empty());
566/// ```
567pub struct BatchEncoder;
568
569impl BatchEncoder {
570    /// Encode multiple items to a single buffer with length prefix
571    ///
572    /// # Errors
573    ///
574    /// Returns error if encoding fails
575    pub fn encode_batch<T: BinaryEncode>(items: &[T]) -> ChieResult<Vec<u8>> {
576        let mut buf = Vec::new();
577        let mut encoder = BinaryEncoder::new(&mut buf);
578        encoder.write_header()?;
579
580        // Write count
581        let count = u32::try_from(items.len())
582            .map_err(|_| ChieError::serialization("Too many items for batch"))?;
583        encoder.write_u32(count)?;
584
585        // Write each item
586        for item in items {
587            item.encode(&mut encoder)?;
588        }
589
590        Ok(buf)
591    }
592
593    /// Encode multiple strings efficiently
594    ///
595    /// # Errors
596    ///
597    /// Returns error if encoding fails
598    pub fn encode_strings(strings: &[&str]) -> ChieResult<Vec<u8>> {
599        let mut buf = Vec::new();
600        let mut encoder = BinaryEncoder::new(&mut buf);
601        encoder.write_header()?;
602
603        let count = u32::try_from(strings.len())
604            .map_err(|_| ChieError::serialization("Too many strings for batch"))?;
605        encoder.write_u32(count)?;
606
607        for s in strings {
608            encoder.write_string(s)?;
609        }
610
611        Ok(buf)
612    }
613
614    /// Encode multiple u64 values efficiently
615    ///
616    /// # Errors
617    ///
618    /// Returns error if encoding fails
619    pub fn encode_u64_batch(values: &[u64]) -> ChieResult<Vec<u8>> {
620        let mut buf = Vec::new();
621        let mut encoder = BinaryEncoder::new(&mut buf);
622        encoder.write_header()?;
623
624        let count = u32::try_from(values.len())
625            .map_err(|_| ChieError::serialization("Too many values for batch"))?;
626        encoder.write_u32(count)?;
627
628        for &value in values {
629            encoder.write_u64(value)?;
630        }
631
632        Ok(buf)
633    }
634}
635
636/// Batch decoding utilities for efficient bulk operations
637///
638/// # Examples
639///
640/// ```
641/// use chie_shared::encoding::{BatchEncoder, BatchDecoder};
642///
643/// // Encode and decode a batch of strings
644/// let original = vec!["foo", "bar", "baz"];
645/// let encoded = BatchEncoder::encode_strings(&original).unwrap();
646/// let decoded = BatchDecoder::decode_strings(&encoded).unwrap();
647/// assert_eq!(decoded, original);
648/// ```
649pub struct BatchDecoder;
650
651impl BatchDecoder {
652    /// Decode a batch of items with a factory function
653    ///
654    /// # Errors
655    ///
656    /// Returns error if decoding fails
657    pub fn decode_batch<T, F>(bytes: &[u8], mut decode_fn: F) -> ChieResult<Vec<T>>
658    where
659        F: FnMut(&mut BinaryDecoder<&[u8]>) -> ChieResult<T>,
660    {
661        let mut decoder = BinaryDecoder::new(bytes);
662        decoder.read_header()?;
663
664        let count = decoder.read_u32()?;
665        let mut items = Vec::with_capacity(count as usize);
666
667        for _ in 0..count {
668            items.push(decode_fn(&mut decoder)?);
669        }
670
671        Ok(items)
672    }
673
674    /// Decode a batch of strings
675    ///
676    /// # Errors
677    ///
678    /// Returns error if decoding fails
679    pub fn decode_strings(bytes: &[u8]) -> ChieResult<Vec<String>> {
680        Self::decode_batch(bytes, |decoder| decoder.read_string())
681    }
682
683    /// Decode a batch of u64 values
684    ///
685    /// # Errors
686    ///
687    /// Returns error if decoding fails
688    pub fn decode_u64_batch(bytes: &[u8]) -> ChieResult<Vec<u64>> {
689        Self::decode_batch(bytes, |decoder| decoder.read_u64())
690    }
691}
692
693#[cfg(test)]
694mod tests {
695    use super::*;
696
697    #[test]
698    fn test_encode_decode_u8() {
699        let mut buf = Vec::new();
700        let mut encoder = BinaryEncoder::new(&mut buf);
701        encoder.write_u8(42).unwrap();
702
703        let mut decoder = BinaryDecoder::new(&buf[..]);
704        assert_eq!(decoder.read_u8().unwrap(), 42);
705    }
706
707    #[test]
708    fn test_encode_decode_u32() {
709        let mut buf = Vec::new();
710        let mut encoder = BinaryEncoder::new(&mut buf);
711        encoder.write_u32(123_456).unwrap();
712
713        let mut decoder = BinaryDecoder::new(&buf[..]);
714        assert_eq!(decoder.read_u32().unwrap(), 123_456);
715    }
716
717    #[test]
718    fn test_encode_decode_u64() {
719        let mut buf = Vec::new();
720        let mut encoder = BinaryEncoder::new(&mut buf);
721        encoder.write_u64(987_654_321).unwrap();
722
723        let mut decoder = BinaryDecoder::new(&buf[..]);
724        assert_eq!(decoder.read_u64().unwrap(), 987_654_321);
725    }
726
727    #[test]
728    fn test_encode_decode_bytes() {
729        let data = b"Hello, World!";
730        let mut buf = Vec::new();
731        let mut encoder = BinaryEncoder::new(&mut buf);
732        encoder.write_bytes(data).unwrap();
733
734        let mut decoder = BinaryDecoder::new(&buf[..]);
735        let decoded = decoder.read_bytes().unwrap();
736        assert_eq!(decoded, data);
737    }
738
739    #[test]
740    fn test_encode_decode_string() {
741        let s = "Hello, CHIE!";
742        let mut buf = Vec::new();
743        let mut encoder = BinaryEncoder::new(&mut buf);
744        encoder.write_string(s).unwrap();
745
746        let mut decoder = BinaryDecoder::new(&buf[..]);
747        let decoded = decoder.read_string().unwrap();
748        assert_eq!(decoded, s);
749    }
750
751    #[test]
752    fn test_encode_decode_bool() {
753        let mut buf = Vec::new();
754        let mut encoder = BinaryEncoder::new(&mut buf);
755        encoder.write_bool(true).unwrap();
756        encoder.write_bool(false).unwrap();
757
758        let mut decoder = BinaryDecoder::new(&buf[..]);
759        assert!(decoder.read_bool().unwrap());
760        assert!(!decoder.read_bool().unwrap());
761    }
762
763    #[test]
764    fn test_header_roundtrip() {
765        let mut buf = Vec::new();
766        let mut encoder = BinaryEncoder::new(&mut buf);
767        encoder.write_header().unwrap();
768
769        let mut decoder = BinaryDecoder::new(&buf[..]);
770        let version = decoder.read_header().unwrap();
771        assert_eq!(version, BINARY_PROTOCOL_VERSION);
772    }
773
774    #[test]
775    fn test_invalid_magic_bytes() {
776        let buf = b"FAKE\x01";
777        let mut decoder = BinaryDecoder::new(&buf[..]);
778        let result = decoder.read_header();
779        assert!(result.is_err());
780    }
781
782    #[test]
783    fn test_version_compatibility() {
784        // Test that we can read older versions
785        let buf = b"CHIE\x01"; // Version 1
786        let mut decoder = BinaryDecoder::new(&buf[..]);
787        let version = decoder.read_header().unwrap();
788        assert_eq!(version, 1);
789    }
790
791    #[test]
792    fn test_unsupported_version() {
793        // Test that we reject future versions
794        let buf = b"CHIE\xFF"; // Version 255
795        let mut decoder = BinaryDecoder::new(&buf[..]);
796        let result = decoder.read_header();
797        assert!(result.is_err());
798    }
799
800    #[test]
801    fn test_encoder_into_inner() {
802        let mut buf = Vec::new();
803        let mut encoder = BinaryEncoder::new(&mut buf);
804        encoder.write_u32(42).unwrap();
805        let inner = encoder.into_inner();
806        assert_eq!(inner.len(), 4);
807    }
808
809    #[test]
810    fn test_decoder_version() {
811        let buf = b"CHIE\x01";
812        let mut decoder = BinaryDecoder::new(&buf[..]);
813        decoder.read_header().unwrap();
814        assert_eq!(decoder.version(), 1);
815    }
816
817    #[test]
818    fn test_complex_message() {
819        let mut buf = Vec::new();
820        let mut encoder = BinaryEncoder::new(&mut buf);
821        encoder.write_header().unwrap();
822        encoder.write_string("content_id").unwrap();
823        encoder.write_u32(12345).unwrap();
824        encoder.write_u64(67890).unwrap();
825        encoder.write_bool(true).unwrap();
826        encoder.write_bytes(&[1, 2, 3, 4]).unwrap();
827
828        let mut decoder = BinaryDecoder::new(&buf[..]);
829        decoder.read_header().unwrap();
830        assert_eq!(decoder.read_string().unwrap(), "content_id");
831        assert_eq!(decoder.read_u32().unwrap(), 12345);
832        assert_eq!(decoder.read_u64().unwrap(), 67890);
833        assert!(decoder.read_bool().unwrap());
834        assert_eq!(decoder.read_bytes().unwrap(), vec![1, 2, 3, 4]);
835    }
836
837    #[test]
838    fn test_empty_bytes() {
839        let mut buf = Vec::new();
840        let mut encoder = BinaryEncoder::new(&mut buf);
841        encoder.write_bytes(&[]).unwrap();
842
843        let mut decoder = BinaryDecoder::new(&buf[..]);
844        let decoded = decoder.read_bytes().unwrap();
845        assert!(decoded.is_empty());
846    }
847
848    #[test]
849    fn test_empty_string() {
850        let mut buf = Vec::new();
851        let mut encoder = BinaryEncoder::new(&mut buf);
852        encoder.write_string("").unwrap();
853
854        let mut decoder = BinaryDecoder::new(&buf[..]);
855        let decoded = decoder.read_string().unwrap();
856        assert_eq!(decoded, "");
857    }
858
859    #[test]
860    fn test_crc32_calculation() {
861        let data = b"Hello, World!";
862        let crc = calculate_crc32(data);
863        assert_ne!(crc, 0);
864
865        // Same data should produce same checksum
866        assert_eq!(calculate_crc32(data), crc);
867
868        // Different data should produce different checksum
869        let different_data = b"Hello, CHIE!";
870        assert_ne!(calculate_crc32(different_data), crc);
871    }
872
873    #[test]
874    fn test_crc32_verification() {
875        let data = b"Test data";
876        let crc = calculate_crc32(data);
877
878        assert!(verify_crc32(data, crc));
879        assert!(!verify_crc32(data, crc + 1));
880        assert!(!verify_crc32(b"Different data", crc));
881    }
882
883    #[test]
884    fn test_write_verify_checksum() {
885        let data = b"Important message";
886        let mut buf = Vec::new();
887        let mut encoder = BinaryEncoder::new(&mut buf);
888
889        // Write data and its checksum
890        encoder.write_bytes(data).unwrap();
891        encoder.write_checksum(data).unwrap();
892
893        let mut decoder = BinaryDecoder::new(&buf[..]);
894        let decoded_data = decoder.read_bytes().unwrap();
895        assert_eq!(decoded_data, data);
896
897        // Verify checksum
898        decoder.verify_checksum(&decoded_data).unwrap();
899    }
900
901    #[test]
902    fn test_checksum_mismatch() {
903        let data = b"Original data";
904        let mut buf = Vec::new();
905        let mut encoder = BinaryEncoder::new(&mut buf);
906
907        encoder.write_bytes(data).unwrap();
908        encoder.write_checksum(data).unwrap();
909
910        let mut decoder = BinaryDecoder::new(&buf[..]);
911        let _decoded_data = decoder.read_bytes().unwrap();
912
913        // Modify data to cause checksum mismatch
914        let modified_data = b"Modified data";
915        let result = decoder.verify_checksum(modified_data);
916        assert!(result.is_err());
917    }
918
919    #[test]
920    fn test_empty_data_checksum() {
921        let data = b"";
922        let crc = calculate_crc32(data);
923        // CRC32 of empty data is a specific constant
924        assert!(verify_crc32(data, crc));
925
926        // Different empty data should have same checksum
927        assert_eq!(calculate_crc32(b""), crc);
928    }
929
930    // Compression tests
931    #[test]
932    fn test_no_compression() {
933        let compressor = NoCompression;
934        let data = b"Hello, World!";
935
936        let compressed = compressor.compress(data).unwrap();
937        assert_eq!(compressed, data);
938
939        let decompressed = compressor.decompress(&compressed).unwrap();
940        assert_eq!(decompressed, data);
941
942        assert_eq!(compressor.algorithm_id(), "none");
943        assert!(!compressor.should_compress(10_000));
944    }
945
946    #[test]
947    fn test_compression_config_default() {
948        let config = CompressionConfig::default();
949        assert_eq!(config.min_size, 1024);
950        assert!(config.enabled);
951
952        assert!(!config.should_compress(512)); // Below threshold
953        assert!(config.should_compress(2048)); // Above threshold
954    }
955
956    #[test]
957    fn test_compression_config_disabled() {
958        let config = CompressionConfig::disabled();
959        assert!(!config.enabled);
960        assert!(!config.should_compress(10_000)); // Never compress when disabled
961    }
962
963    #[test]
964    fn test_compression_config_custom() {
965        let config = CompressionConfig::new(2048, true);
966        assert_eq!(config.min_size, 2048);
967        assert!(config.enabled);
968
969        assert!(!config.should_compress(1024)); // Below threshold
970        assert!(config.should_compress(4096)); // Above threshold
971    }
972
973    // Streaming serialization tests
974    #[test]
975    fn test_write_bytes_chunked() {
976        let data = vec![1u8; 10_000]; // 10KB of data
977        let mut reader = &data[..];
978        let mut buf = Vec::new();
979        let mut encoder = BinaryEncoder::new(&mut buf);
980
981        encoder
982            .write_bytes_chunked(&mut reader, 10_000, 1024)
983            .unwrap();
984
985        // Verify: 4 bytes for length + 10,000 bytes of data
986        assert_eq!(buf.len(), 4 + 10_000);
987
988        // Decode and verify
989        let mut decoder = BinaryDecoder::new(&buf[..]);
990        let decoded = decoder.read_bytes().unwrap();
991        assert_eq!(decoded, data);
992    }
993
994    #[test]
995    fn test_read_bytes_chunked() {
996        let data = vec![42u8; 5_000];
997        let mut buf = Vec::new();
998        let mut encoder = BinaryEncoder::new(&mut buf);
999        encoder.write_bytes(&data).unwrap();
1000
1001        let mut decoder = BinaryDecoder::new(&buf[..]);
1002        let mut chunks_received = Vec::new();
1003
1004        let total_read = decoder
1005            .read_bytes_chunked(1024, |chunk| {
1006                chunks_received.extend_from_slice(chunk);
1007                Ok(())
1008            })
1009            .unwrap();
1010
1011        assert_eq!(total_read, 5_000);
1012        assert_eq!(chunks_received, data);
1013    }
1014
1015    #[test]
1016    fn test_copy_from_reader() {
1017        let data = b"Stream this data!";
1018        let mut reader = &data[..];
1019        let mut buf = Vec::new();
1020        let mut encoder = BinaryEncoder::new(&mut buf);
1021
1022        let bytes_copied = encoder.copy_from_reader(&mut reader).unwrap();
1023        assert_eq!(bytes_copied, data.len() as u64);
1024        assert_eq!(buf, data);
1025    }
1026
1027    #[test]
1028    fn test_copy_to_writer() {
1029        let data = b"Output this data!";
1030        let mut buf = Vec::new();
1031        let mut encoder = BinaryEncoder::new(&mut buf);
1032        encoder.write_bytes(data).unwrap();
1033
1034        // Now decode and copy to writer
1035        let mut decoder = BinaryDecoder::new(&buf[..]);
1036        let _len = decoder.read_u32().unwrap(); // Read length prefix
1037
1038        let mut output = Vec::new();
1039        let bytes_copied = decoder
1040            .copy_to_writer(&mut output, data.len() as u64)
1041            .unwrap();
1042
1043        assert_eq!(bytes_copied, data.len() as u64);
1044        assert_eq!(output, data);
1045    }
1046
1047    #[test]
1048    fn test_chunked_roundtrip() {
1049        // Test large payload roundtrip
1050        let data = (0..10_000).map(|i| (i % 256) as u8).collect::<Vec<_>>();
1051        let mut reader = &data[..];
1052        let mut buf = Vec::new();
1053        let mut encoder = BinaryEncoder::new(&mut buf);
1054
1055        // Write chunked
1056        encoder
1057            .write_bytes_chunked(&mut reader, data.len() as u64, 512)
1058            .unwrap();
1059
1060        // Read chunked
1061        let mut decoder = BinaryDecoder::new(&buf[..]);
1062        let mut result = Vec::new();
1063        decoder
1064            .read_bytes_chunked(512, |chunk| {
1065                result.extend_from_slice(chunk);
1066                Ok(())
1067            })
1068            .unwrap();
1069
1070        assert_eq!(result, data);
1071    }
1072
1073    #[test]
1074    fn test_chunked_with_exact_chunk_size() {
1075        // Test when data size is exactly a multiple of chunk size
1076        let data = vec![99u8; 2048];
1077        let mut reader = &data[..];
1078        let mut buf = Vec::new();
1079        let mut encoder = BinaryEncoder::new(&mut buf);
1080
1081        encoder.write_bytes_chunked(&mut reader, 2048, 512).unwrap();
1082
1083        let mut decoder = BinaryDecoder::new(&buf[..]);
1084        let mut result = Vec::new();
1085        decoder
1086            .read_bytes_chunked(512, |chunk| {
1087                result.extend_from_slice(chunk);
1088                Ok(())
1089            })
1090            .unwrap();
1091
1092        assert_eq!(result, data);
1093    }
1094
1095    // Batch encoding/decoding tests
1096    #[test]
1097    fn test_batch_encode_decode_strings() {
1098        let strings = vec!["hello", "world", "chie", "protocol"];
1099        let encoded = BatchEncoder::encode_strings(&strings).unwrap();
1100        let decoded = BatchDecoder::decode_strings(&encoded).unwrap();
1101
1102        assert_eq!(decoded.len(), strings.len());
1103        for (original, decoded) in strings.iter().zip(decoded.iter()) {
1104            assert_eq!(original, decoded);
1105        }
1106    }
1107
1108    #[test]
1109    fn test_batch_encode_decode_u64() {
1110        let values = vec![1, 2, 3, 100, 1000, 10_000, u64::MAX];
1111        let encoded = BatchEncoder::encode_u64_batch(&values).unwrap();
1112        let decoded = BatchDecoder::decode_u64_batch(&encoded).unwrap();
1113
1114        assert_eq!(decoded, values);
1115    }
1116
1117    #[test]
1118    fn test_batch_empty() {
1119        let strings: Vec<&str> = vec![];
1120        let encoded = BatchEncoder::encode_strings(&strings).unwrap();
1121        let decoded = BatchDecoder::decode_strings(&encoded).unwrap();
1122
1123        assert_eq!(decoded.len(), 0);
1124    }
1125
1126    #[test]
1127    fn test_batch_single_item() {
1128        let strings = vec!["single"];
1129        let encoded = BatchEncoder::encode_strings(&strings).unwrap();
1130        let decoded = BatchDecoder::decode_strings(&encoded).unwrap();
1131
1132        assert_eq!(decoded, vec!["single"]);
1133    }
1134
1135    #[test]
1136    fn test_batch_large_count() {
1137        // Test with many items
1138        let values: Vec<u64> = (0..1000).collect();
1139        let encoded = BatchEncoder::encode_u64_batch(&values).unwrap();
1140        let decoded = BatchDecoder::decode_u64_batch(&encoded).unwrap();
1141
1142        assert_eq!(decoded, values);
1143    }
1144}