Skip to main content

qubit_io/std_io/ext/
write_ext.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//! Extension operations for standard byte writers.
10
11use std::io::{
12    Result,
13    Write,
14};
15
16use crate::util::UncheckedSlice;
17
18/// Extension methods for [`Write`] values.
19///
20/// `WriteExt` provides small method-style helpers for byte writers. The
21/// methods are implemented for every type that implements [`Write`], including
22/// `dyn Write` trait objects.
23pub trait WriteExt: Write {
24    /// Writes bytes from a range of `buffer` without checking the range bounds
25    /// in release builds.
26    ///
27    /// This method delegates to [`Write::write`] after creating the source
28    /// slice with raw pointer arithmetic. It performs at most one write
29    /// operation and returns the number of bytes written, keeping the same
30    /// short-write and error behavior as [`Write::write`].
31    ///
32    /// # Parameters
33    /// - `buffer`: Source buffer.
34    /// - `start_index`: Start offset inside `buffer`.
35    /// - `count`: Maximum number of bytes to write.
36    ///
37    /// # Returns
38    /// The number of bytes written from `buffer[start_index..start_index +
39    /// count]`. The value is in `0..=count`.
40    ///
41    /// # Errors
42    /// Returns the error reported by [`Write::write`].
43    ///
44    /// # Panics
45    /// Panics in debug builds if the requested source range does not fit.
46    ///
47    /// # Safety
48    /// The caller must guarantee that `start_index..start_index + count` is a
49    /// valid range within `buffer` and that `start_index + count` does not
50    /// overflow `usize`.
51    #[inline(always)]
52    unsafe fn write_unchecked(
53        &mut self,
54        buffer: &[u8],
55        start_index: usize,
56        count: usize,
57    ) -> Result<usize> {
58        // SAFETY: The caller guarantees that the computed pointer and length
59        // form a valid subslice of `buffer`.
60        let source =
61            unsafe { UncheckedSlice::subslice(buffer, start_index, count) };
62        self.write(source)
63    }
64
65    /// Writes exactly `count` bytes from a range of `buffer` without checking
66    /// the range bounds in release builds.
67    ///
68    /// This method delegates to [`Write::write_all`] after creating the source
69    /// slice with raw pointer arithmetic. It keeps the same short-write,
70    /// [`std::io::ErrorKind::Interrupted`], and
71    /// [`std::io::ErrorKind::WriteZero`] behavior as [`Write::write_all`].
72    ///
73    /// # Parameters
74    /// - `buffer`: Source buffer.
75    /// - `start_index`: Start offset inside `buffer`.
76    /// - `count`: Number of bytes to write.
77    ///
78    /// # Returns
79    /// `Ok(())` after the requested range has been written.
80    ///
81    /// # Errors
82    /// Returns the error reported by [`Write::write_all`].
83    ///
84    /// # Panics
85    /// Panics in debug builds if the requested source range does not fit.
86    ///
87    /// # Safety
88    /// The caller must guarantee that `start_index..start_index + count` is a
89    /// valid range within `buffer` and that `start_index + count` does not
90    /// overflow `usize`.
91    #[inline(always)]
92    unsafe fn write_all_unchecked(
93        &mut self,
94        buffer: &[u8],
95        start_index: usize,
96        count: usize,
97    ) -> Result<()> {
98        // SAFETY: The caller guarantees that the computed pointer and length
99        // form a valid subslice of `buffer`.
100        let source =
101            unsafe { UncheckedSlice::subslice(buffer, start_index, count) };
102        self.write_all(source)
103    }
104}
105
106impl<T> WriteExt for T where T: Write + ?Sized {}