Skip to main content

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}