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::{
12 Read,
13 Result,
14};
15
16use crate::{
17 Input,
18 UncheckedSlice,
19 traits::validate_read_count,
20};
21
22/// Bridges byte-oriented standard readers to item-oriented input.
23impl<R> Input for R
24where
25 R: Read + ?Sized,
26{
27 /// Bytes read by the standard Read implementation.
28 type Item = u8;
29
30 /// Reads bytes into a caller-validated indexed output range.
31 ///
32 /// # Parameters
33 ///
34 /// - `output`: Destination byte slice.
35 /// - `index`: Start offset inside `output`.
36 /// - `count`: Maximum number of bytes to read.
37 ///
38 /// # Returns
39 ///
40 /// The number of bytes reported by the standard reader.
41 ///
42 /// # Errors
43 ///
44 /// Returns the error reported by the standard reader.
45 ///
46 /// # Panics
47 ///
48 /// Panics in debug builds if the requested destination range does not fit.
49 ///
50 /// # Safety
51 ///
52 /// The caller must ensure that index through index plus count is a valid
53 /// range inside output without overflowing.
54 #[inline(always)]
55 unsafe fn read_unchecked(
56 &mut self,
57 output: &mut [u8],
58 index: usize,
59 count: usize,
60 ) -> Result<usize> {
61 // SAFETY: The caller guarantees that the range is valid inside output.
62 let target =
63 unsafe { UncheckedSlice::subslice_mut(output, index, count) };
64 Read::read(self, target)
65 }
66
67 /// Reads bytes into the complete output slice.
68 ///
69 /// # Parameters
70 ///
71 /// - `output`: Destination byte slice.
72 ///
73 /// # Returns
74 ///
75 /// The number of bytes read into `output`.
76 ///
77 /// # Errors
78 ///
79 /// Returns [`std::io::ErrorKind::InvalidData`] if the reader reports more
80 /// bytes than `output` holds, or the error reported by the standard reader.
81 #[inline(always)]
82 fn read(&mut self, output: &mut [Self::Item]) -> Result<usize> {
83 let read = Read::read(self, output)?;
84 validate_read_count(read, output.len())?;
85 Ok(read)
86 }
87}