@@ -6,7 +6,7 @@ mod tests;
6
6
use crate :: cmp;
7
7
use crate :: fmt:: { self , Debug , Formatter } ;
8
8
use crate :: io:: { Result , Write } ;
9
- use crate :: mem:: MaybeUninit ;
9
+ use crate :: mem:: { self , MaybeUninit } ;
10
10
11
11
/// A borrowed byte buffer which is incrementally filled and initialized.
12
12
///
@@ -23,9 +23,9 @@ use crate::mem::MaybeUninit;
23
23
/// ```
24
24
///
25
25
/// A `BorrowedBuf` is created around some existing data (or capacity for data) via a unique reference
26
- /// (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_init`), but otherwise
27
- /// is read-only . To write into the buffer, use `unfilled` to create a `BorrowedCursor`. The cursor
28
- /// has write-only access to the unfilled portion of the buffer (you can think of it like a
26
+ /// (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_init`), but cannot be
27
+ /// directly written . To write into the buffer, use `unfilled` to create a `BorrowedCursor`. The cursor
28
+ /// has write-only access to the unfilled portion of the buffer (you can think of it as a
29
29
/// write-only iterator).
30
30
///
31
31
/// The lifetime `'data` is a bound on the lifetime of the underlying data.
@@ -55,7 +55,7 @@ impl<'data> From<&'data mut [u8]> for BorrowedBuf<'data> {
55
55
let len = slice. len ( ) ;
56
56
57
57
BorrowedBuf {
58
- //SAFETY: initialized data never becoming uninitialized is an invariant of BorrowedBuf
58
+ // SAFETY: initialized data never becoming uninitialized is an invariant of BorrowedBuf
59
59
buf : unsafe { ( slice as * mut [ u8 ] ) . as_uninit_slice_mut ( ) . unwrap ( ) } ,
60
60
filled : 0 ,
61
61
init : len,
@@ -95,14 +95,21 @@ impl<'data> BorrowedBuf<'data> {
95
95
/// Returns a shared reference to the filled portion of the buffer.
96
96
#[ inline]
97
97
pub fn filled ( & self ) -> & [ u8 ] {
98
- //SAFETY: We only slice the filled part of the buffer, which is always valid
98
+ // SAFETY: We only slice the filled part of the buffer, which is always valid
99
99
unsafe { MaybeUninit :: slice_assume_init_ref ( & self . buf [ 0 ..self . filled ] ) }
100
100
}
101
101
102
102
/// Returns a cursor over the unfilled part of the buffer.
103
103
#[ inline]
104
- pub fn unfilled < ' this > ( & ' this mut self ) -> BorrowedCursor < ' this , ' data > {
105
- BorrowedCursor { start : self . filled , buf : self }
104
+ pub fn unfilled < ' this > ( & ' this mut self ) -> BorrowedCursor < ' this > {
105
+ BorrowedCursor {
106
+ start : self . filled ,
107
+ // SAFETY: we never assign into `BorrowedCursor::buf`, so treating its
108
+ // lifetime covariantly is safe.
109
+ buf : unsafe {
110
+ mem:: transmute :: < & ' this mut BorrowedBuf < ' data > , & ' this mut BorrowedBuf < ' this > > ( self )
111
+ } ,
112
+ }
106
113
}
107
114
108
115
/// Clears the buffer, resetting the filled region to empty.
@@ -141,25 +148,37 @@ impl<'data> BorrowedBuf<'data> {
141
148
/// `BorrowedBuf` and can no longer be accessed or re-written by the cursor. I.e., the cursor tracks
142
149
/// the unfilled part of the underlying `BorrowedBuf`.
143
150
///
144
- /// The `'buf` lifetime is a bound on the lifetime of the underlying buffer. `'data` is a bound on
145
- /// that buffer's underlying data .
151
+ /// The lifetime `'a` is a bound on the lifetime of the underlying buffer (which means it is a bound
152
+ /// on the data in that buffer by transitivity) .
146
153
#[ derive( Debug ) ]
147
- pub struct BorrowedCursor < ' buf , ' data > {
154
+ pub struct BorrowedCursor < ' a > {
148
155
/// The underlying buffer.
149
- buf : & ' buf mut BorrowedBuf < ' data > ,
156
+ // Safety invariant: we treat the type of buf as covariant in the lifetime of `BorrowedBuf` when
157
+ // we create a `BorrowedCursor`. This is only safe if we never replace `buf` by assigning into
158
+ // it, so don't do that!
159
+ buf : & ' a mut BorrowedBuf < ' a > ,
150
160
/// The length of the filled portion of the underlying buffer at the time of the cursor's
151
161
/// creation.
152
162
start : usize ,
153
163
}
154
164
155
- impl < ' buf , ' data > BorrowedCursor < ' buf , ' data > {
156
- /// Clone this cursor.
165
+ impl < ' a > BorrowedCursor < ' a > {
166
+ /// Reborrow this cursor by cloning it with a smaller lifetime .
157
167
///
158
- /// Since a cursor maintains unique access to its underlying buffer, the cloned cursor is not
159
- /// accessible while the clone is alive .
168
+ /// Since a cursor maintains unique access to its underlying buffer, the borrowed cursor is
169
+ /// not accessible while the new cursor exists .
160
170
#[ inline]
161
- pub fn clone < ' this > ( & ' this mut self ) -> BorrowedCursor < ' this , ' data > {
162
- BorrowedCursor { buf : self . buf , start : self . start }
171
+ pub fn reborrow < ' this > ( & ' this mut self ) -> BorrowedCursor < ' this > {
172
+ BorrowedCursor {
173
+ // SAFETY: we never assign into `BorrowedCursor::buf`, so treating its
174
+ // lifetime covariantly is safe.
175
+ buf : unsafe {
176
+ mem:: transmute :: < & ' this mut BorrowedBuf < ' a > , & ' this mut BorrowedBuf < ' this > > (
177
+ self . buf ,
178
+ )
179
+ } ,
180
+ start : self . start ,
181
+ }
163
182
}
164
183
165
184
/// Returns the available space in the cursor.
@@ -170,8 +189,8 @@ impl<'buf, 'data> BorrowedCursor<'buf, 'data> {
170
189
171
190
/// Returns the number of bytes written to this cursor since it was created from a `BorrowedBuf`.
172
191
///
173
- /// Note that if this cursor is a clone of another, then the count returned is the count written
174
- /// via either cursor, not the count since the cursor was cloned .
192
+ /// Note that if this cursor is a reborrowed clone of another, then the count returned is the
193
+ /// count written via either cursor, not the count since the cursor was reborrowed .
175
194
#[ inline]
176
195
pub fn written ( & self ) -> usize {
177
196
self . buf . filled - self . start
@@ -180,14 +199,14 @@ impl<'buf, 'data> BorrowedCursor<'buf, 'data> {
180
199
/// Returns a shared reference to the initialized portion of the cursor.
181
200
#[ inline]
182
201
pub fn init_ref ( & self ) -> & [ u8 ] {
183
- //SAFETY: We only slice the initialized part of the buffer, which is always valid
202
+ // SAFETY: We only slice the initialized part of the buffer, which is always valid
184
203
unsafe { MaybeUninit :: slice_assume_init_ref ( & self . buf . buf [ self . buf . filled ..self . buf . init ] ) }
185
204
}
186
205
187
206
/// Returns a mutable reference to the initialized portion of the cursor.
188
207
#[ inline]
189
208
pub fn init_mut ( & mut self ) -> & mut [ u8 ] {
190
- //SAFETY: We only slice the initialized part of the buffer, which is always valid
209
+ // SAFETY: We only slice the initialized part of the buffer, which is always valid
191
210
unsafe {
192
211
MaybeUninit :: slice_assume_init_mut ( & mut self . buf . buf [ self . buf . filled ..self . buf . init ] )
193
212
}
@@ -275,7 +294,7 @@ impl<'buf, 'data> BorrowedCursor<'buf, 'data> {
275
294
}
276
295
}
277
296
278
- impl < ' buf , ' data > Write for BorrowedCursor < ' buf , ' data > {
297
+ impl < ' a > Write for BorrowedCursor < ' a > {
279
298
fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize > {
280
299
self . append ( buf) ;
281
300
Ok ( buf. len ( ) )
0 commit comments