Skip to main content

qubit_io/ext/
binary_read_ext.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use std::io::{
11    Read,
12    Result,
13};
14
15use crate::ByteOrder;
16
17/// Extension methods for reading binary scalar values from [`Read`] streams.
18///
19/// Multi-byte values can be read either with explicit byte-order suffixes or
20/// with a runtime [`ByteOrder`] argument. All methods read exactly the required
21/// number of bytes and therefore return [`std::io::ErrorKind::UnexpectedEof`]
22/// when the stream ends early.
23pub trait BinaryReadExt: Read {
24    /// Reads one unsigned byte.
25    ///
26    /// # Returns
27    /// The byte value.
28    ///
29    /// # Errors
30    /// Returns an I/O error from the underlying reader, including
31    /// `UnexpectedEof` when no byte is available.
32    fn read_u8(&mut self) -> Result<u8>;
33
34    /// Reads one signed byte.
35    ///
36    /// # Returns
37    /// The byte interpreted as `i8`.
38    ///
39    /// # Errors
40    /// Returns an I/O error from the underlying reader, including
41    /// `UnexpectedEof` when no byte is available.
42    fn read_i8(&mut self) -> Result<i8>;
43
44    /// Reads a `u16` using `order`.
45    ///
46    /// # Parameters
47    /// - `order`: Byte order used to decode the value.
48    ///
49    /// # Returns
50    /// The decoded value.
51    ///
52    /// # Errors
53    /// Returns an I/O error when two bytes cannot be read.
54    #[inline]
55    fn read_u16(&mut self, order: ByteOrder) -> Result<u16> {
56        match order {
57            ByteOrder::BigEndian => self.read_u16_be(),
58            ByteOrder::LittleEndian => self.read_u16_le(),
59        }
60    }
61
62    /// Reads a big-endian `u16`.
63    ///
64    /// # Returns
65    /// The decoded value.
66    ///
67    /// # Errors
68    /// Returns an I/O error when two bytes cannot be read.
69    fn read_u16_be(&mut self) -> Result<u16>;
70
71    /// Reads a little-endian `u16`.
72    ///
73    /// # Returns
74    /// The decoded value.
75    ///
76    /// # Errors
77    /// Returns an I/O error when two bytes cannot be read.
78    fn read_u16_le(&mut self) -> Result<u16>;
79
80    /// Reads an `i16` using `order`.
81    ///
82    /// # Parameters
83    /// - `order`: Byte order used to decode the value.
84    ///
85    /// # Returns
86    /// The decoded value.
87    ///
88    /// # Errors
89    /// Returns an I/O error when two bytes cannot be read.
90    #[inline]
91    fn read_i16(&mut self, order: ByteOrder) -> Result<i16> {
92        match order {
93            ByteOrder::BigEndian => self.read_i16_be(),
94            ByteOrder::LittleEndian => self.read_i16_le(),
95        }
96    }
97
98    /// Reads a big-endian `i16`.
99    ///
100    /// # Returns
101    /// The decoded value.
102    ///
103    /// # Errors
104    /// Returns an I/O error when two bytes cannot be read.
105    fn read_i16_be(&mut self) -> Result<i16>;
106
107    /// Reads a little-endian `i16`.
108    ///
109    /// # Returns
110    /// The decoded value.
111    ///
112    /// # Errors
113    /// Returns an I/O error when two bytes cannot be read.
114    fn read_i16_le(&mut self) -> Result<i16>;
115
116    /// Reads a `u32` using `order`.
117    ///
118    /// # Parameters
119    /// - `order`: Byte order used to decode the value.
120    ///
121    /// # Returns
122    /// The decoded value.
123    ///
124    /// # Errors
125    /// Returns an I/O error when four bytes cannot be read.
126    #[inline]
127    fn read_u32(&mut self, order: ByteOrder) -> Result<u32> {
128        match order {
129            ByteOrder::BigEndian => self.read_u32_be(),
130            ByteOrder::LittleEndian => self.read_u32_le(),
131        }
132    }
133
134    /// Reads a big-endian `u32`.
135    ///
136    /// # Returns
137    /// The decoded value.
138    ///
139    /// # Errors
140    /// Returns an I/O error when four bytes cannot be read.
141    fn read_u32_be(&mut self) -> Result<u32>;
142
143    /// Reads a little-endian `u32`.
144    ///
145    /// # Returns
146    /// The decoded value.
147    ///
148    /// # Errors
149    /// Returns an I/O error when four bytes cannot be read.
150    fn read_u32_le(&mut self) -> Result<u32>;
151
152    /// Reads an `i32` using `order`.
153    ///
154    /// # Parameters
155    /// - `order`: Byte order used to decode the value.
156    ///
157    /// # Returns
158    /// The decoded value.
159    ///
160    /// # Errors
161    /// Returns an I/O error when four bytes cannot be read.
162    #[inline]
163    fn read_i32(&mut self, order: ByteOrder) -> Result<i32> {
164        match order {
165            ByteOrder::BigEndian => self.read_i32_be(),
166            ByteOrder::LittleEndian => self.read_i32_le(),
167        }
168    }
169
170    /// Reads a big-endian `i32`.
171    ///
172    /// # Returns
173    /// The decoded value.
174    ///
175    /// # Errors
176    /// Returns an I/O error when four bytes cannot be read.
177    fn read_i32_be(&mut self) -> Result<i32>;
178
179    /// Reads a little-endian `i32`.
180    ///
181    /// # Returns
182    /// The decoded value.
183    ///
184    /// # Errors
185    /// Returns an I/O error when four bytes cannot be read.
186    fn read_i32_le(&mut self) -> Result<i32>;
187
188    /// Reads a `u64` using `order`.
189    ///
190    /// # Parameters
191    /// - `order`: Byte order used to decode the value.
192    ///
193    /// # Returns
194    /// The decoded value.
195    ///
196    /// # Errors
197    /// Returns an I/O error when eight bytes cannot be read.
198    #[inline]
199    fn read_u64(&mut self, order: ByteOrder) -> Result<u64> {
200        match order {
201            ByteOrder::BigEndian => self.read_u64_be(),
202            ByteOrder::LittleEndian => self.read_u64_le(),
203        }
204    }
205
206    /// Reads a big-endian `u64`.
207    ///
208    /// # Returns
209    /// The decoded value.
210    ///
211    /// # Errors
212    /// Returns an I/O error when eight bytes cannot be read.
213    fn read_u64_be(&mut self) -> Result<u64>;
214
215    /// Reads a little-endian `u64`.
216    ///
217    /// # Returns
218    /// The decoded value.
219    ///
220    /// # Errors
221    /// Returns an I/O error when eight bytes cannot be read.
222    fn read_u64_le(&mut self) -> Result<u64>;
223
224    /// Reads an `i64` using `order`.
225    ///
226    /// # Parameters
227    /// - `order`: Byte order used to decode the value.
228    ///
229    /// # Returns
230    /// The decoded value.
231    ///
232    /// # Errors
233    /// Returns an I/O error when eight bytes cannot be read.
234    #[inline]
235    fn read_i64(&mut self, order: ByteOrder) -> Result<i64> {
236        match order {
237            ByteOrder::BigEndian => self.read_i64_be(),
238            ByteOrder::LittleEndian => self.read_i64_le(),
239        }
240    }
241
242    /// Reads a big-endian `i64`.
243    ///
244    /// # Returns
245    /// The decoded value.
246    ///
247    /// # Errors
248    /// Returns an I/O error when eight bytes cannot be read.
249    fn read_i64_be(&mut self) -> Result<i64>;
250
251    /// Reads a little-endian `i64`.
252    ///
253    /// # Returns
254    /// The decoded value.
255    ///
256    /// # Errors
257    /// Returns an I/O error when eight bytes cannot be read.
258    fn read_i64_le(&mut self) -> Result<i64>;
259
260    /// Reads a `u128` using `order`.
261    ///
262    /// # Parameters
263    /// - `order`: Byte order used to decode the value.
264    ///
265    /// # Returns
266    /// The decoded value.
267    ///
268    /// # Errors
269    /// Returns an I/O error when sixteen bytes cannot be read.
270    #[inline]
271    fn read_u128(&mut self, order: ByteOrder) -> Result<u128> {
272        match order {
273            ByteOrder::BigEndian => self.read_u128_be(),
274            ByteOrder::LittleEndian => self.read_u128_le(),
275        }
276    }
277
278    /// Reads a big-endian `u128`.
279    ///
280    /// # Returns
281    /// The decoded value.
282    ///
283    /// # Errors
284    /// Returns an I/O error when sixteen bytes cannot be read.
285    fn read_u128_be(&mut self) -> Result<u128>;
286
287    /// Reads a little-endian `u128`.
288    ///
289    /// # Returns
290    /// The decoded value.
291    ///
292    /// # Errors
293    /// Returns an I/O error when sixteen bytes cannot be read.
294    fn read_u128_le(&mut self) -> Result<u128>;
295
296    /// Reads an `i128` using `order`.
297    ///
298    /// # Parameters
299    /// - `order`: Byte order used to decode the value.
300    ///
301    /// # Returns
302    /// The decoded value.
303    ///
304    /// # Errors
305    /// Returns an I/O error when sixteen bytes cannot be read.
306    #[inline]
307    fn read_i128(&mut self, order: ByteOrder) -> Result<i128> {
308        match order {
309            ByteOrder::BigEndian => self.read_i128_be(),
310            ByteOrder::LittleEndian => self.read_i128_le(),
311        }
312    }
313
314    /// Reads a big-endian `i128`.
315    ///
316    /// # Returns
317    /// The decoded value.
318    ///
319    /// # Errors
320    /// Returns an I/O error when sixteen bytes cannot be read.
321    fn read_i128_be(&mut self) -> Result<i128>;
322
323    /// Reads a little-endian `i128`.
324    ///
325    /// # Returns
326    /// The decoded value.
327    ///
328    /// # Errors
329    /// Returns an I/O error when sixteen bytes cannot be read.
330    fn read_i128_le(&mut self) -> Result<i128>;
331
332    /// Reads an IEEE-754 `f32` using `order`.
333    ///
334    /// # Parameters
335    /// - `order`: Byte order used to decode the value.
336    ///
337    /// # Returns
338    /// The decoded value.
339    ///
340    /// # Errors
341    /// Returns an I/O error when four bytes cannot be read.
342    #[inline]
343    fn read_f32(&mut self, order: ByteOrder) -> Result<f32> {
344        match order {
345            ByteOrder::BigEndian => self.read_f32_be(),
346            ByteOrder::LittleEndian => self.read_f32_le(),
347        }
348    }
349
350    /// Reads a big-endian IEEE-754 `f32`.
351    ///
352    /// # Returns
353    /// The decoded value.
354    ///
355    /// # Errors
356    /// Returns an I/O error when four bytes cannot be read.
357    fn read_f32_be(&mut self) -> Result<f32>;
358
359    /// Reads a little-endian IEEE-754 `f32`.
360    ///
361    /// # Returns
362    /// The decoded value.
363    ///
364    /// # Errors
365    /// Returns an I/O error when four bytes cannot be read.
366    fn read_f32_le(&mut self) -> Result<f32>;
367
368    /// Reads an IEEE-754 `f64` using `order`.
369    ///
370    /// # Parameters
371    /// - `order`: Byte order used to decode the value.
372    ///
373    /// # Returns
374    /// The decoded value.
375    ///
376    /// # Errors
377    /// Returns an I/O error when eight bytes cannot be read.
378    #[inline]
379    fn read_f64(&mut self, order: ByteOrder) -> Result<f64> {
380        match order {
381            ByteOrder::BigEndian => self.read_f64_be(),
382            ByteOrder::LittleEndian => self.read_f64_le(),
383        }
384    }
385
386    /// Reads a big-endian IEEE-754 `f64`.
387    ///
388    /// # Returns
389    /// The decoded value.
390    ///
391    /// # Errors
392    /// Returns an I/O error when eight bytes cannot be read.
393    fn read_f64_be(&mut self) -> Result<f64>;
394
395    /// Reads a little-endian IEEE-754 `f64`.
396    ///
397    /// # Returns
398    /// The decoded value.
399    ///
400    /// # Errors
401    /// Returns an I/O error when eight bytes cannot be read.
402    fn read_f64_le(&mut self) -> Result<f64>;
403}
404
405impl<T> BinaryReadExt for T
406where
407    T: Read + ?Sized,
408{
409    #[inline]
410    fn read_u8(&mut self) -> Result<u8> {
411        read_bytes::<_, 1>(self).map(|buffer| buffer[0])
412    }
413
414    #[inline]
415    fn read_i8(&mut self) -> Result<i8> {
416        read_bytes::<_, 1>(self).map(|buffer| buffer[0] as i8)
417    }
418
419    #[inline]
420    fn read_u16_be(&mut self) -> Result<u16> {
421        read_bytes::<_, 2>(self).map(u16::from_be_bytes)
422    }
423
424    #[inline]
425    fn read_u16_le(&mut self) -> Result<u16> {
426        read_bytes::<_, 2>(self).map(u16::from_le_bytes)
427    }
428
429    #[inline]
430    fn read_i16_be(&mut self) -> Result<i16> {
431        read_bytes::<_, 2>(self).map(i16::from_be_bytes)
432    }
433
434    #[inline]
435    fn read_i16_le(&mut self) -> Result<i16> {
436        read_bytes::<_, 2>(self).map(i16::from_le_bytes)
437    }
438
439    #[inline]
440    fn read_u32_be(&mut self) -> Result<u32> {
441        read_bytes::<_, 4>(self).map(u32::from_be_bytes)
442    }
443
444    #[inline]
445    fn read_u32_le(&mut self) -> Result<u32> {
446        read_bytes::<_, 4>(self).map(u32::from_le_bytes)
447    }
448
449    #[inline]
450    fn read_i32_be(&mut self) -> Result<i32> {
451        read_bytes::<_, 4>(self).map(i32::from_be_bytes)
452    }
453
454    #[inline]
455    fn read_i32_le(&mut self) -> Result<i32> {
456        read_bytes::<_, 4>(self).map(i32::from_le_bytes)
457    }
458
459    #[inline]
460    fn read_u64_be(&mut self) -> Result<u64> {
461        read_bytes::<_, 8>(self).map(u64::from_be_bytes)
462    }
463
464    #[inline]
465    fn read_u64_le(&mut self) -> Result<u64> {
466        read_bytes::<_, 8>(self).map(u64::from_le_bytes)
467    }
468
469    #[inline]
470    fn read_i64_be(&mut self) -> Result<i64> {
471        read_bytes::<_, 8>(self).map(i64::from_be_bytes)
472    }
473
474    #[inline]
475    fn read_i64_le(&mut self) -> Result<i64> {
476        read_bytes::<_, 8>(self).map(i64::from_le_bytes)
477    }
478
479    #[inline]
480    fn read_u128_be(&mut self) -> Result<u128> {
481        read_bytes::<_, 16>(self).map(u128::from_be_bytes)
482    }
483
484    #[inline]
485    fn read_u128_le(&mut self) -> Result<u128> {
486        read_bytes::<_, 16>(self).map(u128::from_le_bytes)
487    }
488
489    #[inline]
490    fn read_i128_be(&mut self) -> Result<i128> {
491        read_bytes::<_, 16>(self).map(i128::from_be_bytes)
492    }
493
494    #[inline]
495    fn read_i128_le(&mut self) -> Result<i128> {
496        read_bytes::<_, 16>(self).map(i128::from_le_bytes)
497    }
498
499    #[inline]
500    fn read_f32_be(&mut self) -> Result<f32> {
501        read_bytes::<_, 4>(self).map(|buffer| f32::from_bits(u32::from_be_bytes(buffer)))
502    }
503
504    #[inline]
505    fn read_f32_le(&mut self) -> Result<f32> {
506        read_bytes::<_, 4>(self).map(|buffer| f32::from_bits(u32::from_le_bytes(buffer)))
507    }
508
509    #[inline]
510    fn read_f64_be(&mut self) -> Result<f64> {
511        read_bytes::<_, 8>(self).map(|buffer| f64::from_bits(u64::from_be_bytes(buffer)))
512    }
513
514    #[inline]
515    fn read_f64_le(&mut self) -> Result<f64> {
516        read_bytes::<_, 8>(self).map(|buffer| f64::from_bits(u64::from_le_bytes(buffer)))
517    }
518}
519
520/// Reads exactly `N` bytes from `reader`.
521///
522/// # Parameters
523/// - `reader`: Source reader. It may be a sized reader or a reader trait
524///   object.
525///
526/// # Returns
527/// An array containing the bytes read from the stream.
528///
529/// # Errors
530/// Returns an I/O error from [`Read::read_exact`], including
531/// [`std::io::ErrorKind::UnexpectedEof`] when fewer than `N` bytes are
532/// available.
533fn read_bytes<R, const N: usize>(reader: &mut R) -> Result<[u8; N]>
534where
535    R: Read + ?Sized,
536{
537    let mut buffer = [0; N];
538    reader.read_exact(&mut buffer)?;
539    Ok(buffer)
540}