deser_core/adapters/bytes/
impls.rs1use alloc::borrow::Cow;
3use alloc::format;
4use alloc::vec::Vec;
5use core::marker::PhantomData;
6
7use crate::BytesFormat;
8use crate::State;
9use crate::adapters::bytes::BytesEncoding;
10use crate::adapters::{DeserializeAs, SerializeAs};
11use crate::de::{Deserialize, Sink, SinkHandle};
12use crate::error::{Error, ErrorKind};
13use crate::event::{Atom, Bytes, ContainerShape};
14use crate::ser::{Begin, Chunk};
15
16mod sealed {
17 use super::*;
18
19 pub trait BytesBufImpl: Sized + Send + Sync {
20 fn bytes(&self) -> &[u8];
21 fn from_vec(bytes: Vec<u8>) -> Result<Self, Error>;
22 fn deserialize_into<'a, 'de>(
23 out: &'a mut Option<Self>,
24 state: &mut State,
25 ) -> SinkHandle<'a, 'de>;
26 }
27
28 pub trait BytesFallbackFormatImpl: 'static {
29 const FORMAT: BytesFormat;
30 fn deserialize_into<'a, 'de, T: BytesBufImpl>(
31 out: &'a mut Option<T>,
32 state: &mut State,
33 ) -> SinkHandle<'a, 'de>;
34 }
35}
36
37pub(crate) use self::sealed::BytesBufImpl;
38use self::sealed::BytesFallbackFormatImpl;
39
40pub trait BytesBuf: BytesBufImpl {}
48
49impl<T: BytesBufImpl> BytesBuf for T {}
50
51impl BytesBufImpl for Vec<u8> {
52 #[inline]
53 fn bytes(&self) -> &[u8] {
54 self
55 }
56
57 #[inline]
58 fn from_vec(bytes: Vec<u8>) -> Result<Self, Error> {
59 Ok(bytes)
60 }
61
62 #[inline]
63 fn deserialize_into<'a, 'de>(
64 out: &'a mut Option<Self>,
65 state: &mut State,
66 ) -> SinkHandle<'a, 'de> {
67 Deserialize::deserialize_into(out, state)
68 }
69}
70
71impl<const N: usize> BytesBufImpl for [u8; N] {
72 #[inline]
73 fn bytes(&self) -> &[u8] {
74 self
75 }
76
77 fn from_vec(bytes: Vec<u8>) -> Result<Self, Error> {
78 bytes
79 .try_into()
80 .map_err(|_| Error::new(ErrorKind::WrongLength, "byte array of wrong length"))
81 }
82
83 #[inline]
84 fn deserialize_into<'a, 'de>(
85 out: &'a mut Option<Self>,
86 state: &mut State,
87 ) -> SinkHandle<'a, 'de> {
88 Deserialize::deserialize_into(out, state)
89 }
90}
91
92impl<'c> BytesBufImpl for Cow<'c, [u8]> {
93 #[inline]
94 fn bytes(&self) -> &[u8] {
95 self
96 }
97
98 #[inline]
99 fn from_vec(bytes: Vec<u8>) -> Result<Self, Error> {
100 Ok(Cow::Owned(bytes))
101 }
102
103 #[inline]
104 fn deserialize_into<'a, 'de>(
105 out: &'a mut Option<Self>,
106 state: &mut State,
107 ) -> SinkHandle<'a, 'de> {
108 Deserialize::deserialize_into(out, state)
109 }
110}
111
112pub trait BytesFallbackFormat: BytesFallbackFormatImpl {}
118
119impl<F: BytesFallbackFormatImpl> BytesFallbackFormat for F {}
120
121impl<E: BytesEncoding> BytesFallbackFormatImpl for E {
122 const FORMAT: BytesFormat = BytesFormat::encoded::<E>();
123
124 #[inline]
125 fn deserialize_into<'a, 'de, T: BytesBufImpl>(
126 out: &'a mut Option<T>,
127 state: &mut State,
128 ) -> SinkHandle<'a, 'de> {
129 encoded_handle::<T, E>(out, state)
130 }
131}
132
133pub struct IntSeq;
139
140impl BytesFallbackFormatImpl for IntSeq {
141 const FORMAT: BytesFormat = BytesFormat::SEQ;
142
143 #[inline]
144 fn deserialize_into<'a, 'de, T: BytesBufImpl>(
145 out: &'a mut Option<T>,
146 state: &mut State,
147 ) -> SinkHandle<'a, 'de> {
148 T::deserialize_into(out, state)
150 }
151}
152
153struct EncodedSink<'a, T, E> {
155 out: &'a mut Option<T>,
156 _marker: PhantomData<fn() -> E>,
157}
158
159impl<'a, 'de, T: BytesBufImpl, E: BytesEncoding> Sink<'de> for EncodedSink<'a, T, E> {
160 fn expecting(&self) -> Cow<'_, str> {
161 Cow::Owned(format!("bytes or {} string", E::NAME))
162 }
163
164 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
165 let bytes = match atom {
166 Atom::Bytes(value) => value.into_data().into_owned(),
167 Atom::Str(value) => E::decode(&value)?,
168 other => return self.unexpected_atom(other, state),
169 };
170 *self.out = Some(T::from_vec(bytes)?);
171 Ok(())
172 }
173}
174
175#[inline]
176pub(crate) fn encoded_handle<'a, 'de, T: BytesBufImpl, E: BytesEncoding>(
177 out: &'a mut Option<T>,
178 state: &mut State,
179) -> SinkHandle<'a, 'de> {
180 SinkHandle::arena(
181 EncodedSink::<T, E> {
182 out,
183 _marker: PhantomData,
184 },
185 state,
186 )
187}
188
189macro_rules! encoding_adapter {
195 ($([$($gen:tt)*] $ty:ty),* $(,)?) => {
196 $(
197 impl<$($gen)* E: $crate::adapters::BytesEncoding> $crate::adapters::SerializeAs<$ty> for E {
198 fn serialize_as<'a>(
199 value: &'a $ty,
200 _state: &mut $crate::State,
201 ) -> Result<$crate::ser::Chunk<'a>, $crate::Error> {
202 let mut rv = alloc::string::String::new();
203 E::encode(
204 $crate::adapters::bytes::BytesBufImpl::bytes(value),
205 &mut rv,
206 );
207 Ok($crate::ser::Chunk::Atom($crate::Atom::Str($crate::Text::owned(rv))))
208 }
209
210 #[inline]
211 fn __private_begin_as<'a>(
212 value: &'a $ty,
213 state: &mut $crate::State,
214 ) -> Result<$crate::ser::Begin<'a>, $crate::Error> {
215 Ok($crate::ser::Begin::chunk(
216 Self::serialize_as(value, state)?,
217 $crate::ContainerShape::new(),
218 false,
219 ))
220 }
221 }
222
223 impl<'de, $($gen)* E: $crate::adapters::BytesEncoding>
224 $crate::adapters::DeserializeAs<'de, $ty> for E
225 {
226 #[inline]
227 fn deserialize_into_as<'a>(
228 out: &'a mut Option<$ty>, state: &mut $crate::State) -> $crate::de::SinkHandle<'a, 'de> {
229 $crate::adapters::bytes::encoded_handle::<$ty, E>(out, state)
230 }
231 }
232 )*
233 };
234}
235
236#[allow(unused_imports)]
238pub(crate) use encoding_adapter;
239
240encoding_adapter!(
241 [] Vec<u8>,
242 [const N: usize,] [u8; N],
243 ['c,] Cow<'c, [u8]>,
244);
245
246pub struct BytesFallback<F>(PhantomData<fn() -> F>);
277
278impl<T: BytesBuf, F: BytesFallbackFormat> SerializeAs<T> for BytesFallback<F> {
279 #[inline]
280 fn serialize_as<'a>(value: &'a T, _state: &mut State) -> Result<Chunk<'a>, Error> {
281 Ok(Chunk::Atom(Atom::Bytes(
282 Bytes::borrowed(value.bytes()).with_fallback(const { &F::FORMAT }),
283 )))
284 }
285
286 #[inline]
287 fn __private_begin_as<'a>(value: &'a T, state: &mut State) -> Result<Begin<'a>, Error> {
288 Ok(Begin::chunk(
289 Self::serialize_as(value, state)?,
290 ContainerShape::new(),
291 false,
292 ))
293 }
294}
295
296impl<'de, T: BytesBuf, F: BytesFallbackFormat> DeserializeAs<'de, T> for BytesFallback<F> {
297 #[inline]
298 fn deserialize_into_as<'out>(
299 out: &'out mut Option<T>,
300 state: &mut State,
301 ) -> SinkHandle<'out, 'de> {
302 F::deserialize_into(out, state)
303 }
304}