qubit_io/std_io/impls/input.rs
1// =============================================================================
2// Copyright (c) 2026 Haixing Hu.
3//
4// SPDX-License-Identifier: Apache-2.0
5//
6// Licensed under the Apache License, Version 2.0.
7// =============================================================================
8
9//! Standard [`Read`](std::io::Read) implementations of item input traits.
10
11use std::io::Read;
12use std::io::Result;
13
14use crate::Input;
15use crate::traits::validate_read_count;
16use crate::util::UncheckedSlice;
17
18/// Bridges byte-oriented standard readers to item-oriented input.
19impl<R> Input for R
20where
21 R: Read + ?Sized,
22{
23 /// Bytes read by the standard Read implementation.
24 type Item = u8;
25
26 /// Reads bytes into a caller-validated indexed output range.
27 ///
28 /// # Parameters
29 ///
30 /// - `output`: Destination byte slice.
31 /// - `index`: Start offset inside `output`.
32 /// - `count`: Maximum number of bytes to read.
33 ///
34 /// # Returns
35 ///
36 /// The number of bytes reported by the standard reader.
37 ///
38 /// # Errors
39 ///
40 /// Returns the error reported by the standard reader.
41 ///
42 /// # Panics
43 ///
44 /// Panics in debug builds if the requested destination range does not fit.
45 ///
46 /// # Safety
47 ///
48 /// The caller must ensure that index through index plus count is a valid
49 /// range inside output without overflowing.
50 #[inline(always)]
51 unsafe fn read_unchecked(&mut self, output: &mut [u8], index: usize, count: usize) -> Result<usize> {
52 // SAFETY: The caller guarantees that the range is valid inside output.
53 let target = unsafe { UncheckedSlice::subslice_mut(output, index, count) };
54 Read::read(self, target)
55 }
56
57 /// Reads bytes into the complete output slice.
58 ///
59 /// # Parameters
60 ///
61 /// - `output`: Destination byte slice.
62 ///
63 /// # Returns
64 ///
65 /// The number of bytes read into `output`.
66 ///
67 /// # Errors
68 ///
69 /// Returns [`std::io::ErrorKind::InvalidData`] if the reader reports more
70 /// bytes than `output` holds, or the error reported by the standard reader.
71 #[inline(always)]
72 fn read(&mut self, output: &mut [Self::Item]) -> Result<usize> {
73 let read = Read::read(self, output)?;
74 validate_read_count(read, output.len())?;
75 Ok(read)
76 }
77
78 /// Reads from the buffers in order using the standard reader's vectored
79 /// method. Returns `InvalidInput` if their total length overflows,
80 /// `OutOfMemory` if descriptor preparation fails before I/O, or
81 /// `InvalidData` if the reader reports more than the total capacity. Short
82 /// progress and reader errors are returned without retrying or undoing
83 /// underlying side effects.
84 fn read_vectored(&mut self, buffers: &mut [&mut [u8]]) -> Result<usize> {
85 let capacity = crate::util::requested_items(buffers.iter().map(|buffer| buffer.len()))?;
86 if capacity == 0 {
87 return Ok(0);
88 }
89 let mut slices = crate::util::io_slices_mut(buffers)?;
90 let count = Read::read_vectored(self, &mut slices)?;
91 validate_read_count(count, capacity)?;
92 Ok(count)
93 }
94}