tokio_util_codec_compose/primitives/ints.rs
1//! Codec for integers.
2
3use bytes::{Buf, BufMut};
4
5/// Codec for an [`u8`].
6///
7/// # Examples
8///
9/// ## Decoding
10///
11/// ```
12/// # use bytes::BytesMut;
13/// # use tokio_util::codec::Decoder;
14/// # use tokio_util_codec_compose::primitives::ints::U8;
15/// let mut decoder = U8::default();
16///
17/// let res = decoder.decode(&mut BytesMut::from("\x2A")).unwrap();
18///
19/// assert_eq!(res, Some(42))
20/// ```
21///
22/// ## Encoding
23///
24/// ```
25/// # use bytes::BytesMut;
26/// # use tokio_util::codec::Encoder;
27/// # use tokio_util_codec_compose::primitives::ints::U8;
28/// let mut encoder = U8::default();
29///
30/// let mut dst = BytesMut::default();
31/// encoder.encode(0x2A, &mut dst).unwrap();
32///
33/// assert_eq!(dst, BytesMut::from("\x2A"))
34/// ```
35#[must_use = "decoders do nothing unless used"]
36#[derive(Debug, Default)]
37pub struct U8;
38
39/// Codec for an [`u16`] big-endian.
40///
41/// # Examples
42///
43/// ## Decoding
44///
45/// ```
46/// # use bytes::BytesMut;
47/// # use tokio_util::codec::Decoder;
48/// # use tokio_util_codec_compose::primitives::ints::U16BE;
49/// let mut decoder = U16BE::default();
50///
51/// let res = decoder.decode(&mut BytesMut::from("\x2A\x3B")).unwrap();
52///
53/// assert_eq!(res, Some(0x2A3B))
54/// ```
55///
56/// ## Encoding
57///
58/// ```
59/// # use bytes::BytesMut;
60/// # use tokio_util::codec::Encoder;
61/// # use tokio_util_codec_compose::primitives::ints::U16BE;
62/// let mut encoder = U16BE::default();
63///
64/// let mut dst = BytesMut::default();
65/// encoder.encode(0x2A3B, &mut dst).unwrap();
66///
67/// assert_eq!(dst, BytesMut::from("\x2A\x3B"))
68/// ```
69#[must_use = "codecs do nothing unless used"]
70#[derive(Debug, Default)]
71pub struct U16BE;
72
73/// Codec for an [`u16`] little-endian.
74///
75/// # Examples
76///
77/// ## Decoding
78///
79/// ```
80/// # use bytes::BytesMut;
81/// # use tokio_util::codec::Decoder;
82/// # use tokio_util_codec_compose::primitives::ints::U16LE;
83/// let mut decoder = U16LE::default();
84///
85/// let res = decoder.decode(&mut BytesMut::from("\x2A\x3B")).unwrap();
86///
87/// assert_eq!(res, Some(0x3B2A))
88/// ```
89///
90/// ## Encoding
91///
92/// ```
93/// # use bytes::BytesMut;
94/// # use tokio_util::codec::Encoder;
95/// # use tokio_util_codec_compose::primitives::ints::U16LE;
96/// let mut encoder = U16LE::default();
97///
98/// let mut dst = BytesMut::default();
99/// encoder.encode(0x2A3B, &mut dst).unwrap();
100///
101/// assert_eq!(dst, BytesMut::from("\x3B\x2A"))
102/// ```
103#[must_use = "codecs do nothing unless used"]
104#[derive(Debug, Default)]
105pub struct U16LE;
106
107/// Codec for an [`u32`] big-endian.
108///
109/// # Examples
110///
111/// ## Decoding
112///
113/// ```
114/// # use bytes::BytesMut;
115/// # use tokio_util::codec::Decoder;
116/// # use tokio_util_codec_compose::primitives::ints::U32BE;
117/// let mut decoder = U32BE::default();
118///
119/// let res = decoder.decode(&mut BytesMut::from("\x2A\x3B\x4C\x5D")).unwrap();
120///
121/// assert_eq!(res, Some(0x2A3B4C5D))
122/// ```
123///
124/// ## Encoding
125///
126/// ```
127/// # use bytes::BytesMut;
128/// # use tokio_util::codec::Encoder;
129/// # use tokio_util_codec_compose::primitives::ints::U32BE;
130/// let mut encoder = U32BE::default();
131///
132/// let mut dst = BytesMut::default();
133/// encoder.encode(0x2A3B4C5D, &mut dst).unwrap();
134///
135/// assert_eq!(dst, BytesMut::from("\x2A\x3B\x4C\x5D"))
136/// ```
137#[must_use = "codecs do nothing unless used"]
138#[derive(Debug, Default)]
139pub struct U32BE;
140
141/// Codec for an [`u32`] little-endian.
142///
143/// # Examples
144///
145/// ## Decoding
146///
147/// ```
148/// # use bytes::BytesMut;
149/// # use tokio_util::codec::Decoder;
150/// # use tokio_util_codec_compose::primitives::ints::U32LE;
151/// let mut decoder = U32LE::default();
152///
153/// let res = decoder.decode(&mut BytesMut::from("\x2A\x3B\x4C\x5D")).unwrap();
154///
155/// assert_eq!(res, Some(0x5D4C3B2A))
156/// ```
157///
158/// ## Encoding
159///
160/// ```
161/// # use bytes::BytesMut;
162/// # use tokio_util::codec::Encoder;
163/// # use tokio_util_codec_compose::primitives::ints::U32LE;
164/// let mut encoder = U32LE::default();
165///
166/// let mut dst = BytesMut::default();
167/// encoder.encode(0x5D4C3B2A, &mut dst).unwrap();
168///
169/// assert_eq!(dst, BytesMut::from("\x2A\x3B\x4C\x5D"))
170/// ```
171#[must_use = "codecs do nothing unless used"]
172#[derive(Debug, Default)]
173pub struct U32LE;
174
175macro_rules! impl_decoder {
176 ($type:ty, $value:ty, $len:expr, $get:ident) => {
177 impl ::tokio_util::codec::Decoder for $type {
178 type Item = $value;
179
180 type Error = std::io::Error;
181
182 fn decode(
183 &mut self,
184 src: &mut ::bytes::BytesMut,
185 ) -> Result<Option<Self::Item>, Self::Error> {
186 if src.len() < $len {
187 Ok(None)
188 } else {
189 Ok(src.$get().into())
190 }
191 }
192 }
193 };
194}
195
196impl_decoder!(U8, u8, 1, get_u8);
197impl_decoder!(U16BE, u16, 2, get_u16);
198impl_decoder!(U16LE, u16, 2, get_u16_le);
199impl_decoder!(U32BE, u32, 4, get_u32);
200impl_decoder!(U32LE, u32, 4, get_u32_le);
201
202macro_rules! impl_encoder {
203 ($type:ty, $value:ty, $len:expr, $put:ident) => {
204 impl ::tokio_util::codec::Encoder<$value> for $type {
205 type Error = std::io::Error;
206
207 fn encode(
208 &mut self,
209 item: $value,
210 dst: &mut ::bytes::BytesMut,
211 ) -> Result<(), Self::Error> {
212 dst.reserve($len);
213 dst.$put(item);
214 Ok(())
215 }
216 }
217 };
218}
219
220impl_encoder!(U8, u8, 1, put_u8);
221impl_encoder!(U16BE, u16, 2, put_u16);
222impl_encoder!(U16LE, u16, 2, put_u16_le);
223impl_encoder!(U32BE, u32, 4, put_u32);
224impl_encoder!(U32LE, u32, 4, put_u32_le);
225
226#[cfg(test)]
227mod tests {
228 use super::*;
229 use anyhow::Result;
230 use bytes::BytesMut;
231 use std::{error, fmt::Debug};
232 use tokio_util::codec::Decoder;
233
234 #[test]
235 fn u8_decode() -> Result<()> {
236 check(CheckOpts {
237 decoder: U8,
238 src: BytesMut::from("\x2A\x00\x01\x02\x03"),
239 expected_output: 0x2A,
240 expected_remainder: BytesMut::from("\x00\x01\x02\x03"),
241 })
242 }
243
244 #[test]
245 fn u16be_decode() -> Result<()> {
246 check(CheckOpts {
247 decoder: U16BE,
248 src: BytesMut::from("\x2A\x3B\x01\x02\x03"),
249 expected_output: 0x2A3B,
250 expected_remainder: BytesMut::from("\x01\x02\x03"),
251 })
252 }
253
254 #[test]
255 fn u16le_decode() -> Result<()> {
256 check(CheckOpts {
257 decoder: U16LE,
258 src: BytesMut::from("\x2A\x3B\x01\x02\x03"),
259 expected_output: 0x3B2A,
260 expected_remainder: BytesMut::from("\x01\x02\x03"),
261 })
262 }
263
264 #[test]
265 fn u32be_decode() -> Result<()> {
266 check(CheckOpts {
267 decoder: U32BE,
268 src: BytesMut::from("\x2A\x3B\x01\x02\x03"),
269 expected_output: 0x2A3B_0102,
270 expected_remainder: BytesMut::from("\x03"),
271 })
272 }
273
274 #[test]
275 fn u32le_decode() -> Result<()> {
276 check(CheckOpts {
277 decoder: U32LE,
278 src: BytesMut::from("\x2A\x3B\x01\x02\x03"),
279 expected_output: 0x0201_3B2A,
280 expected_remainder: BytesMut::from("\x03"),
281 })
282 }
283
284 #[track_caller]
285 fn check<D, A>(
286 CheckOpts {
287 mut decoder,
288 mut src,
289 expected_output,
290 expected_remainder,
291 }: CheckOpts<D, A>,
292 ) -> Result<()>
293 where
294 D: Decoder<Item = A>,
295 A: PartialEq + Debug,
296 D::Error: error::Error + Send + Sync + 'static,
297 {
298 let output = decoder.decode(&mut src)?;
299
300 assert_eq!(output, Some(expected_output));
301 assert_eq!(src, expected_remainder);
302
303 Ok(())
304 }
305
306 #[derive(Debug)]
307 struct CheckOpts<D, A> {
308 decoder: D,
309 src: BytesMut,
310 expected_output: A,
311 expected_remainder: BytesMut,
312 }
313}