1use ::core::future::Future;
2
3use leb128_tokio::{
4 Leb128DecoderI16, Leb128DecoderI32, Leb128DecoderI64, Leb128DecoderU16, Leb128DecoderU32,
5 Leb128DecoderU64, Leb128Encoder,
6};
7use tokio::io::{AsyncRead, AsyncReadExt as _, AsyncWrite, AsyncWriteExt as _};
8use tokio_util::bytes::{Buf as _, BufMut as _, Bytes, BytesMut};
9use tokio_util::codec::{Decoder, Encoder};
10use utf8_tokio::Utf8Codec;
11
12use crate::CoreNameEncoder;
13
14macro_rules! ensure_capacity {
15 ($src:ident, $n:expr) => {
16 if let Some(n) = $n.checked_sub($src.len()) {
17 if n > 0 {
18 $src.reserve(n);
19 return Ok(None);
20 }
21 }
22 };
23}
24
25macro_rules! impl_encode_copy_ref {
26 ($enc:ident, $t:ty) => {
27 impl Encoder<&$t> for $enc {
28 type Error = std::io::Error;
29
30 #[cfg_attr(
31 feature = "tracing",
32 tracing::instrument(level = "trace", ret, fields(ty = stringify!($t)))
33 )]
34 fn encode(&mut self, item: &$t, dst: &mut BytesMut) -> Result<(), Self::Error> {
35 self.encode(*item, dst)
36 }
37 }
38
39 impl Encoder<&&$t> for $enc {
40 type Error = std::io::Error;
41
42 #[cfg_attr(
43 feature = "tracing",
44 tracing::instrument(level = "trace", ret, fields(ty = stringify!($t)))
45 )]
46 fn encode(&mut self, item: &&$t, dst: &mut BytesMut) -> Result<(), Self::Error> {
47 self.encode(**item, dst)
48 }
49 }
50 };
51}
52
53macro_rules! impl_encode_str {
54 ($enc:ident, $t:ty) => {
55 impl Encoder<$t> for $enc {
56 type Error = std::io::Error;
57
58 #[cfg_attr(
59 feature = "tracing",
60 tracing::instrument(level = "trace", ret, fields(ty = "string"))
61 )]
62 fn encode(&mut self, item: $t, dst: &mut BytesMut) -> Result<(), Self::Error> {
63 CoreNameEncoder.encode(item, dst)
64 }
65 }
66
67 impl Encoder<&$t> for $enc {
68 type Error = std::io::Error;
69
70 #[cfg_attr(
71 feature = "tracing",
72 tracing::instrument(level = "trace", ret, fields(ty = "string"))
73 )]
74 fn encode(&mut self, item: &$t, dst: &mut BytesMut) -> Result<(), Self::Error> {
75 CoreNameEncoder.encode(item, dst)
76 }
77 }
78 };
79}
80
81pub trait AsyncReadValue: AsyncRead {
82 #[cfg_attr(
83 feature = "tracing",
84 tracing::instrument(level = "trace", ret, skip_all, fields(ty = "bool"))
85 )]
86 fn read_bool(&mut self) -> impl Future<Output = std::io::Result<bool>>
87 where
88 Self: Unpin,
89 {
90 async move {
91 match self.read_u8().await? {
92 0 => Ok(false),
93 1 => Ok(true),
94 n => Err(std::io::Error::new(
95 std::io::ErrorKind::InvalidData,
96 format!("invalid bool value byte `{n}`"),
97 )),
98 }
99 }
100 }
101
102 #[cfg_attr(
103 feature = "tracing",
104 tracing::instrument(level = "trace", ret, skip_all, fields(ty = "option"))
105 )]
106 fn read_option_status(&mut self) -> impl Future<Output = std::io::Result<bool>>
107 where
108 Self: Unpin,
109 {
110 async move {
111 match self.read_u8().await? {
112 0 => Ok(false),
113 1 => Ok(true),
114 n => Err(std::io::Error::new(
115 std::io::ErrorKind::InvalidData,
116 format!("invalid option status byte value `{n}`"),
117 )),
118 }
119 }
120 }
121
122 #[cfg_attr(
123 feature = "tracing",
124 tracing::instrument(level = "trace", ret, skip_all, fields(ty = "result"))
125 )]
126 fn read_result_status(&mut self) -> impl Future<Output = std::io::Result<bool>>
127 where
128 Self: Unpin,
129 {
130 async move {
131 match self.read_u8().await? {
132 0 => Ok(true),
133 1 => Ok(false),
134 n => Err(std::io::Error::new(
135 std::io::ErrorKind::InvalidData,
136 format!("invalid result status byte value `{n}`"),
137 )),
138 }
139 }
140 }
141}
142
143impl<T: AsyncRead> AsyncReadValue for T {}
144
145pub trait AsyncWriteValue: AsyncWrite {
146 #[cfg_attr(
147 feature = "tracing",
148 tracing::instrument(level = "trace", ret, skip_all, fields(ty = "bool"))
149 )]
150 fn write_bool(&mut self, v: bool) -> impl Future<Output = std::io::Result<()>>
151 where
152 Self: Unpin,
153 {
154 async move { self.write_u8(v.into()).await }
155 }
156
157 #[cfg_attr(
158 feature = "tracing",
159 tracing::instrument(level = "trace", ret, skip_all, fields(ty = "option"))
160 )]
161 fn write_option_status<T>(&mut self, v: Option<T>) -> impl Future<Output = std::io::Result<()>>
162 where
163 Self: Unpin,
164 {
165 async move { self.write_u8(v.is_some().into()).await }
166 }
167
168 #[cfg_attr(
169 feature = "tracing",
170 tracing::instrument(level = "trace", ret, skip_all, fields(ty = "result"))
171 )]
172 fn write_result_status<T, E>(
173 &mut self,
174 v: Result<T, E>,
175 ) -> impl Future<Output = std::io::Result<()>>
176 where
177 Self: Unpin,
178 {
179 async move { self.write_u8(v.is_err().into()).await }
180 }
181}
182
183impl<T: AsyncWrite> AsyncWriteValue for T {}
184
185#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
186pub struct BoolCodec;
187
188impl Encoder<bool> for BoolCodec {
189 type Error = std::io::Error;
190
191 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
192 fn encode(&mut self, item: bool, dst: &mut BytesMut) -> Result<(), Self::Error> {
193 dst.reserve(1);
194 dst.put_u8(item.into());
195 Ok(())
196 }
197}
198
199impl_encode_copy_ref!(BoolCodec, bool);
200
201impl Decoder for BoolCodec {
202 type Item = bool;
203 type Error = std::io::Error;
204
205 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
206 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
207 ensure_capacity!(src, 1_usize);
208 match src.get_u8() {
209 0 => Ok(Some(false)),
210 1 => Ok(Some(true)),
211 n => Err(std::io::Error::new(
212 std::io::ErrorKind::InvalidData,
213 format!("invalid bool value byte `{n}`"),
214 )),
215 }
216 }
217}
218
219#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
220pub struct S8Codec;
221
222impl Encoder<i8> for S8Codec {
223 type Error = std::io::Error;
224
225 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
226 fn encode(&mut self, item: i8, dst: &mut BytesMut) -> Result<(), Self::Error> {
227 dst.reserve(1);
228 dst.put_i8(item);
229 Ok(())
230 }
231}
232
233impl_encode_copy_ref!(S8Codec, i8);
234
235impl Decoder for S8Codec {
236 type Item = i8;
237 type Error = std::io::Error;
238
239 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
240 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
241 ensure_capacity!(src, 1_usize);
242 Ok(Some(src.get_i8()))
243 }
244}
245
246#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
247pub struct U8Codec;
248
249impl Encoder<u8> for U8Codec {
250 type Error = std::io::Error;
251
252 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
253 fn encode(&mut self, item: u8, dst: &mut BytesMut) -> Result<(), Self::Error> {
254 dst.reserve(1);
255 dst.put_u8(item);
256 Ok(())
257 }
258}
259
260impl_encode_copy_ref!(U8Codec, u8);
261
262impl Decoder for U8Codec {
263 type Item = u8;
264 type Error = std::io::Error;
265
266 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
267 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
268 let Some(v) = src.first().copied() else {
269 return Ok(None);
270 };
271 src.advance(1);
272 Ok(Some(v))
273 }
274}
275
276#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
277pub struct S16Codec;
278
279impl Encoder<i16> for S16Codec {
280 type Error = std::io::Error;
281
282 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
283 fn encode(&mut self, item: i16, dst: &mut BytesMut) -> Result<(), Self::Error> {
284 Leb128Encoder.encode(item, dst)
285 }
286}
287
288impl_encode_copy_ref!(S16Codec, i16);
289
290impl Decoder for S16Codec {
291 type Item = i16;
292 type Error = std::io::Error;
293
294 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
295 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
296 Leb128DecoderI16.decode(src)
297 }
298}
299
300#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
301pub struct U16Codec;
302
303impl Encoder<u16> for U16Codec {
304 type Error = std::io::Error;
305
306 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
307 fn encode(&mut self, item: u16, dst: &mut BytesMut) -> Result<(), Self::Error> {
308 Leb128Encoder.encode(item, dst)
309 }
310}
311
312impl_encode_copy_ref!(U16Codec, u16);
313
314impl Decoder for U16Codec {
315 type Item = u16;
316 type Error = std::io::Error;
317
318 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
319 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
320 Leb128DecoderU16.decode(src)
321 }
322}
323
324#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
325pub struct S32Codec;
326
327impl Encoder<i32> for S32Codec {
328 type Error = std::io::Error;
329
330 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
331 fn encode(&mut self, item: i32, dst: &mut BytesMut) -> Result<(), Self::Error> {
332 Leb128Encoder.encode(item, dst)
333 }
334}
335
336impl_encode_copy_ref!(S32Codec, i32);
337
338impl Decoder for S32Codec {
339 type Item = i32;
340 type Error = std::io::Error;
341
342 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
343 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
344 Leb128DecoderI32.decode(src)
345 }
346}
347
348#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
349pub struct U32Codec;
350
351impl Encoder<u32> for U32Codec {
352 type Error = std::io::Error;
353
354 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
355 fn encode(&mut self, item: u32, dst: &mut BytesMut) -> Result<(), Self::Error> {
356 Leb128Encoder.encode(item, dst)
357 }
358}
359
360impl_encode_copy_ref!(U32Codec, u32);
361
362impl Decoder for U32Codec {
363 type Item = u32;
364 type Error = std::io::Error;
365
366 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
367 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
368 Leb128DecoderU32.decode(src)
369 }
370}
371
372#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
373pub struct S64Codec;
374
375impl Encoder<i64> for S64Codec {
376 type Error = std::io::Error;
377
378 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
379 fn encode(&mut self, item: i64, dst: &mut BytesMut) -> Result<(), Self::Error> {
380 Leb128Encoder.encode(item, dst)
381 }
382}
383
384impl_encode_copy_ref!(S64Codec, i64);
385
386impl Decoder for S64Codec {
387 type Item = i64;
388 type Error = std::io::Error;
389
390 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
391 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
392 Leb128DecoderI64.decode(src)
393 }
394}
395
396#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
397pub struct U64Codec;
398
399impl Encoder<u64> for U64Codec {
400 type Error = std::io::Error;
401
402 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
403 fn encode(&mut self, item: u64, dst: &mut BytesMut) -> Result<(), Self::Error> {
404 Leb128Encoder.encode(item, dst)
405 }
406}
407
408impl_encode_copy_ref!(U64Codec, u64);
409
410impl Decoder for U64Codec {
411 type Item = u64;
412 type Error = std::io::Error;
413
414 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
415 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
416 Leb128DecoderU64.decode(src)
417 }
418}
419
420#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
421pub struct F32Codec;
422
423impl Encoder<f32> for F32Codec {
424 type Error = std::io::Error;
425
426 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
427 fn encode(&mut self, item: f32, dst: &mut BytesMut) -> Result<(), Self::Error> {
428 dst.reserve(4);
429 dst.put_f32_le(item);
430 Ok(())
431 }
432}
433
434impl_encode_copy_ref!(F32Codec, f32);
435
436impl Decoder for F32Codec {
437 type Item = f32;
438 type Error = std::io::Error;
439
440 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
441 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
442 ensure_capacity!(src, 4_usize);
443 Ok(Some(src.get_f32_le()))
444 }
445}
446
447#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
448pub struct F64Codec;
449
450impl Encoder<f64> for F64Codec {
451 type Error = std::io::Error;
452
453 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
454 fn encode(&mut self, item: f64, dst: &mut BytesMut) -> Result<(), Self::Error> {
455 dst.reserve(8);
456 dst.put_f64_le(item);
457 Ok(())
458 }
459}
460
461impl_encode_copy_ref!(F64Codec, f64);
462
463impl Decoder for F64Codec {
464 type Item = f64;
465 type Error = std::io::Error;
466
467 #[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", ret))]
468 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
469 ensure_capacity!(src, 8_usize);
470 Ok(Some(src.get_f64_le()))
471 }
472}
473
474#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
475pub struct PrimValEncoder;
476
477impl Encoder<bool> for PrimValEncoder {
478 type Error = std::io::Error;
479
480 fn encode(&mut self, item: bool, dst: &mut BytesMut) -> Result<(), Self::Error> {
481 BoolCodec.encode(item, dst)
482 }
483}
484
485impl Encoder<i8> for PrimValEncoder {
486 type Error = std::io::Error;
487
488 #[cfg_attr(
489 feature = "tracing",
490 tracing::instrument(level = "trace", ret, fields(ty = "s8"))
491 )]
492 fn encode(&mut self, item: i8, dst: &mut BytesMut) -> Result<(), Self::Error> {
493 S8Codec.encode(item, dst)
494 }
495}
496
497impl Encoder<u8> for PrimValEncoder {
498 type Error = std::io::Error;
499
500 #[cfg_attr(
501 feature = "tracing",
502 tracing::instrument(level = "trace", ret, fields(ty = "u8"))
503 )]
504 fn encode(&mut self, item: u8, dst: &mut BytesMut) -> Result<(), Self::Error> {
505 U8Codec.encode(item, dst)
506 }
507}
508
509impl Encoder<i16> for PrimValEncoder {
510 type Error = std::io::Error;
511
512 #[cfg_attr(
513 feature = "tracing",
514 tracing::instrument(level = "trace", ret, fields(ty = "s16"))
515 )]
516 fn encode(&mut self, item: i16, dst: &mut BytesMut) -> Result<(), Self::Error> {
517 S16Codec.encode(item, dst)
518 }
519}
520
521impl Encoder<u16> for PrimValEncoder {
522 type Error = std::io::Error;
523
524 #[cfg_attr(
525 feature = "tracing",
526 tracing::instrument(level = "trace", ret, fields(ty = "u16"))
527 )]
528 fn encode(&mut self, item: u16, dst: &mut BytesMut) -> Result<(), Self::Error> {
529 U16Codec.encode(item, dst)
530 }
531}
532
533impl Encoder<i32> for PrimValEncoder {
534 type Error = std::io::Error;
535
536 #[cfg_attr(
537 feature = "tracing",
538 tracing::instrument(level = "trace", ret, fields(ty = "s32"))
539 )]
540 fn encode(&mut self, item: i32, dst: &mut BytesMut) -> Result<(), Self::Error> {
541 S32Codec.encode(item, dst)
542 }
543}
544
545impl Encoder<u32> for PrimValEncoder {
546 type Error = std::io::Error;
547
548 #[cfg_attr(
549 feature = "tracing",
550 tracing::instrument(level = "trace", ret, fields(ty = "u32"))
551 )]
552 fn encode(&mut self, item: u32, dst: &mut BytesMut) -> Result<(), Self::Error> {
553 U32Codec.encode(item, dst)
554 }
555}
556
557impl Encoder<i64> for PrimValEncoder {
558 type Error = std::io::Error;
559
560 #[cfg_attr(
561 feature = "tracing",
562 tracing::instrument(level = "trace", ret, fields(ty = "s64"))
563 )]
564 fn encode(&mut self, item: i64, dst: &mut BytesMut) -> Result<(), Self::Error> {
565 S64Codec.encode(item, dst)
566 }
567}
568
569impl Encoder<u64> for PrimValEncoder {
570 type Error = std::io::Error;
571
572 #[cfg_attr(
573 feature = "tracing",
574 tracing::instrument(level = "trace", ret, fields(ty = "u64"))
575 )]
576 fn encode(&mut self, item: u64, dst: &mut BytesMut) -> Result<(), Self::Error> {
577 U64Codec.encode(item, dst)
578 }
579}
580
581impl Encoder<f32> for PrimValEncoder {
582 type Error = std::io::Error;
583
584 #[cfg_attr(
585 feature = "tracing",
586 tracing::instrument(level = "trace", ret, fields(ty = "f32"))
587 )]
588 fn encode(&mut self, item: f32, dst: &mut BytesMut) -> Result<(), Self::Error> {
589 F32Codec.encode(item, dst)
590 }
591}
592
593impl Encoder<f64> for PrimValEncoder {
594 type Error = std::io::Error;
595
596 #[cfg_attr(
597 feature = "tracing",
598 tracing::instrument(level = "trace", ret, fields(ty = "f64"))
599 )]
600 fn encode(&mut self, item: f64, dst: &mut BytesMut) -> Result<(), Self::Error> {
601 F64Codec.encode(item, dst)
602 }
603}
604
605impl Encoder<char> for PrimValEncoder {
606 type Error = std::io::Error;
607
608 #[cfg_attr(
609 feature = "tracing",
610 tracing::instrument(level = "trace", ret, fields(ty = "char"))
611 )]
612 fn encode(&mut self, item: char, dst: &mut BytesMut) -> Result<(), Self::Error> {
613 Utf8Codec.encode(item, dst)
614 }
615}
616
617#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
618pub struct FlagEncoder;
619
620impl Encoder<u8> for FlagEncoder {
621 type Error = std::io::Error;
622
623 #[cfg_attr(
624 feature = "tracing",
625 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "flags"))
626 )]
627 fn encode(&mut self, item: u8, dst: &mut BytesMut) -> Result<(), Self::Error> {
628 dst.reserve(1);
629 dst.put_u8(item);
630 Ok(())
631 }
632}
633
634impl Encoder<u16> for FlagEncoder {
635 type Error = std::io::Error;
636
637 #[cfg_attr(
638 feature = "tracing",
639 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "flags"))
640 )]
641 fn encode(&mut self, item: u16, dst: &mut BytesMut) -> Result<(), Self::Error> {
642 dst.reserve(2);
643 dst.put_u16_le(item);
644 Ok(())
645 }
646}
647
648impl Encoder<u32> for FlagEncoder {
649 type Error = std::io::Error;
650
651 #[cfg_attr(
652 feature = "tracing",
653 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "flags"))
654 )]
655 fn encode(&mut self, item: u32, dst: &mut BytesMut) -> Result<(), Self::Error> {
656 dst.reserve(4);
657 dst.put_u32_le(item);
658 Ok(())
659 }
660}
661
662impl Encoder<u64> for FlagEncoder {
663 type Error = std::io::Error;
664
665 #[cfg_attr(
666 feature = "tracing",
667 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "flags"))
668 )]
669 fn encode(&mut self, item: u64, dst: &mut BytesMut) -> Result<(), Self::Error> {
670 dst.reserve(8);
671 dst.put_u64_le(item);
672 Ok(())
673 }
674}
675
676impl Encoder<u128> for FlagEncoder {
677 type Error = std::io::Error;
678
679 #[cfg_attr(
680 feature = "tracing",
681 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "flags"))
682 )]
683 fn encode(&mut self, item: u128, dst: &mut BytesMut) -> Result<(), Self::Error> {
684 dst.reserve(16);
685 dst.put_u128_le(item);
686 Ok(())
687 }
688}
689
690impl Encoder<Vec<u8>> for FlagEncoder {
691 type Error = std::io::Error;
692
693 #[cfg_attr(
694 feature = "tracing",
695 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "flags"))
696 )]
697 fn encode(&mut self, item: Vec<u8>, dst: &mut BytesMut) -> Result<(), Self::Error> {
698 dst.extend_from_slice(&item);
699 Ok(())
700 }
701}
702
703impl Encoder<&[u8]> for FlagEncoder {
704 type Error = std::io::Error;
705
706 #[cfg_attr(
707 feature = "tracing",
708 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "flags"))
709 )]
710 fn encode(&mut self, item: &[u8], dst: &mut BytesMut) -> Result<(), Self::Error> {
711 dst.extend_from_slice(item);
712 Ok(())
713 }
714}
715
716impl Encoder<Bytes> for FlagEncoder {
717 type Error = std::io::Error;
718
719 #[cfg_attr(
720 feature = "tracing",
721 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "flags"))
722 )]
723 fn encode(&mut self, item: Bytes, dst: &mut BytesMut) -> Result<(), Self::Error> {
724 dst.extend_from_slice(&item);
725 Ok(())
726 }
727}
728
729impl Encoder<&Bytes> for FlagEncoder {
730 type Error = std::io::Error;
731
732 #[cfg_attr(
733 feature = "tracing",
734 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "flags"))
735 )]
736 fn encode(&mut self, item: &Bytes, dst: &mut BytesMut) -> Result<(), Self::Error> {
737 dst.extend_from_slice(item);
738 Ok(())
739 }
740}
741
742#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
743pub struct FlagDecoder<const N: usize>;
744
745impl<const N: usize> Decoder for FlagDecoder<N> {
746 type Item = Bytes;
747 type Error = std::io::Error;
748
749 #[cfg_attr(
750 feature = "tracing",
751 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "flags"))
752 )]
753 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
754 let n = if N % 8 == 0 { N / 8 } else { N / 8 + 1 };
755 if src.len() < n {
756 ensure_capacity!(src, n);
757 }
758 Ok(Some(src.split_to(n).freeze()))
759 }
760}
761
762impl_encode_copy_ref!(PrimValEncoder, bool);
763impl_encode_copy_ref!(PrimValEncoder, i8);
764impl_encode_copy_ref!(PrimValEncoder, u8);
765impl_encode_copy_ref!(PrimValEncoder, i16);
766impl_encode_copy_ref!(PrimValEncoder, u16);
767impl_encode_copy_ref!(PrimValEncoder, i32);
768impl_encode_copy_ref!(PrimValEncoder, u32);
769impl_encode_copy_ref!(PrimValEncoder, i64);
770impl_encode_copy_ref!(PrimValEncoder, u64);
771impl_encode_copy_ref!(PrimValEncoder, f32);
772impl_encode_copy_ref!(PrimValEncoder, f64);
773impl_encode_copy_ref!(PrimValEncoder, char);
774
775impl_encode_copy_ref!(FlagEncoder, u8);
776impl_encode_copy_ref!(FlagEncoder, u16);
777impl_encode_copy_ref!(FlagEncoder, u32);
778impl_encode_copy_ref!(FlagEncoder, u64);
779impl_encode_copy_ref!(FlagEncoder, u128);
780
781impl_encode_str!(PrimValEncoder, &str);
782impl_encode_str!(PrimValEncoder, String);
783
784#[derive(Copy, Clone, Debug, Eq, PartialEq)]
785pub struct TupleEncoder<T>(pub T);
786
787#[derive(Debug)]
788pub struct TupleDecoder<C, V> {
789 dec: C,
790 v: V,
791}
792
793impl<C, V> TupleDecoder<C, V> {
794 pub fn into_inner(self) -> C {
795 self.dec
796 }
797}
798
799impl<C, V> TupleDecoder<C, V>
800where
801 V: Default,
802{
803 pub fn new(decoder: C) -> Self {
804 Self {
805 dec: decoder,
806 v: V::default(),
807 }
808 }
809}
810
811macro_rules! impl_tuple_codec {
812 ($($vn:ident),+; $($vt:ident),+; $($cn:ident),+; $($ct:ident),+) => {
813 impl<$($ct),+> Default for TupleEncoder::<($($ct),+,)>
814 where
815 $($ct: Default),+
816 {
817 fn default() -> Self {
818 Self(($($ct::default()),+,))
819 }
820 }
821
822 impl<$($ct),+> From<($($ct),+,)> for TupleEncoder<($($ct),+,)> {
823 fn from(e: ($($ct),+,)) -> Self {
824 Self(e)
825 }
826 }
827
828 impl<E, $($vt, $ct),+> Encoder<($($vt),+,)> for TupleEncoder<($($ct),+,)>
829 where
830 E: From<std::io::Error>,
831 $($ct: Encoder<$vt, Error = E>),+
832 {
833 type Error = E;
834
835 #[cfg_attr(
836 feature = "tracing",
837 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "tuple"))
838 )]
839 fn encode(
840 &mut self,
841 ($($vn),+,): ($($vt),+,),
842 dst: &mut BytesMut,
843 ) -> Result<(), Self::Error> {
844 let ($(ref mut $cn),+,) = self.0;
845 $($cn.encode($vn, dst)?;)+
846 Ok(())
847 }
848 }
849
850 impl<'a, E, $($vt, $ct),+> Encoder<&'a ($($vt),+,)> for TupleEncoder<($($ct),+,)>
851 where
852 E: From<std::io::Error>,
853 $($ct: Encoder<&'a $vt, Error = E>),+
854 {
855 type Error = E;
856
857 #[cfg_attr(
858 feature = "tracing",
859 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "tuple"))
860 )]
861 fn encode(
862 &mut self,
863 ($($vn),+,): &'a ($($vt),+,),
864 dst: &mut BytesMut,
865 ) -> Result<(), Self::Error> {
866 let ($(ref mut $cn),+,) = self.0;
867 $($cn.encode($vn, dst)?;)+
868 Ok(())
869 }
870 }
871
872 impl<$($ct),+> Default for TupleDecoder<($($ct),+,), ($(Option<$ct::Item>),+,)>
873 where
874 $($ct: Decoder + Default),+,
875 {
876 fn default() -> Self {
877 Self{
878 dec: ($($ct::default()),+,),
879 v: ($(Option::<$ct::Item>::None),+,),
880 }
881 }
882 }
883
884 impl<E, $($ct),+> Decoder for TupleDecoder<($($ct),+,), ($(Option<$ct::Item>),+,)>
885 where
886 E: From<std::io::Error>,
887 $($ct: Decoder<Error = E>),+,
888 {
889 type Error = E;
890 type Item = ($($ct::Item),+,);
891
892 #[cfg_attr(
893 feature = "tracing",
894 tracing::instrument(level = "trace", skip(self), fields(ty = "tuple"))
895 )]
896 fn decode(
897 &mut self,
898 src: &mut BytesMut,
899 ) -> Result<Option<Self::Item>, Self::Error> {
900 let ($(ref mut $vn),+,) = self.v;
901 let ($(ref mut $cn),+,) = self.dec;
902 $(
903 if $vn.is_none() {
904 let Some(v) = $cn.decode(src)? else {
905 return Ok(None)
906 };
907 *$vn = Some(v);
908 }
909 )+
910 Ok(Some(($($vn.take().unwrap()),+,)))
911 }
912 }
913 };
914}
915
916impl_tuple_codec!(
917 v0;
918 V0;
919 c0;
920 C0
921);
922
923impl_tuple_codec!(
924 v0, v1;
925 V0, V1;
926 c0, c1;
927 C0, C1
928);
929
930impl_tuple_codec!(
931 v0, v1, v2;
932 V0, V1, V2;
933 c0, c1, c2;
934 C0, C1, C2
935);
936
937impl_tuple_codec!(
938 v0, v1, v2, v3;
939 V0, V1, V2, V3;
940 c0, c1, c2, c3;
941 C0, C1, C2, C3
942);
943
944impl_tuple_codec!(
945 v0, v1, v2, v3, v4;
946 V0, V1, V2, V3, V4;
947 c0, c1, c2, c3, c4;
948 C0, C1, C2, C3, C4
949);
950
951impl_tuple_codec!(
952 v0, v1, v2, v3, v4, v5;
953 V0, V1, V2, V3, V4, V5;
954 c0, c1, c2, c3, c4, c5;
955 C0, C1, C2, C3, C4, C5
956);
957
958impl_tuple_codec!(
959 v0, v1, v2, v3, v4, v5, v6;
960 V0, V1, V2, V3, V4, V5, V6;
961 c0, c1, c2, c3, c4, c5, c6;
962 C0, C1, C2, C3, C4, C5, C6
963);
964
965impl_tuple_codec!(
966 v0, v1, v2, v3, v4, v5, v6, v7;
967 V0, V1, V2, V3, V4, V5, V6, V7;
968 c0, c1, c2, c3, c4, c5, c6, c7;
969 C0, C1, C2, C3, C4, C5, C6, C7
970);
971
972impl_tuple_codec!(
973 v0, v1, v2, v3, v4, v5, v6, v7, v8;
974 V0, V1, V2, V3, V4, V5, V6, V7, V8;
975 c0, c1, c2, c3, c4, c5, c6, c7, c8;
976 C0, C1, C2, C3, C4, C5, C6, C7, C8
977);
978
979impl_tuple_codec!(
980 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9;
981 V0, V1, V2, V3, V4, V5, V6, V7, V8, V9;
982 c0, c1, c2, c3, c4, c5, c6, c7, c8, c9;
983 C0, C1, C2, C3, C4, C5, C6, C7, C8, C9
984);
985
986impl_tuple_codec!(
987 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10;
988 V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10;
989 c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10;
990 C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10
991);
992
993impl_tuple_codec!(
994 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11;
995 V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11;
996 c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11;
997 C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11
998);
999
1000impl_tuple_codec!(
1001 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12;
1002 V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12;
1003 c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12;
1004 C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12
1005);
1006
1007impl_tuple_codec!(
1008 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13;
1009 V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13;
1010 c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13;
1011 C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13
1012);
1013
1014impl_tuple_codec!(
1015 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14;
1016 V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14;
1017 c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14;
1018 C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14
1019);
1020
1021impl_tuple_codec!(
1022 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15;
1023 V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14, V15;
1024 c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15;
1025 C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15
1026);
1027
1028#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
1029pub struct OptionEncoder<T>(pub T);
1030
1031impl<C, T> Encoder<Option<T>> for OptionEncoder<C>
1032where
1033 C: Encoder<T>,
1034{
1035 type Error = C::Error;
1036
1037 #[cfg_attr(
1038 feature = "tracing",
1039 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "option"))
1040 )]
1041 fn encode(&mut self, v: Option<T>, dst: &mut BytesMut) -> Result<(), Self::Error> {
1042 dst.reserve(1);
1043 if let Some(v) = v {
1044 dst.put_u8(1);
1045 self.0.encode(v, dst)
1046 } else {
1047 dst.put_u8(0);
1048 Ok(())
1049 }
1050 }
1051}
1052
1053impl<'a, C, T> Encoder<&'a Option<T>> for OptionEncoder<C>
1054where
1055 C: Encoder<&'a T>,
1056{
1057 type Error = C::Error;
1058
1059 #[cfg_attr(
1060 feature = "tracing",
1061 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "option"))
1062 )]
1063 fn encode(&mut self, v: &'a Option<T>, dst: &mut BytesMut) -> Result<(), Self::Error> {
1064 dst.reserve(1);
1065 if let Some(v) = v {
1066 dst.put_u8(1);
1067 self.0.encode(v, dst)
1068 } else {
1069 dst.put_u8(0);
1070 Ok(())
1071 }
1072 }
1073}
1074
1075#[derive(Debug, Default)]
1076pub struct OptionDecoder<T> {
1077 dec: T,
1078 is_some: bool,
1079}
1080
1081impl<T> OptionDecoder<T> {
1082 pub fn into_inner(self) -> T {
1083 self.dec
1084 }
1085}
1086
1087impl<T> OptionDecoder<T> {
1088 pub fn new(decoder: T) -> Self {
1089 Self {
1090 dec: decoder,
1091 is_some: false,
1092 }
1093 }
1094}
1095
1096impl<T> Decoder for OptionDecoder<T>
1097where
1098 T: Decoder,
1099{
1100 type Item = Option<T::Item>;
1101 type Error = T::Error;
1102
1103 #[cfg_attr(
1104 feature = "tracing",
1105 tracing::instrument(level = "trace", skip(self), fields(ty = "option"))
1106 )]
1107 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
1108 if !self.is_some {
1109 ensure_capacity!(src, 1_usize);
1110 match src.get_u8() {
1111 0 => return Ok(Some(None)),
1112 1 => {
1113 self.is_some = true;
1114 }
1115 n => {
1116 return Err(std::io::Error::new(
1117 std::io::ErrorKind::InvalidData,
1118 format!("invalid option status byte value `{n}`"),
1119 )
1120 .into())
1121 }
1122 }
1123 }
1124 let Some(v) = self.dec.decode(src)? else {
1125 return Ok(None);
1126 };
1127 self.is_some = false;
1128 Ok(Some(Some(v)))
1129 }
1130}
1131
1132#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
1133pub struct ResultEncoder<O, E> {
1134 pub ok: O,
1135 pub err: E,
1136}
1137
1138impl<CO, O, CE, E> Encoder<Result<O, E>> for ResultEncoder<CO, CE>
1139where
1140 CO: Encoder<O>,
1141 CE: Encoder<E>,
1142 std::io::Error: From<CO::Error>,
1143 std::io::Error: From<CE::Error>,
1144{
1145 type Error = std::io::Error;
1146
1147 #[cfg_attr(
1148 feature = "tracing",
1149 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "result"))
1150 )]
1151 fn encode(&mut self, v: Result<O, E>, dst: &mut BytesMut) -> Result<(), Self::Error> {
1152 dst.reserve(1);
1153 match v {
1154 Ok(v) => {
1155 dst.put_u8(0);
1156 self.ok.encode(v, dst)?;
1157 }
1158 Err(v) => {
1159 dst.put_u8(1);
1160 self.err.encode(v, dst)?;
1161 }
1162 }
1163 Ok(())
1164 }
1165}
1166
1167impl<'a, CO, O, CE, E> Encoder<&'a Result<O, E>> for ResultEncoder<CO, CE>
1168where
1169 CO: Encoder<&'a O>,
1170 CE: Encoder<&'a E>,
1171 std::io::Error: From<CO::Error>,
1172 std::io::Error: From<CE::Error>,
1173{
1174 type Error = std::io::Error;
1175
1176 #[cfg_attr(
1177 feature = "tracing",
1178 tracing::instrument(level = "trace", skip_all, fields(dst, ty = "result"))
1179 )]
1180 fn encode(&mut self, v: &'a Result<O, E>, dst: &mut BytesMut) -> Result<(), Self::Error> {
1181 dst.reserve(1);
1182 match v {
1183 Ok(v) => {
1184 dst.put_u8(0);
1185 self.ok.encode(v, dst)?;
1186 }
1187 Err(v) => {
1188 dst.put_u8(1);
1189 self.err.encode(v, dst)?;
1190 }
1191 }
1192 Ok(())
1193 }
1194}
1195
1196#[derive(Debug, Default)]
1197pub struct ResultDecoder<O, E> {
1198 ok: O,
1199 err: E,
1200 is_ok: Option<bool>,
1201}
1202
1203impl<O, E> ResultDecoder<O, E> {
1204 pub fn into_inner(self) -> (O, E) {
1205 (self.ok, self.err)
1206 }
1207
1208 pub fn into_ok(self) -> O {
1209 self.ok
1210 }
1211
1212 pub fn into_err(self) -> E {
1213 self.err
1214 }
1215}
1216
1217impl<O, E> ResultDecoder<O, E> {
1218 pub fn new(ok: O, err: E) -> Self {
1219 Self {
1220 ok,
1221 err,
1222 is_ok: None,
1223 }
1224 }
1225}
1226
1227impl<O, E> Decoder for ResultDecoder<O, E>
1228where
1229 O: Decoder,
1230 E: Decoder,
1231 std::io::Error: From<O::Error>,
1232 std::io::Error: From<E::Error>,
1233{
1234 type Item = Result<O::Item, E::Item>;
1235 type Error = std::io::Error;
1236
1237 #[cfg_attr(
1238 feature = "tracing",
1239 tracing::instrument(level = "trace", skip(self), fields(ty = "result"))
1240 )]
1241 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
1242 let is_ok = if let Some(is_ok) = self.is_ok {
1243 is_ok
1244 } else {
1245 ensure_capacity!(src, 1_usize);
1246 match src.get_u8() {
1247 0 => {
1248 self.is_ok = Some(true);
1249 true
1250 }
1251 1 => {
1252 self.is_ok = Some(false);
1253 false
1254 }
1255 n => {
1256 return Err(std::io::Error::new(
1257 std::io::ErrorKind::InvalidData,
1258 format!("invalid result status byte value `{n}`"),
1259 ))
1260 }
1261 }
1262 };
1263 let res = if is_ok {
1264 let Some(v) = self.ok.decode(src)? else {
1265 return Ok(None);
1266 };
1267 Ok(v)
1268 } else {
1269 let Some(v) = self.err.decode(src)? else {
1270 return Ok(None);
1271 };
1272 Err(v)
1273 };
1274 self.is_ok = None;
1275 Ok(Some(res))
1276 }
1277}
1278
1279#[cfg(test)]
1280mod tests {
1281 use crate::CoreNameDecoder;
1282
1283 use super::*;
1284
1285 #[test_log::test]
1286 fn tuple() {
1287 let mut buf = BytesMut::default();
1288 TupleEncoder((
1289 BoolCodec,
1290 PrimValEncoder,
1291 CoreNameEncoder,
1292 Leb128Encoder,
1293 TupleEncoder((ResultEncoder {
1294 ok: BoolCodec,
1295 err: CoreNameEncoder,
1296 },)),
1297 ))
1298 .encode(
1299 (
1300 true,
1301 0xfeu8,
1302 "test",
1303 0x42u32,
1304 (Result::<_, String>::Ok(true),),
1305 ),
1306 &mut buf,
1307 )
1308 .expect("failed to encode tuple");
1309 assert_eq!(buf.as_ref(), b"\x01\xfe\x04test\x42\0\x01");
1310 let (a, b, c, d, (e,)) = TupleDecoder::new((
1311 BoolCodec,
1312 U8Codec,
1313 CoreNameDecoder::default(),
1314 Leb128DecoderU32,
1315 TupleDecoder::<
1316 (ResultDecoder<BoolCodec, CoreNameDecoder>,),
1317 (Option<Result<bool, String>>,),
1318 >::default(),
1319 ))
1320 .decode(&mut buf)
1321 .expect("failed to decode tuple")
1322 .expect("short tuple read");
1323 assert!(a);
1324 assert_eq!(b, 0xfe);
1325 assert_eq!(c, "test");
1326 assert_eq!(d, 0x42);
1327 assert_eq!(e, Ok(true));
1328 }
1329}