1use core::mem::MaybeUninit;
2
3use crate::buffer::{BufReader, BufWriter, CountWriter};
4use crate::de::{BasicSmallVecVisitor, Deserialize, DeserializeSeed, Deserializer as _};
5use crate::ser::Serialize;
6use crate::{ProductValue, Typespace, WithTypespace};
7use bytes::BytesMut;
8use ser::BsatnError;
9use smallvec::SmallVec;
10
11pub mod de;
12pub mod eq;
13pub mod ser;
14
15pub use de::Deserializer;
16pub use ser::Serializer;
17
18pub use crate::buffer::DecodeError;
19pub use ser::BsatnError as EncodeError;
20
21#[inline]
23pub fn to_writer<W: BufWriter, T: Serialize + ?Sized>(w: &mut W, value: &T) -> Result<(), EncodeError> {
24 value.serialize_into_bsatn(Serializer::new(w))
25}
26
27pub fn to_vec<T: Serialize + ?Sized>(value: &T) -> Result<Vec<u8>, EncodeError> {
29 let mut v = Vec::new();
30 to_writer(&mut v, value)?;
31 Ok(v)
32}
33
34pub fn to_len<T: Serialize + ?Sized>(value: &T) -> Result<usize, EncodeError> {
36 let mut writer = CountWriter::default();
37 to_writer(&mut writer, value)?;
38 Ok(writer.finish())
39}
40
41pub fn from_reader<'de, T: Deserialize<'de>>(reader: &mut impl BufReader<'de>) -> Result<T, DecodeError> {
43 T::deserialize(Deserializer::new(reader))
44}
45
46pub fn from_slice<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result<T, DecodeError> {
48 from_reader(&mut &*bytes)
49}
50
51pub fn decode<'a, 'de, S: ?Sized>(
53 ty: &'a S,
54 bytes: &mut impl BufReader<'de>,
55) -> Result<<WithTypespace<'a, S> as DeserializeSeed<'de>>::Output, DecodeError>
56where
57 WithTypespace<'a, S>: DeserializeSeed<'de>,
58{
59 crate::WithTypespace::empty(ty).deserialize(Deserializer::new(bytes))
60}
61
62macro_rules! codec_funcs {
63 ($ty:ty) => {
64 impl $ty {
65 pub fn decode<'a>(bytes: &mut impl BufReader<'a>) -> Result<Self, DecodeError> {
66 from_reader(bytes)
67 }
68
69 pub fn encode(&self, bytes: &mut impl BufWriter) {
70 to_writer(bytes, self).unwrap()
71 }
72 }
73 };
74 (val: $ty:ty) => {
75 impl $ty {
76 pub fn decode<'a>(
78 ty: &<Self as crate::Value>::Type,
79 bytes: &mut impl BufReader<'a>,
80 ) -> Result<Self, DecodeError> {
81 decode(ty, bytes)
82 }
83
84 pub fn decode_smallvec<'a>(
86 ty: &<Self as crate::Value>::Type,
87 bytes: &mut impl BufReader<'a>,
88 ) -> Result<SmallVec<[Self; 1]>, DecodeError> {
89 Deserializer::new(bytes).deserialize_array_seed(
90 BasicSmallVecVisitor,
91 crate::WithTypespace::new(&Typespace::new(Vec::new()), ty),
92 )
93 }
94
95 pub fn encode(&self, bytes: &mut impl BufWriter) {
96 to_writer(bytes, self).unwrap()
97 }
98 }
99 };
100}
101
102codec_funcs!(crate::AlgebraicType);
103codec_funcs!(crate::ProductType);
104codec_funcs!(crate::SumType);
105codec_funcs!(crate::ProductTypeElement);
106codec_funcs!(crate::SumTypeVariant);
107
108codec_funcs!(val: crate::AlgebraicValue);
109codec_funcs!(val: crate::ProductValue);
110codec_funcs!(val: crate::SumValue);
111
112pub trait BufReservedFill {
115 unsafe fn reserve_and_fill(&mut self, len: usize, fill: impl FnOnce(&mut [MaybeUninit<u8>]));
122}
123
124impl BufReservedFill for Vec<u8> {
125 unsafe fn reserve_and_fill(&mut self, len: usize, fill: impl FnOnce(&mut [MaybeUninit<u8>])) {
126 let start = self.len();
128 self.reserve(len);
129 let sink = &mut self.spare_capacity_mut()[..len];
130
131 fill(sink);
133
134 unsafe { self.set_len(start + len) }
138 }
139}
140
141impl BufReservedFill for BytesMut {
142 unsafe fn reserve_and_fill(&mut self, len: usize, fill: impl FnOnce(&mut [MaybeUninit<u8>])) {
143 let start = self.len();
145 self.reserve(len);
146 let sink = &mut self.spare_capacity_mut()[..len];
147
148 fill(sink);
150
151 unsafe { self.set_len(start + len) }
155 }
156}
157
158pub trait ToBsatn {
164 fn to_bsatn_vec(&self) -> Result<Vec<u8>, BsatnError>;
166
167 fn to_bsatn_extend(&self, buf: &mut (impl BufWriter + BufReservedFill)) -> Result<(), BsatnError>;
170
171 fn static_bsatn_size(&self) -> Option<u16>;
175}
176
177impl<T: ToBsatn> ToBsatn for &T {
178 fn to_bsatn_vec(&self) -> Result<Vec<u8>, BsatnError> {
179 T::to_bsatn_vec(*self)
180 }
181 fn to_bsatn_extend(&self, buf: &mut (impl BufWriter + BufReservedFill)) -> Result<(), BsatnError> {
182 T::to_bsatn_extend(*self, buf)
183 }
184 fn static_bsatn_size(&self) -> Option<u16> {
185 T::static_bsatn_size(*self)
186 }
187}
188
189impl ToBsatn for ProductValue {
190 fn to_bsatn_vec(&self) -> Result<Vec<u8>, BsatnError> {
191 to_vec(self)
192 }
193
194 fn to_bsatn_extend(&self, buf: &mut (impl BufWriter + BufReservedFill)) -> Result<(), BsatnError> {
195 to_writer(buf, self)
196 }
197
198 fn static_bsatn_size(&self) -> Option<u16> {
199 None
200 }
201}
202
203mod private_is_primitive_type {
204 pub trait Sealed {}
205}
206#[doc(hidden)]
213pub unsafe trait IsPrimitiveType: private_is_primitive_type::Sealed {}
214macro_rules! is_primitive_type {
215 ($($prim:ty),*) => {
216 $(
217 impl private_is_primitive_type::Sealed for $prim {}
218 unsafe impl IsPrimitiveType for $prim {}
220 )*
221 };
222}
223is_primitive_type!(u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, f32, f64);
224
225pub const fn assert_is_primitive_type<T: IsPrimitiveType>() {}
228
229#[cfg(test)]
230mod tests {
231 use super::{to_vec, DecodeError, Deserializer};
232 use crate::de::DeserializeSeed;
233 use crate::proptest::{generate_algebraic_type, generate_typed_value};
234 use crate::{meta_type::MetaType, AlgebraicType, AlgebraicValue, WithTypespace};
235 use proptest::prelude::*;
236 use proptest::{collection::vec, proptest};
237
238 #[test]
239 fn type_to_binary_equivalent() {
240 check_type(&AlgebraicType::meta_type());
241 }
242
243 #[track_caller]
244 fn check_type(ty: &AlgebraicType) {
245 let mut through_value = Vec::new();
246 ty.as_value().encode(&mut through_value);
247 let mut direct = Vec::new();
248 ty.encode(&mut direct);
249 assert_eq!(direct, through_value);
250 }
251
252 fn type_non_empty(ty: &AlgebraicType) -> bool {
253 match ty {
254 AlgebraicType::Ref(_) => unreachable!(),
255 AlgebraicType::Array(elem_ty) => type_non_empty(&elem_ty.elem_ty),
256 AlgebraicType::Product(elems) => elems.iter().any(|e| type_non_empty(&e.algebraic_type)),
257 AlgebraicType::Sum(vars) => !vars.is_empty(),
258 _ => true,
259 }
260 }
261
262 proptest! {
263 #[test]
264 fn bsatn_enc_de_roundtrips((ty, val) in generate_typed_value()) {
265 let bytes = to_vec(&val).unwrap();
266 prop_assert_eq!(WithTypespace::empty(&ty).validate(Deserializer::new(&mut &bytes[..])), Ok(()));
267 let val_decoded = AlgebraicValue::decode(&ty, &mut &bytes[..]).unwrap();
268 prop_assert_eq!(val, val_decoded);
269 }
270
271 #[test]
272 fn bsatn_invalid_wont_decode(ty in generate_algebraic_type(), bytes in vec(any::<u8>(), 0..4096)) {
273 prop_assume!(type_non_empty(&ty));
274 prop_assume!(WithTypespace::empty(&ty).validate(Deserializer::new(&mut &bytes[..])).is_err());
275 prop_assert!(AlgebraicValue::decode(&ty, &mut &bytes[..]).is_err());
276 }
277
278 #[test]
279 fn bsatn_non_zero_one_u8_aint_bool(val in 2u8..) {
280 let bytes = [val];
281 prop_assert_eq!(
282 AlgebraicValue::decode(&AlgebraicType::Bool, &mut &bytes[..]),
283 Err(DecodeError::InvalidBool(val))
284 );
285 }
286 }
287}