Skip to main content

leb128_tokio/
lib.rs

1#![allow(clippy::cast_possible_truncation)]
2
3use ::core::fmt::Display;
4use ::core::future::Future;
5
6use tokio::io::{AsyncRead, AsyncReadExt as _, AsyncWrite, AsyncWriteExt as _};
7use tokio_util::bytes::{Buf as _, BytesMut};
8use tokio_util::codec::{Decoder, Encoder};
9
10/// Error returned for overflows decoding statically-sized integers
11#[derive(Debug)]
12pub struct Overflow<const N: usize>;
13
14impl<const N: usize> Display for Overflow<N> {
15    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16        write!(f, "varint overflows {N}-bit integer")
17    }
18}
19
20impl<const N: usize> std::error::Error for Overflow<N> {}
21
22/// Error returned for overflows decoding variable size integers
23#[derive(Debug)]
24pub struct OverflowVar(u8);
25
26impl Display for OverflowVar {
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        write!(f, "varint overflows {}-bit integer", self.0)
29    }
30}
31
32impl std::error::Error for OverflowVar {}
33
34fn invalid_data(err: impl Sync + Send + std::error::Error + 'static) -> std::io::Error {
35    std::io::Error::new(std::io::ErrorKind::InvalidData, err)
36}
37
38fn is_sign_extended(b: u8, bits: u32) -> bool {
39    let shift = bits.saturating_sub(1);
40    let rest = (b & 0x7f) >> shift;
41    rest == 0 || rest == 0x7f >> shift
42}
43
44macro_rules! decode_unsigned_leb128 {
45    ($t:ident, $i:ident => $next:expr, $x:ident => $ret:expr) => {
46        decode_unsigned_leb128!(
47            $t,
48            <$t>::BITS,
49            Overflow::<{ <$t>::BITS as usize }>,
50            $i => $next,
51            $x => $ret
52        )
53    };
54    ($t:ident, $bits:expr, $err:expr, $i:ident => $next:expr, $x:ident => $ret:expr) => {{
55        let bits: u32 = $bits;
56        let last = bits.saturating_sub(1) / 7 * 7;
57        let max: u8 = (1 << bits.saturating_sub(last)) - 1;
58        let mut $x: $t = 0;
59        for ($i, s) in (0..=last).step_by(7).enumerate() {
60            let b: u8 = $next;
61            if s == last && b > max {
62                break;
63            }
64            $x |= (<$t>::from(b) & 0x7f) << s;
65            if b & 0x80 == 0 {
66                return $ret;
67            }
68        }
69        Err(invalid_data($err))
70    }};
71}
72
73macro_rules! decode_signed_leb128 {
74    ($t:ident, $i:ident => $next:expr, $x:ident => $ret:expr) => {{
75        const LAST: u32 = (<$t>::BITS - 1) / 7 * 7;
76        let mut $x: $t = 0;
77        for ($i, s) in (0..=LAST).step_by(7).enumerate() {
78            let b: u8 = $next;
79            if s == LAST && !is_sign_extended(b, <$t>::BITS - LAST) {
80                break;
81            }
82            $x |= <$t>::from((b & 0x7f).cast_signed()) << s;
83            if b & 0x80 == 0 {
84                if s != LAST && b & 0x40 != 0 {
85                    $x |= !0 << (s + 7);
86                }
87                return $ret;
88            }
89        }
90        Err(invalid_data(Overflow::<{ <$t>::BITS as usize }>))
91    }};
92}
93
94macro_rules! read_leb128 {
95    ($f:ident, $t:ident, $decode:ident) => {
96        #[cfg_attr(
97            feature = "tracing",
98            tracing::instrument(level = "trace", ret, skip_all, fields(ty = stringify!($t)))
99        )]
100        fn $f(&mut self) -> impl Future<Output = std::io::Result<$t>>
101        where
102            Self: Unpin,
103        {
104            async move { $decode!($t, _i => self.read_u8().await?, x => Ok(x)) }
105        }
106    };
107}
108
109macro_rules! read_var_unsigned_leb128 {
110    ($f:ident, $t:ident, $bits:literal, $fixed:ident, [$($sbits:literal => $sfixed:ident),*]) => {
111        #[cfg_attr(
112            feature = "tracing",
113            tracing::instrument(level = "trace", ret, skip_all, fields(ty = "uvarint", n = n))
114        )]
115        fn $f(&mut self, n: u8) -> impl Future<Output = std::io::Result<$t>>
116        where
117            Self: Unpin,
118        {
119            async move {
120                match n {
121                    $($sbits => return self.$sfixed().await.map(Into::into),)*
122                    $bits => return self.$fixed().await,
123                    n if n > $bits => {
124                        return Err(std::io::Error::new(
125                            std::io::ErrorKind::InvalidInput,
126                            format!("{n}-bit integer does not fit in `{}`", stringify!($t)),
127                        ))
128                    }
129                    _ => {}
130                }
131                decode_unsigned_leb128!(
132                    $t,
133                    u32::from(n),
134                    OverflowVar(n),
135                    _i => self.read_u8().await?,
136                    x => Ok(x)
137                )
138            }
139        }
140    };
141}
142
143pub trait AsyncReadLeb128: AsyncRead {
144    read_leb128!(read_u8_leb128, u8, decode_unsigned_leb128);
145    read_leb128!(read_u16_leb128, u16, decode_unsigned_leb128);
146    read_leb128!(read_u32_leb128, u32, decode_unsigned_leb128);
147    read_leb128!(read_u64_leb128, u64, decode_unsigned_leb128);
148    read_leb128!(read_u128_leb128, u128, decode_unsigned_leb128);
149
150    read_var_unsigned_leb128!(read_var_u8_leb128, u8, 8, read_u8_leb128, []);
151    read_var_unsigned_leb128!(
152        read_var_u16_leb128,
153        u16,
154        16,
155        read_u16_leb128,
156        [8 => read_u8_leb128]
157    );
158    read_var_unsigned_leb128!(
159        read_var_u32_leb128,
160        u32,
161        32,
162        read_u32_leb128,
163        [8 => read_u8_leb128, 16 => read_u16_leb128]
164    );
165    read_var_unsigned_leb128!(
166        read_var_u64_leb128,
167        u64,
168        64,
169        read_u64_leb128,
170        [8 => read_u8_leb128, 16 => read_u16_leb128, 32 => read_u32_leb128]
171    );
172    read_var_unsigned_leb128!(
173        read_var_u128_leb128,
174        u128,
175        128,
176        read_u128_leb128,
177        [8 => read_u8_leb128, 16 => read_u16_leb128, 32 => read_u32_leb128, 64 => read_u64_leb128]
178    );
179
180    read_leb128!(read_i8_leb128, i8, decode_signed_leb128);
181    read_leb128!(read_i16_leb128, i16, decode_signed_leb128);
182    read_leb128!(read_i32_leb128, i32, decode_signed_leb128);
183    read_leb128!(read_i64_leb128, i64, decode_signed_leb128);
184    read_leb128!(read_i128_leb128, i128, decode_signed_leb128);
185}
186
187impl<T: AsyncRead> AsyncReadLeb128 for T {}
188
189macro_rules! write_leb128 {
190    ($f:ident, $t:ident, $put:ident) => {
191        #[cfg_attr(
192                    feature = "tracing",
193                    tracing::instrument(level = "trace", ret, skip_all, fields(ty = stringify!($t)))
194                )]
195        fn $f(&mut self, x: $t) -> impl Future<Output = std::io::Result<()>>
196        where
197            Self: Unpin,
198        {
199            async move { self.write_all($put(&mut Default::default(), x)).await }
200        }
201    };
202}
203
204pub trait AsyncWriteLeb128: AsyncWrite {
205    write_leb128!(write_u8_leb128, u8, put_u8_leb128);
206    write_leb128!(write_u16_leb128, u16, put_u16_leb128);
207    write_leb128!(write_u32_leb128, u32, put_u32_leb128);
208    write_leb128!(write_u64_leb128, u64, put_u64_leb128);
209    write_leb128!(write_u128_leb128, u128, put_u128_leb128);
210    write_leb128!(write_i8_leb128, i8, put_i8_leb128);
211    write_leb128!(write_i16_leb128, i16, put_i16_leb128);
212    write_leb128!(write_i32_leb128, i32, put_i32_leb128);
213    write_leb128!(write_i64_leb128, i64, put_i64_leb128);
214    write_leb128!(write_i128_leb128, i128, put_i128_leb128);
215}
216
217impl<T: AsyncWrite> AsyncWriteLeb128 for T {}
218
219fn stateless_decode_eof<D>(dec: &mut D, buf: &mut BytesMut) -> Result<Option<D::Item>, D::Error>
220where
221    D: Decoder,
222{
223    match dec.decode(buf)? {
224        Some(frame) => Ok(Some(frame)),
225        None => {
226            if buf.is_empty() {
227                Ok(None)
228            } else {
229                Err(std::io::Error::from(std::io::ErrorKind::UnexpectedEof).into())
230            }
231        }
232    }
233}
234
235pub struct Leb128Encoder;
236
237macro_rules! impl_encode {
238    ($t:ty, $f:ident) => {
239        impl Encoder<$t> for Leb128Encoder {
240            type Error = std::io::Error;
241
242            fn encode(&mut self, item: $t, dst: &mut BytesMut) -> Result<(), Self::Error> {
243                dst.extend_from_slice($f(&mut Default::default(), item));
244                Ok(())
245            }
246        }
247
248        impl Encoder<&$t> for Leb128Encoder {
249            type Error = std::io::Error;
250
251            fn encode(&mut self, item: &$t, dst: &mut BytesMut) -> Result<(), Self::Error> {
252                self.encode(*item, dst)
253            }
254        }
255
256        impl Encoder<&&$t> for Leb128Encoder {
257            type Error = std::io::Error;
258
259            fn encode(&mut self, item: &&$t, dst: &mut BytesMut) -> Result<(), Self::Error> {
260                self.encode(*item, dst)
261            }
262        }
263    };
264}
265
266macro_rules! leb128_decoder {
267    ($t:ident, $decoder:ident, $decode:ident) => {
268        #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
269        pub struct $decoder;
270
271        impl Decoder for $decoder {
272            type Item = $t;
273            type Error = std::io::Error;
274
275            fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
276                $decode!(
277                    $t,
278                    i => {
279                        let Some(b) = src.get(i).copied() else {
280                            src.reserve(1);
281                            return Ok(None);
282                        };
283                        b
284                    },
285                    x => {
286                        src.advance(i + 1);
287                        Ok(Some(x))
288                    }
289                )
290            }
291
292            fn decode_eof(
293                &mut self,
294                src: &mut BytesMut,
295            ) -> Result<Option<Self::Item>, Self::Error> {
296                stateless_decode_eof(self, src)
297            }
298        }
299    };
300}
301
302macro_rules! unsigned_leb128 {
303    ($t:ident, $put:ident, $decoder:ident) => {
304        pub fn $put(buf: &mut [u8; <$t>::BITS.div_ceil(7) as usize], mut x: $t) -> &mut [u8] {
305            let mut i = 0;
306            while x >= 0x80 {
307                buf[i] = (x as u8) | 0x80;
308                x >>= 7;
309                i += 1;
310            }
311            buf[i] = x as u8;
312            &mut buf[..=i]
313        }
314
315        leb128_decoder!($t, $decoder, decode_unsigned_leb128);
316        impl_encode!($t, $put);
317    };
318}
319
320macro_rules! signed_leb128 {
321    ($t:ident, $put:ident, $decoder:ident) => {
322        pub fn $put(buf: &mut [u8; <$t>::BITS.div_ceil(7) as usize], mut x: $t) -> &mut [u8] {
323            let mut i = 0;
324            loop {
325                let b = x as u8;
326                x >>= 6;
327                if x == 0 || x == !0 {
328                    buf[i] = b & 0x7f;
329                    return &mut buf[..=i];
330                } else {
331                    buf[i] = b | 0x80;
332                    x >>= 1;
333                }
334                i += 1;
335            }
336        }
337
338        leb128_decoder!($t, $decoder, decode_signed_leb128);
339        impl_encode!($t, $put);
340    };
341}
342
343unsigned_leb128!(u8, put_u8_leb128, Leb128DecoderU8);
344unsigned_leb128!(u16, put_u16_leb128, Leb128DecoderU16);
345unsigned_leb128!(u32, put_u32_leb128, Leb128DecoderU32);
346unsigned_leb128!(u64, put_u64_leb128, Leb128DecoderU64);
347unsigned_leb128!(u128, put_u128_leb128, Leb128DecoderU128);
348signed_leb128!(i8, put_i8_leb128, Leb128DecoderI8);
349signed_leb128!(i16, put_i16_leb128, Leb128DecoderI16);
350signed_leb128!(i32, put_i32_leb128, Leb128DecoderI32);
351signed_leb128!(i64, put_i64_leb128, Leb128DecoderI64);
352signed_leb128!(i128, put_i128_leb128, Leb128DecoderI128);
353
354#[cfg(test)]
355mod tests {
356    use super::*;
357
358    #[tokio::test]
359    async fn unsigned_leb128() {
360        const ENCODED: [u8; 3] = [0xe5, 0x8e, 0x26];
361
362        let v = ENCODED
363            .as_slice()
364            .read_u32_leb128()
365            .await
366            .expect("failed to read u32");
367        assert_eq!(v, 624_485);
368
369        let v = Leb128DecoderU32
370            .decode(&mut ENCODED.as_slice().into())
371            .expect("failed to decode u32");
372        assert_eq!(v, Some(624_485));
373
374        let v = ENCODED
375            .as_slice()
376            .read_u64_leb128()
377            .await
378            .expect("failed to read u64");
379        assert_eq!(v, 624_485);
380
381        let v = Leb128DecoderU64
382            .decode(&mut ENCODED.as_slice().into())
383            .expect("failed to decode u64");
384        assert_eq!(v, Some(624_485));
385
386        let mut buf = vec![];
387        buf.write_u32_leb128(624_485)
388            .await
389            .expect("failed to write u32");
390        assert_eq!(buf, ENCODED);
391
392        let mut buf = vec![];
393        buf.write_u64_leb128(624_485)
394            .await
395            .expect("failed to write u64");
396        assert_eq!(buf, ENCODED);
397
398        let v = [0xff, 0x01]
399            .as_slice()
400            .read_u8_leb128()
401            .await
402            .expect("failed to read u8");
403        assert_eq!(v, u8::MAX);
404
405        let v = [0x7f]
406            .as_slice()
407            .read_u8_leb128()
408            .await
409            .expect("failed to read u8");
410        assert_eq!(v, 0x7f);
411
412        let v = [0xff, 0x00]
413            .as_slice()
414            .read_u8_leb128()
415            .await
416            .expect("failed to read u8");
417        assert_eq!(v, 0x7f);
418
419        [0xff, 0x02]
420            .as_slice()
421            .read_u8_leb128()
422            .await
423            .expect_err("u8 read should have failed, since it encoded 9 bits");
424
425        let v = [0xff, 0xff, 0x01]
426            .as_slice()
427            .read_u16_leb128()
428            .await
429            .expect("failed to read u16");
430        assert_eq!(v, 0x7fff);
431
432        let v = [0xff, 0xff, 0x02]
433            .as_slice()
434            .read_u16_leb128()
435            .await
436            .expect("failed to read u16");
437        assert_eq!(v, 0xbfff);
438
439        let v = [0xff, 0xff, 0x03]
440            .as_slice()
441            .read_u16_leb128()
442            .await
443            .expect("failed to read u16");
444        assert_eq!(v, u16::MAX);
445
446        [0xff, 0xff, 0x04]
447            .as_slice()
448            .read_u16_leb128()
449            .await
450            .expect_err("u16 read should have failed, since it encoded 17 bits");
451
452        let v = [0xff, 0xff, 0xff, 0xff, 0x0f]
453            .as_slice()
454            .read_u32_leb128()
455            .await
456            .expect("failed to read u32");
457        assert_eq!(v, u32::MAX);
458
459        [0xff, 0xff, 0xff, 0xff, 0x10]
460            .as_slice()
461            .read_u32_leb128()
462            .await
463            .expect_err("u32 read should have failed, since it encoded 33 bits");
464
465        let v = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]
466            .as_slice()
467            .read_u64_leb128()
468            .await
469            .expect("failed to read u64");
470        assert_eq!(v, u64::MAX);
471
472        [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02]
473            .as_slice()
474            .read_u64_leb128()
475            .await
476            .expect_err("u64 read should have failed, since it encoded 65 bits");
477
478        let v = [
479            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
480            0xff, 0xff, 0xff, 0xff, 0x03,
481        ]
482        .as_slice()
483        .read_u128_leb128()
484        .await
485        .expect("failed to read u128");
486        assert_eq!(v, u128::MAX);
487
488        [
489            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
490            0xff, 0xff, 0xff, 0xff, 0x04,
491        ]
492        .as_slice()
493        .read_u128_leb128()
494        .await
495        .expect_err("u128 read should have failed, since it encoded 129 bits");
496    }
497
498    #[tokio::test]
499    async fn signed_leb128() {
500        const ENCODED: [u8; 3] = [0xc0, 0xbb, 0x78];
501
502        let v = ENCODED
503            .as_slice()
504            .read_i32_leb128()
505            .await
506            .expect("failed to read i32");
507        assert_eq!(v, -123_456);
508
509        let v = ENCODED
510            .as_slice()
511            .read_i64_leb128()
512            .await
513            .expect("failed to read i64");
514        assert_eq!(v, -123_456);
515
516        let mut buf = vec![];
517        buf.write_i32_leb128(-123_456)
518            .await
519            .expect("failed to write i32");
520        assert_eq!(buf, ENCODED);
521
522        let mut buf = vec![];
523        buf.write_i64_leb128(-123_456)
524            .await
525            .expect("failed to write i64");
526        assert_eq!(buf, ENCODED);
527
528        let mut buf = vec![];
529        buf.write_i64_leb128(-1).await.expect("failed to write i64");
530        assert_eq!(buf, [0x7f]);
531
532        let mut buf = vec![];
533        buf.write_i64_leb128(-2).await.expect("failed to write i64");
534        assert_eq!(buf, [0x7e]);
535
536        let v = [0x80, 0x7f]
537            .as_slice()
538            .read_i8_leb128()
539            .await
540            .expect("failed to read i8");
541        assert_eq!(v, i8::MIN);
542
543        let v = [0x7f]
544            .as_slice()
545            .read_i8_leb128()
546            .await
547            .expect("failed to read i8");
548        assert_eq!(v, -1);
549
550        let v = [0xff, 0x00]
551            .as_slice()
552            .read_i8_leb128()
553            .await
554            .expect("failed to read i8");
555        assert_eq!(v, 0x7f);
556
557        [0xff, 0x02]
558            .as_slice()
559            .read_i8_leb128()
560            .await
561            .expect_err("i8 read should have failed, since it encoded 9 bits");
562
563        let v = [0xff, 0xff, 0x01]
564            .as_slice()
565            .read_i16_leb128()
566            .await
567            .expect("failed to read i16");
568        assert_eq!(v, 0x7fff);
569
570        let v = [0xff, 0xff, 0x7e]
571            .as_slice()
572            .read_i16_leb128()
573            .await
574            .expect("failed to read i16");
575        assert_eq!(v, -0x4001);
576
577        let v = [0xff, 0xff, 0x7f]
578            .as_slice()
579            .read_i16_leb128()
580            .await
581            .expect("failed to read i16");
582        assert_eq!(v, -1);
583
584        [0xff, 0xff, 0x04]
585            .as_slice()
586            .read_i16_leb128()
587            .await
588            .expect_err("i16 read should have failed, since it encoded 17 bits");
589
590        let v = [0x7f]
591            .as_slice()
592            .read_i32_leb128()
593            .await
594            .expect("failed to read i32");
595        assert_eq!(v, -1);
596
597        let v = [0x7e]
598            .as_slice()
599            .read_i32_leb128()
600            .await
601            .expect("failed to read i32");
602        assert_eq!(v, -2);
603
604        let v = [0xff, 0xff, 0xff, 0xff, 0x7f]
605            .as_slice()
606            .read_i32_leb128()
607            .await
608            .expect("failed to read i32");
609        assert_eq!(v, -1);
610
611        let v = [0xfe, 0xff, 0xff, 0xff, 0x7f]
612            .as_slice()
613            .read_i32_leb128()
614            .await
615            .expect("failed to read i32");
616        assert_eq!(v, -2);
617
618        [0xff, 0xff, 0xff, 0xff, 0x10]
619            .as_slice()
620            .read_i32_leb128()
621            .await
622            .expect_err("i32 read should have failed, since it encoded 33 bits");
623
624        let v = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]
625            .as_slice()
626            .read_i64_leb128()
627            .await
628            .expect("failed to read i64");
629        assert_eq!(v, -1);
630
631        [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02]
632            .as_slice()
633            .read_i64_leb128()
634            .await
635            .expect_err("i64 read should have failed, since it encoded 65 bits");
636
637        let v = [
638            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
639            0xff, 0xff, 0xff, 0xff, 0x7f,
640        ]
641        .as_slice()
642        .read_i128_leb128()
643        .await
644        .expect("failed to read i128");
645        assert_eq!(v, -1);
646
647        [
648            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
649            0xff, 0xff, 0xff, 0xff, 0x04,
650        ]
651        .as_slice()
652        .read_i128_leb128()
653        .await
654        .expect_err("i128 read should have failed, since it encoded 129 bits");
655    }
656
657    #[tokio::test]
658    async fn signed_leb128_roundtrip() {
659        macro_rules! roundtrip {
660            ($write:ident, $read:ident, $decoder:ident, $values:expr) => {
661                for v in $values {
662                    let mut buf = vec![];
663                    buf.$write(v).await.expect("failed to encode");
664
665                    let got = buf
666                        .as_slice()
667                        .$read()
668                        .await
669                        .expect("failed to read back encoded value");
670                    assert_eq!(got, v, "async read mismatch for {v}, encoded as {buf:02x?}");
671
672                    let got = $decoder
673                        .decode(&mut buf.as_slice().into())
674                        .expect("failed to decode back encoded value")
675                        .expect("decoder returned no value");
676                    assert_eq!(got, v, "Decoder mismatch for {v}, encoded as {buf:02x?}");
677                }
678            };
679        }
680
681        roundtrip!(
682            write_i8_leb128,
683            read_i8_leb128,
684            Leb128DecoderI8,
685            [i8::MIN, i8::MAX, -1]
686        );
687        roundtrip!(
688            write_i16_leb128,
689            read_i16_leb128,
690            Leb128DecoderI16,
691            [i16::MIN, i16::MAX, -1]
692        );
693        roundtrip!(
694            write_i32_leb128,
695            read_i32_leb128,
696            Leb128DecoderI32,
697            [i32::MIN, i32::MAX, -1]
698        );
699        roundtrip!(
700            write_i64_leb128,
701            read_i64_leb128,
702            Leb128DecoderI64,
703            [i64::MIN, i64::MAX, -1]
704        );
705        roundtrip!(
706            write_i128_leb128,
707            read_i128_leb128,
708            Leb128DecoderI128,
709            [i128::MIN, i128::MAX, -1]
710        );
711    }
712
713    #[tokio::test]
714    async fn unsigned() {
715        let v = [0x01u8]
716            .as_slice()
717            .read_var_u8_leb128(2)
718            .await
719            .expect("failed to read u2");
720        assert_eq!(v, 1);
721
722        let v = [0x02]
723            .as_slice()
724            .read_var_u8_leb128(2)
725            .await
726            .expect("failed to read u2");
727        assert_eq!(v, 2);
728
729        let v = [0x03]
730            .as_slice()
731            .read_var_u8_leb128(2)
732            .await
733            .expect("failed to read u2");
734        assert_eq!(v, 3);
735
736        let v = [0xff, 0x03]
737            .as_slice()
738            .read_var_u16_leb128(9)
739            .await
740            .expect("failed to read u9");
741        assert_eq!(v, 0x1ff);
742
743        [0xff, 0x04]
744            .as_slice()
745            .read_var_u16_leb128(9)
746            .await
747            .expect_err("u9 read should have failed, since it encoded 10 bits");
748
749        [0b100]
750            .as_slice()
751            .read_var_u8_leb128(2)
752            .await
753            .expect_err("u2 read should have failed, since it encoded 3 bits");
754
755        [0x80, 0x80, 0x01]
756            .as_slice()
757            .read_var_u16_leb128(9)
758            .await
759            .expect_err("u9 read should have failed, since it used over 9 bits");
760
761        let v = [0x7f]
762            .as_slice()
763            .read_var_u8_leb128(7)
764            .await
765            .expect("failed to read u7");
766        assert_eq!(v, 0x7f);
767
768        [0x85, 0x00]
769            .as_slice()
770            .read_var_u8_leb128(7)
771            .await
772            .expect_err("u7 read should have failed, since it used over 1 byte");
773
774        [0x80, 0x80, 0x00]
775            .as_slice()
776            .read_var_u16_leb128(14)
777            .await
778            .expect_err("u14 read should have failed, since it used over 2 bytes");
779
780        let err = [0x01]
781            .as_slice()
782            .read_var_u8_leb128(20)
783            .await
784            .expect_err("u20 read into u8 should have failed");
785        assert_eq!(err.kind(), std::io::ErrorKind::InvalidInput);
786
787        let v = [0x80, 0x80, 0x80, 0x80, 0x80, 0x01]
788            .as_slice()
789            .read_var_u64_leb128(64)
790            .await
791            .expect("failed to read u64");
792        assert_eq!(v, 0b1000_0000_0000_0000_0000_0000_0000_0000_0000);
793    }
794
795    #[test]
796    fn truncated_eof() {
797        let mut src = BytesMut::from(b"\xe5\x8e".as_slice());
798        let err = Leb128DecoderU32
799            .decode_eof(&mut src)
800            .expect_err("truncated u32 must fail");
801        assert_eq!(err.kind(), std::io::ErrorKind::UnexpectedEof);
802
803        let mut src = BytesMut::from(b"\x80".as_slice());
804        let err = Leb128DecoderI64
805            .decode_eof(&mut src)
806            .expect_err("truncated i64 must fail");
807        assert_eq!(err.kind(), std::io::ErrorKind::UnexpectedEof);
808
809        assert!(Leb128DecoderU32
810            .decode_eof(&mut BytesMut::new())
811            .unwrap()
812            .is_none());
813    }
814}