1pub use super::int::LenEnc;
10
11use std::{borrow::Cow, cmp::min, fmt, io, marker::PhantomData};
12
13use bytes::BufMut;
14
15use crate::{
16 io::{BufMutExt, ParseBuf},
17 misc::unexpected_buf_eof,
18 proto::{MyDeserialize, MySerialize},
19};
20
21use super::{int::VarLen, RawInt};
22
23#[derive(Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
27#[repr(transparent)]
28pub struct RawBytes<'a, T: BytesRepr>(pub Cow<'a, [u8]>, PhantomData<T>);
29
30impl<'a, T: BytesRepr> RawBytes<'a, T> {
31 pub fn new(text: impl Into<Cow<'a, [u8]>>) -> Self {
33 Self(text.into(), PhantomData)
34 }
35
36 pub fn into_owned(self) -> RawBytes<'static, T> {
38 RawBytes(Cow::Owned(self.0.into_owned()), PhantomData)
39 }
40
41 pub fn is_empty(&self) -> bool {
43 self.len() == 0
44 }
45
46 pub fn len(&self) -> usize {
48 min(self.0.as_ref().len(), T::MAX_LEN)
49 }
50
51 pub fn as_bytes(&self) -> &[u8] {
53 &self.0.as_ref()[..self.len()]
54 }
55
56 pub fn as_str(&'a self) -> Cow<'a, str> {
58 String::from_utf8_lossy(self.as_bytes())
59 }
60}
61
62impl<'a, T: Into<Cow<'a, [u8]>>, U: BytesRepr> From<T> for RawBytes<'a, U> {
63 fn from(bytes: T) -> RawBytes<'a, U> {
64 RawBytes::new(bytes)
65 }
66}
67
68impl<T: BytesRepr> PartialEq<[u8]> for RawBytes<'_, T> {
69 fn eq(&self, other: &[u8]) -> bool {
70 self.0.as_ref().eq(other)
71 }
72}
73
74impl<T: BytesRepr> MySerialize for RawBytes<'_, T> {
75 fn serialize(&self, buf: &mut Vec<u8>) {
76 T::serialize(self.0.as_ref(), buf)
77 }
78}
79
80impl<'de, T: BytesRepr> MyDeserialize<'de> for RawBytes<'de, T> {
81 const SIZE: Option<usize> = T::SIZE;
82 type Ctx = T::Ctx;
83
84 #[inline(always)]
85 fn deserialize(ctx: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
86 Ok(Self(T::deserialize(ctx, buf)?, PhantomData))
87 }
88}
89
90impl<T: BytesRepr> fmt::Debug for RawBytes<'_, T> {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 f.debug_struct("RawBytes")
93 .field("value", &self.as_str())
94 .field(
95 "max_len",
96 &(if self.0.len() <= T::MAX_LEN {
97 format!("{}", T::MAX_LEN)
98 } else {
99 format!("{} EXCEEDED!", T::MAX_LEN)
100 }),
101 )
102 .finish()
103 }
104}
105
106pub trait BytesRepr {
108 const MAX_LEN: usize;
110 const SIZE: Option<usize>;
111 type Ctx;
112
113 fn serialize(text: &[u8], buf: &mut Vec<u8>);
114
115 fn deserialize<'de>(ctx: Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [u8]>>;
117}
118
119impl BytesRepr for LenEnc {
120 const MAX_LEN: usize = usize::MAX;
121 const SIZE: Option<usize> = None;
122 type Ctx = ();
123
124 fn serialize(text: &[u8], buf: &mut Vec<u8>) {
125 buf.put_lenenc_int(text.len() as u64);
126 buf.put_slice(text);
127 }
128
129 fn deserialize<'de>((): Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [u8]>> {
130 let len = buf.parse::<RawInt<LenEnc>>(())?;
131 buf.checked_eat(len.0 as usize)
132 .map(Cow::Borrowed)
133 .ok_or_else(unexpected_buf_eof)
134 }
135}
136
137#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
141pub struct U8Bytes;
142
143impl BytesRepr for U8Bytes {
144 const MAX_LEN: usize = u8::MAX as usize;
145 const SIZE: Option<usize> = None;
146 type Ctx = ();
147
148 fn serialize(text: &[u8], buf: &mut Vec<u8>) {
149 buf.put_u8_str(text);
150 }
151
152 fn deserialize<'de>((): Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [u8]>> {
153 let len: RawInt<u8> = buf.parse(())?;
154 buf.checked_eat(len.0 as usize)
155 .map(Cow::Borrowed)
156 .ok_or_else(unexpected_buf_eof)
157 }
158}
159
160#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
164pub struct U32Bytes;
165
166impl BytesRepr for U32Bytes {
167 const MAX_LEN: usize = u32::MAX as usize;
168 const SIZE: Option<usize> = None;
169 type Ctx = ();
170
171 fn serialize(text: &[u8], buf: &mut Vec<u8>) {
172 buf.put_u32_str(text);
173 }
174
175 fn deserialize<'de>((): Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [u8]>> {
176 buf.checked_eat_u32_str()
177 .map(Cow::Borrowed)
178 .ok_or_else(unexpected_buf_eof)
179 }
180}
181
182#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
186pub struct NullBytes;
187
188impl BytesRepr for NullBytes {
189 const MAX_LEN: usize = usize::MAX;
190 const SIZE: Option<usize> = None;
191 type Ctx = ();
192
193 fn serialize(text: &[u8], buf: &mut Vec<u8>) {
194 let last = text.iter().position(|x| *x == 0).unwrap_or(text.len());
195 buf.put_slice(&text[..last]);
196 buf.put_u8(0);
197 }
198
199 fn deserialize<'de>((): Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [u8]>> {
200 match buf.0.iter().position(|x| *x == 0) {
201 Some(i) => {
202 let out = buf.eat(i);
203 buf.skip(1);
204 Ok(Cow::Borrowed(out))
205 }
206 None => Err(io::Error::new(
207 io::ErrorKind::InvalidData,
208 "no null terminator for null-terminated string",
209 )),
210 }
211 }
212}
213
214#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
216pub struct EofBytes;
217
218impl BytesRepr for EofBytes {
219 const MAX_LEN: usize = usize::MAX;
220 const SIZE: Option<usize> = None;
221 type Ctx = ();
222
223 fn serialize(text: &[u8], buf: &mut Vec<u8>) {
224 buf.put_slice(text);
225 }
226
227 fn deserialize<'de>((): Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [u8]>> {
228 Ok(Cow::Borrowed(buf.eat_all()))
229 }
230}
231
232#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
236pub struct BareBytes<const MAX_LEN: usize>;
237
238impl<const MAX_LEN: usize> BytesRepr for BareBytes<MAX_LEN> {
239 const MAX_LEN: usize = MAX_LEN;
240 const SIZE: Option<usize> = None;
241 type Ctx = usize;
242
243 fn serialize(text: &[u8], buf: &mut Vec<u8>) {
244 let len = min(text.len(), MAX_LEN);
245 buf.put_slice(&text[..len]);
246 }
247
248 fn deserialize<'de>(len: usize, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [u8]>> {
249 buf.checked_eat(len)
250 .ok_or_else(unexpected_buf_eof)
251 .map(Cow::Borrowed)
252 }
253}
254
255pub type BareU8Bytes = BareBytes<{ u8::MAX as usize }>;
257
258pub type BareU16Bytes = BareBytes<{ u16::MAX as usize }>;
260
261#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
265pub struct FixedLengthText<const LEN: usize>;
266
267impl<const LEN: usize> BytesRepr for FixedLengthText<LEN> {
268 const MAX_LEN: usize = LEN;
269 const SIZE: Option<usize> = Some(LEN);
270 type Ctx = ();
271
272 fn serialize(text: &[u8], buf: &mut Vec<u8>) {
273 let len = min(LEN, text.len());
274 buf.put_slice(&text[..len]);
275 for _ in 0..(LEN - len) {
276 buf.put_u8(0);
277 }
278 }
279
280 fn deserialize<'de>((): Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [u8]>> {
281 match Self::SIZE {
282 Some(len) => Ok(Cow::Borrowed(buf.eat(len))),
283 None => buf
284 .checked_eat(LEN)
285 .map(Cow::Borrowed)
286 .ok_or_else(unexpected_buf_eof),
287 }
288 }
289}
290
291impl BytesRepr for VarLen {
292 const MAX_LEN: usize = u32::MAX as usize;
293 const SIZE: Option<usize> = None;
294 type Ctx = ();
295
296 fn serialize(text: &[u8], buf: &mut Vec<u8>) {
297 buf.put_lenenc_int(text.len() as u64);
298 buf.put_slice(text);
299 }
300
301 fn deserialize<'de>((): Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Cow<'de, [u8]>> {
302 let len = buf.parse::<RawInt<VarLen>>(())?;
303 buf.checked_eat(len.0 as usize)
304 .map(Cow::Borrowed)
305 .ok_or_else(unexpected_buf_eof)
306 }
307}
308
309#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
311pub struct ConstBytes<T, const LEN: usize>(PhantomData<T>);
312
313pub trait ConstBytesValue<const LEN: usize> {
314 const VALUE: [u8; LEN];
315 type Error: Default + std::error::Error + Send + Sync + 'static;
316}
317
318impl<'de, T, const LEN: usize> MyDeserialize<'de> for ConstBytes<T, LEN>
319where
320 T: Default,
321 T: ConstBytesValue<LEN>,
322{
323 const SIZE: Option<usize> = Some(LEN);
324 type Ctx = ();
325
326 fn deserialize((): Self::Ctx, buf: &mut ParseBuf<'de>) -> io::Result<Self> {
327 let bytes: [u8; LEN] = buf.parse_unchecked(())?;
328 if bytes == T::VALUE {
329 Ok(Default::default())
330 } else {
331 Err(io::Error::new(
332 io::ErrorKind::InvalidData,
333 T::Error::default(),
334 ))
335 }
336 }
337}
338
339impl<T, const LEN: usize> MySerialize for ConstBytes<T, LEN>
340where
341 T: ConstBytesValue<LEN>,
342{
343 fn serialize(&self, buf: &mut Vec<u8>) {
344 T::VALUE.serialize(buf)
345 }
346}