1#![cfg(feature = "std")]
2#![cfg_attr(docsrs, doc(cfg(feature = "std")))]
3
4use std::io::{Bytes, Error, Read, Result, Write};
5
6use super::{Overflow, Varint};
7
8macro_rules! write_impl {
9 ($type:ty, $name:ident) => {
10 #[doc = "Writes a LEB128-encoded `"]
11 #[doc = stringify!($type)]
12 #[doc = "` and returns the number of bytes written."]
13 fn $name(&mut self, x: $type) -> Result<usize> {
14 self.write_int(x)
15 }
16 };
17}
18
19pub trait WriteVarint: Write {
22 fn write_int<T: Varint>(&mut self, x: T) -> Result<usize> {
25 let mut buf = T::Buf::default();
26 let encoded = x.write(&mut buf);
27 self.write_all(encoded)?;
28 Ok(encoded.len())
29 }
30
31 write_impl!(u8, write_u8);
32 write_impl!(u16, write_u16);
33 write_impl!(u32, write_u32);
34 write_impl!(u64, write_u64);
35 write_impl!(u128, write_u128);
36 write_impl!(usize, write_usize);
37
38 write_impl!(i8, write_i8);
39 write_impl!(i16, write_i16);
40 write_impl!(i32, write_i32);
41 write_impl!(i64, write_i64);
42 write_impl!(i128, write_i128);
43 write_impl!(isize, write_isize);
44}
45
46macro_rules! read_impl {
47 ($type:ty, $name:ident) => {
48 #[doc = "Reads a LEB128-encoded `"]
49 #[doc = stringify!($type)]
50 #[doc = "`."]
51 fn $name(&mut self) -> Result<$type> {
52 self.read_int()
53 }
54 };
55}
56
57impl<W: Write + ?Sized> WriteVarint for W {}
58
59pub trait ReadVarint: Read {
62 fn read_int<T: Varint>(&mut self) -> Result<T> {
64 let mut iter = Iter::new(self.bytes());
65 let (v, _) = T::read_iter(&mut iter).map_err(Error::other)?;
66 if let Some(err) = iter.err {
67 Err(err)
68 } else {
69 Ok(v)
70 }
71 }
72
73 read_impl!(u8, read_u8);
74 read_impl!(u16, read_u16);
75 read_impl!(u32, read_u32);
76 read_impl!(u64, read_u64);
77 read_impl!(u128, read_u128);
78 read_impl!(usize, read_usize);
79
80 read_impl!(i8, read_i8);
81 read_impl!(i16, read_i16);
82 read_impl!(i32, read_i32);
83 read_impl!(i64, read_i64);
84 read_impl!(i128, read_i128);
85 read_impl!(isize, read_isize);
86}
87
88impl<R: Read + ?Sized> ReadVarint for R {}
89
90impl From<Overflow> for Error {
91 fn from(err: Overflow) -> Self {
92 Error::other(err)
93 }
94}
95
96struct Iter<R> {
97 inner: Bytes<R>,
98 err: Option<Error>,
99}
100
101impl<R> Iter<R> {
102 const fn new(inner: Bytes<R>) -> Self {
103 Self { inner, err: None }
104 }
105}
106
107impl<R: Read> Iterator for Iter<R> {
108 type Item = u8;
109
110 fn next(&mut self) -> Option<Self::Item> {
111 match self.err {
112 Some(_) => None,
113 None => match self.inner.next()? {
114 Ok(v) => Some(v),
115 Err(err) => {
116 self.err = Some(err);
117 None
118 }
119 },
120 }
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 const TESTS: &[i128] = &[
129 -1 << 127,
130 (-1 << 127) + 1,
131 -1 << 63,
132 (-1 << 63) + 1,
133 -1,
134 0,
135 1,
136 2,
137 10,
138 20,
139 63,
140 64,
141 65,
142 127,
143 128,
144 129,
145 255,
146 256,
147 257,
148 (1 << 63) - 1,
149 i128::MAX,
150 ];
151
152 macro_rules! test_impl {
153 ($name:ident, $type:ty, $write:ident, $read:ident) => {
154 #[test]
155 fn $name() {
156 fn test<F>(buf: &mut [u8], want: $type, name: &str, mut f: F)
157 where
158 F: FnMut(&mut [u8], $type) -> Result<usize>,
159 {
160 buf.fill(0xff);
161
162 let got = f(buf, want).unwrap_or_else(|_| {
163 panic!("`{name}({want}{})` should not fail", stringify!($type))
164 });
165 assert_eq!(
166 got,
167 want.encoded_len(),
168 "`{name}({want})` != encoded_len({want})"
169 );
170
171 let mut tmp = (&*buf);
172 let got = tmp
173 .$read()
174 .unwrap_or_else(|_| panic!("`{}` should not fail", stringify!($read)));
175 assert_eq!(got, want, "`{}`", stringify!($read));
176
177 let got = (&*buf).read_int::<$type>().unwrap_or_else(|_| {
178 panic!(
179 "`read_int::<{}>({want})` should not fail",
180 stringify!($type)
181 )
182 });
183 assert_eq!(got, want, "`read_int::<{}>`", stringify!($type));
184 }
185
186 let mut buf = vec![0x80u8; 100];
187 for &x in TESTS {
188 let Ok(want) = x.try_into() else {
189 continue;
190 };
191 test(&mut buf, want, stringify!($write), |mut buf, want| {
192 buf.$write(want)
193 });
194 test(&mut buf, want, stringify!("write_int"), |mut buf, want| {
195 buf.write_int(want)
196 });
197 }
198 }
199 };
200 }
201 test_impl!(test_io_u8, u8, write_u8, read_u8);
202 test_impl!(test_io_u16, u16, write_u16, read_u16);
203 test_impl!(test_io_u32, u32, write_u32, read_u32);
204 test_impl!(test_io_u64, u64, write_u64, read_u64);
205 test_impl!(test_io_u128, u128, write_u128, read_u128);
206 test_impl!(test_io_usize, usize, write_usize, read_usize);
207
208 test_impl!(test_io_i8, i8, write_i8, read_i8);
209 test_impl!(test_io_i16, i16, write_i16, read_i16);
210 test_impl!(test_io_i32, i32, write_i32, read_i32);
211 test_impl!(test_io_i64, i64, write_i64, read_i64);
212 test_impl!(test_io_i128, i128, write_i128, read_i128);
213 test_impl!(test_io_isize, isize, write_isize, read_isize);
214}