wasm_tokio/cm/
values.rs

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}