@@ -25,6 +25,52 @@ use std::task::{Context, Poll};
2525/// Reads bytes from a source.
2626///
2727/// This trait is similar to `std::io::Read`, but supports asynchronous reads.
28+ ///
29+ /// # Implementing `Read`
30+ ///
31+ /// Implementations should read data into the provided [`ReadBufCursor`] and
32+ /// advance the cursor to indicate how many bytes were written. The simplest
33+ /// and safest approach is to use [`ReadBufCursor::put_slice`]:
34+ ///
35+ /// ```
36+ /// use hyper::rt::{Read, ReadBufCursor};
37+ /// use std::pin::Pin;
38+ /// use std::task::{Context, Poll};
39+ /// use std::io;
40+ ///
41+ /// struct MyReader {
42+ /// data: Vec<u8>,
43+ /// position: usize,
44+ /// }
45+ ///
46+ /// impl Read for MyReader {
47+ /// fn poll_read(
48+ /// mut self: Pin<&mut Self>,
49+ /// _cx: &mut Context<'_>,
50+ /// mut buf: ReadBufCursor<'_>,
51+ /// ) -> Poll<Result<(), io::Error>> {
52+ /// let remaining_data = &self.data[self.position..];
53+ /// if remaining_data.is_empty() {
54+ /// // No more data to read, signal EOF by returning Ok without
55+ /// // advancing the buffer
56+ /// return Poll::Ready(Ok(()));
57+ /// }
58+ ///
59+ /// // Calculate how many bytes we can write
60+ /// let to_copy = remaining_data.len().min(buf.remaining());
61+ /// // Use put_slice to safely copy data and advance the cursor
62+ /// buf.put_slice(&remaining_data[..to_copy]);
63+ ///
64+ /// self.position += to_copy;
65+ /// Poll::Ready(Ok(()))
66+ /// }
67+ /// }
68+ /// ```
69+ ///
70+ /// For more advanced use cases where you need direct access to the buffer
71+ /// (e.g., when interfacing with APIs that write directly to a pointer),
72+ /// you can use the unsafe [`ReadBufCursor::as_mut`] and [`ReadBufCursor::advance`]
73+ /// methods. See their documentation for safety requirements.
2874pub trait Read {
2975 /// Attempts to read bytes into the `buf`.
3076 ///
@@ -124,9 +170,62 @@ pub struct ReadBuf<'a> {
124170 init : usize ,
125171}
126172
127- /// The cursor part of a [`ReadBuf`].
173+ /// The cursor part of a [`ReadBuf`], representing the unfilled portion.
174+ ///
175+ /// This is created by calling [`ReadBuf::unfilled()`].
176+ ///
177+ /// `ReadBufCursor` provides safe and unsafe methods for writing data into the
178+ /// buffer:
179+ ///
180+ /// - **Safe approach**: Use [`put_slice`](Self::put_slice) to copy data from
181+ /// a slice. This handles initialization tracking and cursor advancement
182+ /// automatically.
183+ ///
184+ /// - **Unsafe approach**: For zero-copy scenarios or when interfacing with
185+ /// low-level APIs, use [`as_mut`](Self::as_mut) to get a mutable slice
186+ /// of `MaybeUninit<u8>`, then call [`advance`](Self::advance) after writing.
187+ /// This is more efficient but requires careful attention to safety invariants.
128188///
129- /// This is created by calling `ReadBuf::unfilled()`.
189+ /// # Example using safe methods
190+ ///
191+ /// ```
192+ /// use hyper::rt::ReadBuf;
193+ ///
194+ /// let mut backing = [0u8; 64];
195+ /// let mut read_buf = ReadBuf::new(&mut backing);
196+ ///
197+ /// {
198+ /// let mut cursor = read_buf.unfilled();
199+ /// // put_slice handles everything safely
200+ /// cursor.put_slice(b"hello");
201+ /// }
202+ ///
203+ /// assert_eq!(read_buf.filled(), b"hello");
204+ /// ```
205+ ///
206+ /// # Example using unsafe methods
207+ ///
208+ /// ```
209+ /// use hyper::rt::ReadBuf;
210+ ///
211+ /// let mut backing = [0u8; 64];
212+ /// let mut read_buf = ReadBuf::new(&mut backing);
213+ ///
214+ /// {
215+ /// let mut cursor = read_buf.unfilled();
216+ /// // SAFETY: we will initialize exactly 5 bytes
217+ /// let slice = unsafe { cursor.as_mut() };
218+ /// slice[0].write(b'h');
219+ /// slice[1].write(b'e');
220+ /// slice[2].write(b'l');
221+ /// slice[3].write(b'l');
222+ /// slice[4].write(b'o');
223+ /// // SAFETY: we have initialized 5 bytes
224+ /// unsafe { cursor.advance(5) };
225+ /// }
226+ ///
227+ /// assert_eq!(read_buf.filled(), b"hello");
228+ /// ```
130229#[ derive( Debug ) ]
131230pub struct ReadBufCursor < ' a > {
132231 buf : & ' a mut ReadBuf < ' a > ,
0 commit comments