14
14
//!
15
15
//! # Octets
16
16
//!
17
- //! There is no special trait for octets, we simply use `AsRef<[u8]>`. This
18
- //! way, any type implementing these traits can be used as a basic octets
19
- //! already. Additional properties are signalled through additional traits.
20
- //! `AsMut<[u8]>` is used to signal the ability to manipulate the contents of
21
- //! an octets sequence (while the length is still fixed). The trait
22
- //! [`Truncate`] introduced by the crate signals that an octets sequence can
23
- //! be shortened.
17
+ //! In their most simple form, any type that implements `AsRef<[u8]>` can
18
+ //! serve as octets. However, in some cases additional functionality is
19
+ //! required.
24
20
//!
25
- //! # Octets References
26
- //!
27
- //! A reference to an octets type implements [`OctetsRef`]. The main purpose
28
- //! of this trait is to allow taking a sub-sequence, called a ‘range’,
29
- //! out of the octets in the cheapest way possible. For most types, ranges
30
- //! will be octet slices `&[u8]` but some shareable types (most notably
21
+ //! The trait [`Octets`] allows taking a sub-sequence, called a ‘range’, out
22
+ //! of the octets in the cheapest way possible. For most types, ranges will
23
+ //! be octet slices `&[u8]` but some shareable types (most notably
31
24
//! `bytes::Bytes`) allow ranges to be owned values, thus avoiding the
32
- //! lifetime limitations a slice would bring.
33
- //!
34
- //! One type is special in that it is its own octets reference: `&[u8]`,
35
- //! referred to as an _octets slice_ here. This means that you
36
- //! always use an octets slice regardless of whether a type is generic over
37
- //! an octets sequence or an octets reference.
38
- //!
39
- //! The [`OctetsRef`] trait is separate because of limitations of lifetimes
40
- //! in traits. It has an associated type `OctetsRef::Range` that defines the
41
- //! type of a range. When using the trait as a trait bound for a generic type,
42
- //! you will typically use a reference to this type. For instance, a generic
43
- //! function taking part out of some octets and returning a reference to it
44
- //! could be defined like so:
45
- //!
46
- //! ```
47
- //! # use octseq::OctetsRef;
48
- //!
49
- //! fn take_part<'a, Octets>(
50
- //! src: &'a Octets
51
- //! ) -> <&'a Octets as OctetsRef>::Range
52
- //! where &'a Octets: OctetsRef {
53
- //! unimplemented!()
54
- //! }
55
- //! ```
56
- //!
57
- //! The where clause demands that whatever octets type is being used, a
58
- //! reference to it must be an octets ref. The return value refers to the
59
- //! range type defined for this octets ref. The lifetime argument is
60
- //! necessary to tie all these references together.
61
- //!
25
+ //! lifetime limitations a slice would bring. Therefore, `Octets` allows
26
+ //! defining the type of a range as an associated type.
62
27
//!
63
28
//! # Octets Builders
64
29
//!
106
71
//! eager you may paint yourself into a corner.
107
72
//!
108
73
//! In many cases you can get away with a simple `AsRef<[u8]>` bound. Only use
109
- //! an explicit `OctetsRef ` bound when you need to return a range that may be
74
+ //! an explicit `Octets ` bound when you need to return a range that may be
110
75
//! kept around.
111
76
//!
112
77
//! Similarly, only demand of an octets builder what you actually need. Even
@@ -124,110 +89,105 @@ use core::convert::Infallible;
124
89
125
90
//============ Octets and Octet Builders =====================================
126
91
92
+ //------------ Octets --------------------------------------------------------
127
93
128
- //------------ OctetsRef -----------------------------------------------------
129
-
130
- /// A reference to an octets sequence.
131
- ///
132
- /// This trait is to be implemented for a (immutable) reference to a type of
133
- /// an octets sequence. I.e., it `T` is an octets sequence, `OctetsRef` needs
134
- /// to be implemented for `&T`.
94
+ /// A type representing an octets sequence.
135
95
///
136
96
/// The primary purpose of the trait is to allow access to a sub-sequence,
137
97
/// called a ‘range.’ The type of this range is given via the `Range`
138
- /// associated type. For most types it will be a `&[u8]` with a lifetime equal
139
- /// to that of the reference itself . Only if an owned range can be created
98
+ /// associated type. For most types it will be a `&[u8]` with a lifetime
99
+ /// equal to that of a reference. Only if an owned range can be created
140
100
/// cheaply, it should be that type.
141
- ///
142
- /// There is two basic ways of using the trait for a trait bound. You can
143
- /// either limit the octets sequence type itself by bounding references to it
144
- /// via a where clause. I.e., for an octets sequence type argument `Octets`
145
- /// you can specify `where &'a Octets: OctetsRef` or, if you don’t have a
146
- /// lifetime argument available `where for<'a> &'a Octets: OctetsRef`. For
147
- /// this option, you’d typically refer to values as references to the
148
- /// octets type, i.e., `&Octets`.
149
- ///
150
- /// Alternatively, you can refer to the reference itself as a owned value.
151
- /// This works out fine since all octets references are required to be
152
- /// `Copy`. For instance, a function can take a value of generic type `Oref`
153
- /// and that type can then be directly bounded via `Oref: OctetsRef`.
154
- pub trait OctetsRef : AsRef < [ u8 ] > + Copy + Sized {
155
- /// The type of a range of the sequence.
156
- type Range : AsRef < [ u8 ] > ;
101
+ pub trait Octets : AsRef < [ u8 ] > {
102
+ type Range < ' a > : Octets where Self : ' a ;
157
103
158
104
/// Returns a sub-sequence or ‘range’ of the sequence.
159
- fn range ( self , start : usize , end : usize ) -> Self :: Range ;
105
+ ///
106
+ /// # Panics
107
+ ///
108
+ /// The method should panic if `start` or `end` are greater than the
109
+ /// length of the octets sequence or if `start` is greater than `end`.
110
+ fn range ( & self , start : usize , end : usize ) -> Self :: Range < ' _ > ;
160
111
161
112
/// Returns a range starting at index `start` and going to the end.
162
- fn range_from ( self , start : usize ) -> Self :: Range {
113
+ ///
114
+ /// # Panics
115
+ ///
116
+ /// The method should panic if `start` is greater than the
117
+ /// length of the octets sequence.
118
+ fn range_from ( & self , start : usize ) -> Self :: Range < ' _ > {
163
119
self . range ( start, self . as_ref ( ) . len ( ) )
164
120
}
165
121
166
122
/// Returns a range from the start to before index `end`.
167
- fn range_to ( self , end : usize ) -> Self :: Range {
123
+ ///
124
+ /// # Panics
125
+ ///
126
+ /// The method should panic if `end` is greater than the
127
+ /// length of the octets sequence.
128
+ fn range_to ( & self , end : usize ) -> Self :: Range < ' _ > {
168
129
self . range ( 0 , end)
169
130
}
170
131
171
132
/// Returns a range that covers the entire sequence.
172
- fn range_all ( self ) -> Self :: Range {
133
+ fn range_all ( & self ) -> Self :: Range < ' _ > {
173
134
self . range ( 0 , self . as_ref ( ) . len ( ) )
174
135
}
175
136
}
176
137
177
- impl < ' a , T : OctetsRef > OctetsRef for & ' a T {
178
- type Range = T :: Range ;
138
+ impl < ' t , T : Octets + ? Sized > Octets for & ' t T {
139
+ type Range < ' a > = < T as Octets > :: Range < ' a > where Self : ' a ;
179
140
180
- fn range ( self , start : usize , end : usize ) -> Self :: Range {
141
+ fn range ( & self , start : usize , end : usize ) -> Self :: Range < ' _ > {
181
142
( * self ) . range ( start, end)
182
143
}
183
144
}
184
145
185
- impl < ' a > OctetsRef for & ' a [ u8 ] {
186
- type Range = & ' a [ u8 ] ;
146
+ impl Octets for [ u8 ] {
147
+ type Range < ' a > = & ' a [ u8 ] ;
187
148
188
- fn range ( self , start : usize , end : usize ) -> Self :: Range {
149
+ fn range ( & self , start : usize , end : usize ) -> Self :: Range < ' _ > {
189
150
& self [ start..end]
190
151
}
191
152
}
192
153
193
154
#[ cfg( feature = "std" ) ]
194
- impl < ' a , ' s > OctetsRef for & ' a Cow < ' s , [ u8 ] > {
195
- type Range = & ' a [ u8 ] ;
155
+ impl < ' c > Octets for Cow < ' c , [ u8 ] > {
156
+ type Range < ' a > = & ' a [ u8 ] where Self : ' a ;
196
157
197
- fn range ( self , start : usize , end : usize ) -> Self :: Range {
158
+ fn range ( & self , start : usize , end : usize ) -> Self :: Range < ' _ > {
198
159
& self . as_ref ( ) [ start..end]
199
160
}
200
161
}
201
162
202
163
#[ cfg( feature = "std" ) ]
203
- impl < ' a > OctetsRef for & ' a Vec < u8 > {
204
- type Range = & ' a [ u8 ] ;
164
+ impl Octets for Vec < u8 > {
165
+ type Range < ' a > = & ' a [ u8 ] ;
205
166
206
- fn range ( self , start : usize , end : usize ) -> Self :: Range {
167
+ fn range ( & self , start : usize , end : usize ) -> Self :: Range < ' _ > {
207
168
& self [ start..end]
208
169
}
209
170
}
210
171
211
172
#[ cfg( feature = "bytes" ) ]
212
- impl < ' a > OctetsRef for & ' a Bytes {
213
- type Range = Bytes ;
173
+ impl Octets for Bytes {
174
+ type Range < ' a > = Bytes ;
214
175
215
- fn range ( self , start : usize , end : usize ) -> Self :: Range {
176
+ fn range ( & self , start : usize , end : usize ) -> Self :: Range < ' _ > {
216
177
self . slice ( start..end)
217
178
}
218
179
}
219
180
220
181
#[ cfg( feature = "smallvec" ) ]
221
- impl < ' a , A : smallvec:: Array < Item = u8 > >
222
- OctetsRef for & ' a smallvec:: SmallVec < A >
223
- {
224
- type Range = & ' a [ u8 ] ;
182
+ impl < A : smallvec:: Array < Item = u8 > > Octets for smallvec:: SmallVec < A > {
183
+ type Range < ' a > = & ' a [ u8 ] where A : ' a ;
225
184
226
- fn range ( self , start : usize , end : usize ) -> Self :: Range {
185
+ fn range ( & self , start : usize , end : usize ) -> Self :: Range < ' _ > {
227
186
& self . as_slice ( ) [ start..end]
228
187
}
229
188
}
230
189
190
+
231
191
//------------ Truncate ------------------------------------------------------
232
192
233
193
/// An octet sequence that can be shortened.
0 commit comments