Skip to main content

hitbox_backend/format/
bincode.rs

1use bytes::Bytes;
2use hitbox_core::{BoxContext, Raw};
3
4use super::{
5    BincodeDecoder, BincodeEncoder, Format, FormatDeserializer, FormatError, FormatSerializer,
6    FormatTypeId,
7};
8use crate::context::Context;
9
10/// Writer wrapper for bincode serialization.
11///
12/// Bincode's internal `VecWriter` is not publicly exported, so this provides
13/// the same functionality. This type is exposed in `FormatSerializer::Bincode`
14/// but cannot be constructed outside this crate.
15#[derive(Default)]
16pub(crate) struct BincodeVecWriter(Vec<u8>);
17
18impl BincodeVecWriter {
19    pub(crate) fn new() -> Self {
20        Self(Vec::new())
21    }
22
23    pub(crate) fn into_vec(self) -> Vec<u8> {
24        self.0
25    }
26}
27
28impl ::bincode::enc::write::Writer for BincodeVecWriter {
29    fn write(&mut self, bytes: &[u8]) -> Result<(), ::bincode::error::EncodeError> {
30        self.0.extend_from_slice(bytes);
31        Ok(())
32    }
33}
34
35/// Fast, compact binary serialization.
36///
37/// Produces the smallest output among serde-based formats with good performance.
38/// Not human-readable. Uses bincode's standard configuration.
39#[derive(Debug, Clone, Copy, Default)]
40pub struct BincodeFormat;
41
42impl Format for BincodeFormat {
43    fn with_serializer(
44        &self,
45        f: &mut dyn FnMut(&mut FormatSerializer) -> Result<(), FormatError>,
46        _context: &dyn Context,
47    ) -> Result<Raw, FormatError> {
48        let writer = BincodeVecWriter::new();
49        let config = ::bincode::config::standard();
50        let mut encoder = ::bincode::enc::EncoderImpl::new(writer, config);
51
52        // Create FormatSerializer::Bincode variant with opaque wrapper
53        let mut format_ser = FormatSerializer::Bincode(BincodeEncoder(&mut encoder));
54        f(&mut format_ser)?;
55
56        // Extract the buffer from the encoder
57        let buf = encoder.into_writer().into_vec();
58        Ok(Bytes::from(buf))
59    }
60
61    fn with_deserializer(
62        &self,
63        data: &[u8],
64        f: &mut dyn FnMut(&mut FormatDeserializer) -> Result<(), FormatError>,
65        _ctx: &mut BoxContext,
66    ) -> Result<(), FormatError> {
67        use ::bincode::de::read::SliceReader;
68
69        let reader = SliceReader::new(data);
70        let config = ::bincode::config::standard();
71        let context = (); // Context for the decoder
72        let mut decoder = ::bincode::de::DecoderImpl::new(reader, config, context);
73
74        // Create FormatDeserializer::Bincode variant with opaque wrapper
75        let mut format_deserializer = FormatDeserializer::Bincode(BincodeDecoder(&mut decoder));
76        f(&mut format_deserializer)?;
77
78        Ok(())
79    }
80
81    fn clone_box(&self) -> Box<dyn Format> {
82        Box::new(*self)
83    }
84
85    fn format_type_id(&self) -> FormatTypeId {
86        FormatTypeId::Bincode
87    }
88}