qubit_io/traits/output.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
9use std::io::{
10 Result,
11 Write,
12};
13
14/// Minimal indexed output interface over units.
15///
16/// `Output` is intentionally smaller and lower-level than [`Write`]. It only
17/// states that an implementor can write up to `count` units from
18/// `input[index..index + count]`, plus an explicit flush operation. The caller
19/// owns range validation so hot paths can avoid repeated slicing and bounds
20/// checks.
21pub trait Output {
22 /// The unit type written to this output.
23 type Item;
24
25 /// Writes units from an indexed input range without checking the range.
26 ///
27 /// # Parameters
28 ///
29 /// * `input` - Source storage.
30 /// * `index` - Start index inside `input`.
31 /// * `count` - Maximum number of units to write.
32 ///
33 /// # Returns
34 ///
35 /// The number of units accepted from `input[index..index + count]`. The
36 /// value must be in `0..=count`.
37 ///
38 /// # Errors
39 ///
40 /// Returns the output error reported by the implementation.
41 ///
42 /// # Safety
43 ///
44 /// The caller must guarantee that `index..index + count` is a valid range
45 /// inside `input` and that the addition does not overflow.
46 unsafe fn write_unchecked(
47 &mut self,
48 input: &[Self::Item],
49 index: usize,
50 count: usize,
51 ) -> Result<usize>;
52
53 /// Flushes any internally buffered units.
54 ///
55 /// # Errors
56 ///
57 /// Returns the output error reported by the implementation.
58 fn flush(&mut self) -> Result<()>;
59}
60
61impl<W> Output for W
62where
63 W: Write + ?Sized,
64{
65 type Item = u8;
66
67 /// Writes bytes to a standard [`Write`] value from an indexed range.
68 #[inline(always)]
69 unsafe fn write_unchecked(
70 &mut self,
71 input: &[u8],
72 index: usize,
73 count: usize,
74 ) -> Result<usize> {
75 debug_assert!(
76 index
77 .checked_add(count)
78 .is_some_and(|end| end <= input.len()),
79 "unchecked write range exceeds input buffer"
80 );
81 // SAFETY: The caller guarantees that the range is valid inside
82 // `input`.
83 let source = unsafe {
84 core::slice::from_raw_parts(input.as_ptr().add(index), count)
85 };
86 self.write(source)
87 }
88
89 /// Flushes a standard [`Write`] value.
90 #[inline(always)]
91 fn flush(&mut self) -> Result<()> {
92 Write::flush(self)
93 }
94}