spacetimedb_sats/bsatn/
ser.rs

1use crate::buffer::BufWriter;
2use crate::de::DeserializeSeed;
3use crate::ser::{self, Error, ForwardNamedToSeqProduct, SerializeArray, SerializeSeqProduct};
4use crate::{i256, u256};
5use crate::{AlgebraicValue, WithTypespace};
6use core::fmt;
7
8/// Defines the BSATN serialization data format.
9pub struct Serializer<'a, W> {
10    writer: &'a mut W,
11}
12
13impl<'a, W> Serializer<'a, W> {
14    /// Returns a serializer using the given `writer`.
15    pub fn new(writer: &'a mut W) -> Self {
16        Self { writer }
17    }
18
19    /// Reborrows the serializer.
20    #[inline]
21    fn reborrow(&mut self) -> Serializer<'_, W> {
22        Serializer { writer: self.writer }
23    }
24}
25
26impl<W: BufWriter> Serializer<'_, W> {
27    /// Directly write `bytes` to the writer.
28    /// This is a raw API. Only use this if you know what you are doing.
29    #[inline(always)]
30    #[doc(hidden)]
31    pub fn raw_write_bytes(self, bytes: &[u8]) {
32        self.writer.put_slice(bytes);
33    }
34}
35
36/// An error during BSATN serialization.
37#[derive(Debug, Clone)]
38// TODO: rename to EncodeError
39pub struct BsatnError {
40    /// The error message for the BSATN error.
41    custom: String,
42}
43
44impl fmt::Display for BsatnError {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        f.write_str(&self.custom)
47    }
48}
49impl std::error::Error for BsatnError {}
50
51impl Error for BsatnError {
52    fn custom<T: fmt::Display>(msg: T) -> Self {
53        let custom = msg.to_string();
54        Self { custom }
55    }
56}
57
58/// Writes `len` converted to a `u32` to `writer`.
59///
60/// Errors if `len` would not fit in a `u32`.
61fn put_len(writer: &mut impl BufWriter, len: usize) -> Result<(), BsatnError> {
62    let len = len.try_into().map_err(|_| BsatnError::custom("len too long"))?;
63    writer.put_u32(len);
64    Ok(())
65}
66
67impl<W: BufWriter> ser::Serializer for Serializer<'_, W> {
68    type Ok = ();
69    type Error = BsatnError;
70    type SerializeArray = Self;
71    type SerializeSeqProduct = Self;
72    type SerializeNamedProduct = ForwardNamedToSeqProduct<Self>;
73
74    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
75        self.writer.put_u8(v as u8);
76        Ok(())
77    }
78    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
79        self.writer.put_u8(v);
80        Ok(())
81    }
82    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
83        self.writer.put_u16(v);
84        Ok(())
85    }
86    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
87        self.writer.put_u32(v);
88        Ok(())
89    }
90    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
91        self.writer.put_u64(v);
92        Ok(())
93    }
94    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
95        self.writer.put_u128(v);
96        Ok(())
97    }
98    fn serialize_u256(self, v: u256) -> Result<Self::Ok, Self::Error> {
99        self.writer.put_u256(v);
100        Ok(())
101    }
102    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
103        self.writer.put_i8(v);
104        Ok(())
105    }
106    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
107        self.writer.put_i16(v);
108        Ok(())
109    }
110    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
111        self.writer.put_i32(v);
112        Ok(())
113    }
114    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
115        self.writer.put_i64(v);
116        Ok(())
117    }
118    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
119        self.writer.put_i128(v);
120        Ok(())
121    }
122    fn serialize_i256(self, v: i256) -> Result<Self::Ok, Self::Error> {
123        self.writer.put_i256(v);
124        Ok(())
125    }
126    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
127        self.writer.put_u32(v.to_bits());
128        Ok(())
129    }
130    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
131        self.writer.put_u64(v.to_bits());
132        Ok(())
133    }
134    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
135        self.serialize_bytes(v.as_bytes())
136    }
137    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
138        put_len(self.writer, v.len())?; // N.B. `v.len() > u32::MAX` isn't allowed.
139        self.writer.put_slice(v);
140        Ok(())
141    }
142    fn serialize_array(self, len: usize) -> Result<Self::SerializeArray, Self::Error> {
143        put_len(self.writer, len)?; // N.B. `len > u32::MAX` isn't allowed.
144        Ok(self)
145    }
146    fn serialize_seq_product(self, _len: usize) -> Result<Self::SerializeSeqProduct, Self::Error> {
147        Ok(self)
148    }
149    fn serialize_named_product(self, len: usize) -> Result<Self::SerializeNamedProduct, Self::Error> {
150        // Serialize named like unnamed.
151        self.serialize_seq_product(len).map(ForwardNamedToSeqProduct::new)
152    }
153    fn serialize_variant<T: super::Serialize + ?Sized>(
154        self,
155        tag: u8,
156        _name: Option<&str>,
157        value: &T,
158    ) -> Result<Self::Ok, Self::Error> {
159        self.writer.put_u8(tag);
160        value.serialize(self)
161    }
162
163    unsafe fn serialize_bsatn<Ty>(self, ty: &Ty, bsatn: &[u8]) -> Result<Self::Ok, Self::Error>
164    where
165        for<'a, 'de> WithTypespace<'a, Ty>: DeserializeSeed<'de, Output: Into<AlgebraicValue>>,
166    {
167        debug_assert!(crate::bsatn::decode(ty, &mut { bsatn }).is_ok());
168        self.writer.put_slice(bsatn);
169        Ok(())
170    }
171
172    unsafe fn serialize_bsatn_in_chunks<'a, Ty, I: Clone + Iterator<Item = &'a [u8]>>(
173        self,
174        ty: &Ty,
175        total_bsatn_len: usize,
176        bsatn: I,
177    ) -> Result<Self::Ok, Self::Error>
178    where
179        for<'b, 'de> WithTypespace<'b, Ty>: DeserializeSeed<'de, Output: Into<AlgebraicValue>>,
180    {
181        debug_assert!(total_bsatn_len <= isize::MAX as usize);
182        debug_assert!(crate::bsatn::decode(ty, &mut &*concat_bytes_slow(total_bsatn_len, bsatn.clone())).is_ok());
183
184        for chunk in bsatn {
185            self.writer.put_slice(chunk);
186        }
187        Ok(())
188    }
189
190    unsafe fn serialize_str_in_chunks<'a, I: Clone + Iterator<Item = &'a [u8]>>(
191        self,
192        total_len: usize,
193        string: I,
194    ) -> Result<Self::Ok, Self::Error> {
195        debug_assert!(total_len <= isize::MAX as usize);
196        debug_assert!(String::from_utf8(concat_bytes_slow(total_len, string.clone())).is_ok());
197
198        // We need to len-prefix to make this BSATN.
199        put_len(self.writer, total_len)?;
200
201        for chunk in string {
202            self.writer.put_slice(chunk);
203        }
204        Ok(())
205    }
206}
207
208/// Concatenates `chunks` into a `Vec<u8>`.
209fn concat_bytes_slow<'a>(cap: usize, chunks: impl Iterator<Item = &'a [u8]>) -> Vec<u8> {
210    let mut bytes = Vec::with_capacity(cap);
211    for chunk in chunks {
212        bytes.extend(chunk);
213    }
214    assert_eq!(bytes.len(), cap);
215    bytes
216}
217
218impl<W: BufWriter> SerializeArray for Serializer<'_, W> {
219    type Ok = ();
220    type Error = BsatnError;
221
222    fn serialize_element<T: super::Serialize + ?Sized>(&mut self, elem: &T) -> Result<(), Self::Error> {
223        elem.serialize(self.reborrow())
224    }
225
226    fn end(self) -> Result<Self::Ok, Self::Error> {
227        Ok(())
228    }
229}
230
231impl<W: BufWriter> SerializeSeqProduct for Serializer<'_, W> {
232    type Ok = ();
233    type Error = BsatnError;
234
235    fn serialize_element<T: super::Serialize + ?Sized>(&mut self, elem: &T) -> Result<(), Self::Error> {
236        elem.serialize(self.reborrow())
237    }
238    fn end(self) -> Result<Self::Ok, Self::Error> {
239        Ok(())
240    }
241}