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 {}