@@ -8,32 +8,22 @@ use core::mem::MaybeUninit;
8
8
use core:: slice;
9
9
10
10
/// A memory buffer that may be uninitialized.
11
- pub trait Buffer < T > {
12
- /// The result of the process operation.
13
- type Result ;
14
-
15
- /// Convert this buffer into a maybe-unitiailized view.
16
- fn as_maybe_uninitialized ( & mut self ) -> & mut [ MaybeUninit < T > ] ;
17
-
18
- /// Convert a finished buffer pointer into its result.
19
- ///
20
- /// # Safety
21
- ///
22
- /// At least `len` bytes of the buffer must now be initialized.
23
- unsafe fn finish ( self , len : usize ) -> Self :: Result ;
24
- }
11
+ pub trait Buffer < T > : private:: Sealed < T > { }
25
12
26
- /// Implements [`Buffer`] around the a slice of bytes.
27
- ///
28
- /// `Result` is a `usize` indicating how many bytes were written.
29
- impl < T > Buffer < T > for & mut [ T ] {
13
+ // Implement `Buffer` for all the types that implement `Sealed`.
14
+ impl < T > Buffer < T > for & mut [ T ] { }
15
+ impl < T , const N : usize > Buffer < T > for & mut [ T ; N ] { }
16
+ impl < T > Buffer < T > for & mut Vec < T > { }
17
+ impl < ' a , T > Buffer < T > for & ' a mut [ MaybeUninit < T > ] { }
18
+ impl < ' a , T , const N : usize > Buffer < T > for & ' a mut [ MaybeUninit < T > ; N ] { }
19
+ impl < T > Buffer < T > for Vec < T > { }
20
+
21
+ impl < T > private:: Sealed < T > for & mut [ T ] {
30
22
type Result = usize ;
31
23
32
24
#[ inline]
33
- fn as_maybe_uninitialized ( & mut self ) -> & mut [ MaybeUninit < T > ] {
34
- // SAFETY: This just casts away the knowledge that the elements are
35
- // initialized.
36
- unsafe { core:: mem:: transmute :: < & mut [ T ] , & mut [ MaybeUninit < T > ] > ( self ) }
25
+ fn as_raw_parts_mut ( & mut self ) -> ( * mut T , usize ) {
26
+ ( self . as_mut_ptr ( ) , self . len ( ) )
37
27
}
38
28
39
29
#[ inline]
@@ -42,17 +32,12 @@ impl<T> Buffer<T> for &mut [T] {
42
32
}
43
33
}
44
34
45
- /// Implements [`Buffer`] around the a slice of bytes.
46
- ///
47
- /// `Result` is a `usize` indicating how many bytes were written.
48
- impl < T , const N : usize > Buffer < T > for & mut [ T ; N ] {
35
+ impl < T , const N : usize > private:: Sealed < T > for & mut [ T ; N ] {
49
36
type Result = usize ;
50
37
51
38
#[ inline]
52
- fn as_maybe_uninitialized ( & mut self ) -> & mut [ MaybeUninit < T > ] {
53
- // SAFETY: This just casts away the knowledge that the elements are
54
- // initialized.
55
- unsafe { core:: mem:: transmute :: < & mut [ T ] , & mut [ MaybeUninit < T > ] > ( * self ) }
39
+ fn as_raw_parts_mut ( & mut self ) -> ( * mut T , usize ) {
40
+ ( self . as_mut_ptr ( ) , N )
56
41
}
57
42
58
43
#[ inline]
@@ -61,17 +46,15 @@ impl<T, const N: usize> Buffer<T> for &mut [T; N] {
61
46
}
62
47
}
63
48
64
- /// Implements [`Buffer`] around the a slice of bytes.
65
- ///
66
- /// `Result` is a `usize` indicating how many bytes were written .
67
- impl < T > Buffer < T > for & mut Vec < T > {
49
+ // `Vec` implements `DerefMut` to `&mut [T]`, however it doesn't get
50
+ // auto-derefed in a `impl Buffer<u8>`, so we add this `impl` so that our users
51
+ // don't have to add an extra `*` in these situations .
52
+ impl < T > private :: Sealed < T > for & mut Vec < T > {
68
53
type Result = usize ;
69
54
70
55
#[ inline]
71
- fn as_maybe_uninitialized ( & mut self ) -> & mut [ MaybeUninit < T > ] {
72
- // SAFETY: This just casts away the knowledge that the elements are
73
- // initialized.
74
- unsafe { core:: mem:: transmute :: < & mut [ T ] , & mut [ MaybeUninit < T > ] > ( self ) }
56
+ fn as_raw_parts_mut ( & mut self ) -> ( * mut T , usize ) {
57
+ ( self . as_mut_ptr ( ) , self . len ( ) )
75
58
}
76
59
77
60
#[ inline]
@@ -80,16 +63,31 @@ impl<T> Buffer<T> for &mut Vec<T> {
80
63
}
81
64
}
82
65
83
- /// Implements [`Buffer`] around the a slice of uninitialized bytes.
84
- ///
85
- /// `Result` is a pair of slices giving the initialized and uninitialized
86
- /// subslices after the new data is written.
87
- impl < ' a , T > Buffer < T > for & ' a mut [ MaybeUninit < T > ] {
66
+ impl < ' a , T > private:: Sealed < T > for & ' a mut [ MaybeUninit < T > ] {
88
67
type Result = ( & ' a mut [ T ] , & ' a mut [ MaybeUninit < T > ] ) ;
89
68
90
69
#[ inline]
91
- fn as_maybe_uninitialized ( & mut self ) -> & mut [ MaybeUninit < T > ] {
92
- self
70
+ fn as_raw_parts_mut ( & mut self ) -> ( * mut T , usize ) {
71
+ ( self . as_mut_ptr ( ) . cast ( ) , self . len ( ) )
72
+ }
73
+
74
+ #[ inline]
75
+ unsafe fn finish ( self , len : usize ) -> Self :: Result {
76
+ let ( init, uninit) = self . split_at_mut ( len) ;
77
+
78
+ // SAFETY: The user asserts that the slice is now initialized.
79
+ let init = slice:: from_raw_parts_mut ( init. as_mut_ptr ( ) . cast :: < T > ( ) , init. len ( ) ) ;
80
+
81
+ ( init, uninit)
82
+ }
83
+ }
84
+
85
+ impl < ' a , T , const N : usize > private:: Sealed < T > for & ' a mut [ MaybeUninit < T > ; N ] {
86
+ type Result = ( & ' a mut [ T ] , & ' a mut [ MaybeUninit < T > ] ) ;
87
+
88
+ #[ inline]
89
+ fn as_raw_parts_mut ( & mut self ) -> ( * mut T , usize ) {
90
+ ( self . as_mut_ptr ( ) . cast ( ) , self . len ( ) )
93
91
}
94
92
95
93
#[ inline]
@@ -103,18 +101,14 @@ impl<'a, T> Buffer<T> for &'a mut [MaybeUninit<T>] {
103
101
}
104
102
}
105
103
106
- /// Implements [`Buffer`] around the `Vec` type.
107
- ///
108
- /// This implementation fills the buffer, overwriting any previous data, with
109
- /// the new data data and sets the length.
110
104
#[ cfg( feature = "alloc" ) ]
111
- impl < T > Buffer < T > for Vec < T > {
105
+ impl < T > private :: Sealed < T > for Vec < T > {
112
106
type Result = Vec < T > ;
113
107
114
108
#[ inline]
115
- fn as_maybe_uninitialized ( & mut self ) -> & mut [ MaybeUninit < T > ] {
109
+ fn as_raw_parts_mut ( & mut self ) -> ( * mut T , usize ) {
116
110
self . clear ( ) ;
117
- self . spare_capacity_mut ( )
111
+ ( self . as_mut_ptr ( ) , self . capacity ( ) )
118
112
}
119
113
120
114
#[ inline]
@@ -143,6 +137,23 @@ pub(super) unsafe fn split_init(
143
137
( init, uninit)
144
138
}
145
139
140
+ mod private {
141
+ pub trait Sealed < T > {
142
+ /// The result of the process operation.
143
+ type Result ;
144
+
145
+ /// Return a pointer and length for this buffer.
146
+ fn as_raw_parts_mut ( & mut self ) -> ( * mut T , usize ) ;
147
+
148
+ /// Convert a finished buffer pointer into its result.
149
+ ///
150
+ /// # Safety
151
+ ///
152
+ /// At least `len` bytes of the buffer must now be initialized.
153
+ unsafe fn finish ( self , len : usize ) -> Self :: Result ;
154
+ }
155
+ }
156
+
146
157
#[ cfg( test) ]
147
158
mod tests {
148
159
use super :: * ;
0 commit comments