@@ -5,27 +5,43 @@ use crate::{
5
5
Tag , Writer , asn1:: AnyRef , ord:: OrdIsValueOrd ,
6
6
} ;
7
7
8
+ // TODO(tarcieri): custom derive hack until the logic is updated to support `&'a` reference types
9
+ #[ doc( hidden) ]
10
+ pub type OctetStringRef2 < ' a > = & ' a OctetStringRef ;
11
+
8
12
/// ASN.1 `OCTET STRING` type: borrowed form.
9
13
///
10
14
/// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
11
15
///
12
16
/// This is a zero-copy reference type which borrows from the input data.
13
- #[ derive( Copy , Clone , Debug , Eq , PartialEq , PartialOrd , Ord ) ]
14
- pub struct OctetStringRef < ' a > {
17
+ #[ derive( Debug , Eq , Hash , PartialEq , PartialOrd , Ord ) ]
18
+ #[ repr( transparent) ]
19
+ pub struct OctetStringRef {
15
20
/// Inner value
16
- inner : & ' a BytesRef ,
21
+ inner : BytesRef ,
17
22
}
18
23
19
- impl < ' a > OctetStringRef < ' a > {
24
+ impl OctetStringRef {
20
25
/// Create a new ASN.1 `OCTET STRING` from a byte slice.
21
- pub fn new ( slice : & ' a [ u8 ] ) -> Result < Self , Error > {
26
+ pub fn new ( slice : & [ u8 ] ) -> Result < & Self , Error > {
22
27
BytesRef :: new ( slice)
23
- . map ( |inner| Self { inner } )
28
+ . map ( Self :: from_bytes_ref )
24
29
. map_err ( |_| ErrorKind :: Length { tag : Self :: TAG } . into ( ) )
25
30
}
26
31
32
+ /// Create an [`OctetStringRef`] from a [`BytesRef`].
33
+ ///
34
+ /// Implemented as an inherent method to keep [`BytesRef`] out of the public API.
35
+ fn from_bytes_ref ( bytes_ref : & BytesRef ) -> & Self {
36
+ // SAFETY: `Self` is a `repr(transparent)` newtype for `BytesRef`
37
+ #[ allow( unsafe_code) ]
38
+ unsafe {
39
+ & * ( bytes_ref. as_ptr ( ) as * const Self )
40
+ }
41
+ }
42
+
27
43
/// Borrow the inner byte slice.
28
- pub fn as_bytes ( & self ) -> & ' a [ u8 ] {
44
+ pub fn as_bytes ( & self ) -> & [ u8 ] {
29
45
self . inner . as_slice ( )
30
46
}
31
47
@@ -40,29 +56,28 @@ impl<'a> OctetStringRef<'a> {
40
56
}
41
57
42
58
/// Parse `T` from this `OCTET STRING`'s contents.
43
- pub fn decode_into < T : Decode < ' a > > ( & self ) -> Result < T , T :: Error > {
59
+ pub fn decode_into < ' a , T : Decode < ' a > > ( & ' a self ) -> Result < T , T :: Error > {
44
60
Decode :: from_der ( self . as_bytes ( ) )
45
61
}
46
62
}
47
63
48
- impl_any_conversions ! ( OctetStringRef <' a>, ' a) ;
64
+ // impl_any_conversions!(OctetStringRef<'a>, 'a);
49
65
50
- impl AsRef < [ u8 ] > for OctetStringRef < ' _ > {
66
+ impl AsRef < [ u8 ] > for OctetStringRef {
51
67
fn as_ref ( & self ) -> & [ u8 ] {
52
68
self . as_bytes ( )
53
69
}
54
70
}
55
71
56
- impl < ' a > DecodeValue < ' a > for OctetStringRef < ' a > {
72
+ impl < ' a > DecodeValue < ' a > for & ' a OctetStringRef {
57
73
type Error = Error ;
58
74
59
75
fn decode_value < R : Reader < ' a > > ( reader : & mut R , header : Header ) -> Result < Self , Error > {
60
- let inner = <& ' a BytesRef >:: decode_value ( reader, header) ?;
61
- Ok ( Self { inner } )
76
+ <& ' a BytesRef >:: decode_value ( reader, header) . map ( OctetStringRef :: from_bytes_ref)
62
77
}
63
78
}
64
79
65
- impl EncodeValue for OctetStringRef < ' _ > {
80
+ impl EncodeValue for & OctetStringRef {
66
81
fn value_len ( & self ) -> Result < Length , Error > {
67
82
self . inner . value_len ( )
68
83
}
@@ -72,59 +87,56 @@ impl EncodeValue for OctetStringRef<'_> {
72
87
}
73
88
}
74
89
75
- impl FixedTag for OctetStringRef < ' _ > {
90
+ impl FixedTag for OctetStringRef {
76
91
const TAG : Tag = Tag :: OctetString ;
77
92
}
78
-
79
- impl OrdIsValueOrd for OctetStringRef < ' _ > { }
80
-
81
- impl < ' a > From < & OctetStringRef < ' a > > for OctetStringRef < ' a > {
82
- fn from ( value : & OctetStringRef < ' a > ) -> OctetStringRef < ' a > {
83
- * value
84
- }
93
+ impl FixedTag for & OctetStringRef {
94
+ const TAG : Tag = Tag :: OctetString ;
85
95
}
86
96
87
- impl < ' a > From < OctetStringRef < ' a > > for AnyRef < ' a > {
88
- fn from ( octet_string : OctetStringRef < ' a > ) -> AnyRef < ' a > {
89
- AnyRef :: from_tag_and_value ( Tag :: OctetString , octet_string. inner )
97
+ impl OrdIsValueOrd for & OctetStringRef { }
98
+
99
+ impl < ' a > From < & ' a OctetStringRef > for AnyRef < ' a > {
100
+ fn from ( octet_string : & ' a OctetStringRef ) -> AnyRef < ' a > {
101
+ AnyRef :: from_tag_and_value ( Tag :: OctetString , & octet_string. inner )
90
102
}
91
103
}
92
104
93
- impl < ' a > From < OctetStringRef < ' a > > for & ' a [ u8 ] {
94
- fn from ( octet_string : OctetStringRef < ' a > ) -> & ' a [ u8 ] {
105
+ impl < ' a > From < & ' a OctetStringRef > for & ' a [ u8 ] {
106
+ fn from ( octet_string : & ' a OctetStringRef ) -> & ' a [ u8 ] {
95
107
octet_string. as_bytes ( )
96
108
}
97
109
}
98
110
99
- impl < ' a > TryFrom < & ' a [ u8 ] > for OctetStringRef < ' a > {
111
+ impl < ' a > TryFrom < & ' a [ u8 ] > for & ' a OctetStringRef {
100
112
type Error = Error ;
101
113
102
114
fn try_from ( byte_slice : & ' a [ u8 ] ) -> Result < Self , Error > {
103
115
OctetStringRef :: new ( byte_slice)
104
116
}
105
117
}
106
118
107
- /// Hack for simplifying the custom derive use case.
108
- impl < ' a > TryFrom < & & ' a [ u8 ] > for OctetStringRef < ' a > {
119
+ // TODO(tarcieri): hack to make derive tests pass. Get rid of this!
120
+ impl < ' a > TryFrom < & & ' a [ u8 ] > for & ' a OctetStringRef {
109
121
type Error = Error ;
110
122
111
123
fn try_from ( byte_slice : & & ' a [ u8 ] ) -> Result < Self , Error > {
112
124
OctetStringRef :: new ( byte_slice)
113
125
}
114
126
}
115
127
116
- impl < ' a , const N : usize > TryFrom < & ' a [ u8 ; N ] > for OctetStringRef < ' a > {
128
+ impl < ' a , const N : usize > TryFrom < & ' a [ u8 ; N ] > for & ' a OctetStringRef {
117
129
type Error = Error ;
118
130
119
131
fn try_from ( byte_slice : & ' a [ u8 ; N ] ) -> Result < Self , Error > {
120
132
OctetStringRef :: new ( byte_slice)
121
133
}
122
134
}
123
135
124
- impl < ' a , const N : usize > TryFrom < OctetStringRef < ' a > > for [ u8 ; N ] {
136
+ impl < ' a , const N : usize > TryFrom < & ' a OctetStringRef > for [ u8 ; N ] {
125
137
type Error = Error ;
126
138
127
- fn try_from ( octet_string : OctetStringRef < ' a > ) -> Result < Self , Self :: Error > {
139
+ fn try_from ( octet_string : & ' a OctetStringRef ) -> Result < Self , Self :: Error > {
128
140
octet_string
129
141
. as_bytes ( )
130
142
. try_into ( )
@@ -133,10 +145,10 @@ impl<'a, const N: usize> TryFrom<OctetStringRef<'a>> for [u8; N] {
133
145
}
134
146
135
147
#[ cfg( feature = "heapless" ) ]
136
- impl < ' a , const N : usize > TryFrom < OctetStringRef < ' a > > for heapless:: Vec < u8 , N > {
148
+ impl < const N : usize > TryFrom < & OctetStringRef > for heapless:: Vec < u8 , N > {
137
149
type Error = Error ;
138
150
139
- fn try_from ( octet_string : OctetStringRef < ' a > ) -> Result < Self , Self :: Error > {
151
+ fn try_from ( octet_string : & OctetStringRef ) -> Result < Self , Self :: Error > {
140
152
octet_string
141
153
. as_bytes ( )
142
154
. try_into ( )
@@ -145,7 +157,7 @@ impl<'a, const N: usize> TryFrom<OctetStringRef<'a>> for heapless::Vec<u8, N> {
145
157
}
146
158
147
159
#[ cfg( feature = "heapless" ) ]
148
- impl < ' a , const N : usize > TryFrom < & ' a heapless:: Vec < u8 , N > > for OctetStringRef < ' a > {
160
+ impl < ' a , const N : usize > TryFrom < & ' a heapless:: Vec < u8 , N > > for & ' a OctetStringRef {
149
161
type Error = Error ;
150
162
151
163
fn try_from ( byte_vec : & ' a heapless:: Vec < u8 , N > ) -> Result < Self , Error > {
@@ -159,8 +171,12 @@ pub use self::allocating::OctetString;
159
171
#[ cfg( feature = "alloc" ) ]
160
172
mod allocating {
161
173
use super :: * ;
162
- use crate :: { BytesOwned , referenced:: * } ;
163
- use alloc:: { borrow:: Cow , boxed:: Box , vec:: Vec } ;
174
+ use crate :: BytesOwned ;
175
+ use alloc:: {
176
+ borrow:: { Borrow , Cow , ToOwned } ,
177
+ boxed:: Box ,
178
+ vec:: Vec ,
179
+ } ;
164
180
165
181
/// ASN.1 `OCTET STRING` type: owned form.
166
182
///
@@ -214,6 +230,12 @@ mod allocating {
214
230
}
215
231
}
216
232
233
+ impl Borrow < OctetStringRef > for OctetString {
234
+ fn borrow ( & self ) -> & OctetStringRef {
235
+ OctetStringRef :: from_bytes_ref ( self . inner . as_ref ( ) )
236
+ }
237
+ }
238
+
217
239
impl < ' a > DecodeValue < ' a > for OctetString {
218
240
type Error = Error ;
219
241
@@ -237,40 +259,30 @@ mod allocating {
237
259
const TAG : Tag = Tag :: OctetString ;
238
260
}
239
261
240
- impl < ' a > From < & ' a OctetString > for OctetStringRef < ' a > {
241
- fn from ( octet_string : & ' a OctetString ) -> OctetStringRef < ' a > {
242
- OctetStringRef {
243
- inner : octet_string. inner . as_ref ( ) ,
244
- }
245
- }
246
- }
247
-
248
262
impl OrdIsValueOrd for OctetString { }
249
263
250
- impl < ' a > RefToOwned < ' a > for OctetStringRef < ' a > {
251
- type Owned = OctetString ;
252
- fn ref_to_owned ( & self ) -> Self :: Owned {
253
- OctetString {
254
- inner : self . inner . into ( ) ,
255
- }
264
+ impl < ' a > From < & ' a OctetString > for & ' a OctetStringRef {
265
+ fn from ( octet_string : & ' a OctetString ) -> & ' a OctetStringRef {
266
+ OctetStringRef :: from_bytes_ref ( octet_string. inner . as_ref ( ) )
256
267
}
257
268
}
258
269
259
- impl OwnedToRef for OctetString {
260
- type Borrowed < ' a > = OctetStringRef < ' a > ;
261
- fn owned_to_ref ( & self ) -> Self :: Borrowed < ' _ > {
262
- self . into ( )
270
+ impl From < & OctetStringRef > for OctetString {
271
+ fn from ( octet_string_ref : & OctetStringRef ) -> OctetString {
272
+ Self {
273
+ inner : octet_string_ref. inner . to_owned ( ) ,
274
+ }
263
275
}
264
276
}
265
277
266
- impl From < OctetStringRef < ' _ > > for Vec < u8 > {
267
- fn from ( octet_string : OctetStringRef < ' _ > ) -> Vec < u8 > {
278
+ impl From < & OctetStringRef > for Vec < u8 > {
279
+ fn from ( octet_string : & OctetStringRef ) -> Vec < u8 > {
268
280
Vec :: from ( octet_string. as_bytes ( ) )
269
281
}
270
282
}
271
283
272
284
/// Hack for simplifying the custom derive use case.
273
- impl < ' a > TryFrom < & ' a Vec < u8 > > for OctetStringRef < ' a > {
285
+ impl < ' a > TryFrom < & ' a Vec < u8 > > for & ' a OctetStringRef {
274
286
type Error = Error ;
275
287
276
288
fn try_from ( byte_vec : & ' a Vec < u8 > ) -> Result < Self , Error > {
@@ -284,18 +296,26 @@ mod allocating {
284
296
}
285
297
}
286
298
287
- impl < ' a > TryFrom < & ' a Cow < ' a , [ u8 ] > > for OctetStringRef < ' a > {
299
+ impl ToOwned for OctetStringRef {
300
+ type Owned = OctetString ;
301
+
302
+ fn to_owned ( & self ) -> OctetString {
303
+ self . into ( )
304
+ }
305
+ }
306
+
307
+ impl < ' a > TryFrom < & ' a Cow < ' a , [ u8 ] > > for & ' a OctetStringRef {
288
308
type Error = Error ;
289
309
290
310
fn try_from ( byte_slice : & ' a Cow < ' a , [ u8 ] > ) -> Result < Self , Error > {
291
311
OctetStringRef :: new ( byte_slice)
292
312
}
293
313
}
294
314
295
- impl < ' a > TryFrom < OctetStringRef < ' a > > for Cow < ' a , [ u8 ] > {
315
+ impl < ' a > TryFrom < & ' a OctetStringRef > for Cow < ' a , [ u8 ] > {
296
316
type Error = Error ;
297
317
298
- fn try_from ( octet_string : OctetStringRef < ' a > ) -> Result < Self , Self :: Error > {
318
+ fn try_from ( octet_string : & ' a OctetStringRef ) -> Result < Self , Self :: Error > {
299
319
Ok ( Cow :: Borrowed ( octet_string. as_bytes ( ) ) )
300
320
}
301
321
}
@@ -345,8 +365,8 @@ mod bytes {
345
365
const TAG : Tag = Tag :: OctetString ;
346
366
}
347
367
348
- impl From < OctetStringRef < ' _ > > for Bytes {
349
- fn from ( octet_string : OctetStringRef < ' _ > ) -> Bytes {
368
+ impl From < & OctetStringRef > for Bytes {
369
+ fn from ( octet_string : & OctetStringRef ) -> Bytes {
350
370
Vec :: from ( octet_string) . into ( )
351
371
}
352
372
}
@@ -361,7 +381,23 @@ mod bytes {
361
381
#[ cfg( test) ]
362
382
#[ allow( clippy:: unwrap_used) ]
363
383
mod tests {
364
- use crate :: asn1:: { OctetStringRef , PrintableStringRef } ;
384
+ use crate :: {
385
+ Decode ,
386
+ asn1:: { OctetStringRef , PrintableStringRef } ,
387
+ } ;
388
+ use hex_literal:: hex;
389
+
390
+ #[ test]
391
+ fn octet_string_decode ( ) {
392
+ // PrintableString "hi"
393
+ const EXAMPLE : & [ u8 ] = & hex ! (
394
+ "040c" // primitive definite length OCTET STRING
395
+ "48656c6c6f2c20776f726c64" // "Hello, world"
396
+ ) ;
397
+
398
+ let decoded = <& OctetStringRef >:: from_der ( EXAMPLE ) . unwrap ( ) ;
399
+ assert_eq ! ( decoded. as_bytes( ) , b"Hello, world" ) ;
400
+ }
365
401
366
402
#[ test]
367
403
fn octet_string_decode_into ( ) {
0 commit comments