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}