@@ -10,22 +10,34 @@ use crate::{
10
10
/// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
11
11
///
12
12
/// 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 > {
13
+ #[ derive( Debug , Eq , Hash , PartialEq , PartialOrd , Ord ) ]
14
+ #[ repr( transparent) ]
15
+ pub struct OctetStringRef {
15
16
/// Inner value
16
- inner : & ' a BytesRef ,
17
+ inner : BytesRef ,
17
18
}
18
19
19
- impl < ' a > OctetStringRef < ' a > {
20
+ impl OctetStringRef {
20
21
/// Create a new ASN.1 `OCTET STRING` from a byte slice.
21
- pub fn new ( slice : & ' a [ u8 ] ) -> Result < Self , Error > {
22
+ pub fn new < ' a > ( slice : & ' a [ u8 ] ) -> Result < & ' a Self , Error > {
22
23
BytesRef :: new ( slice)
23
- . map ( |inner| Self { inner } )
24
+ . map ( Self :: from_bytes_ref )
24
25
. map_err ( |_| ErrorKind :: Length { tag : Self :: TAG } . into ( ) )
25
26
}
26
27
28
+ /// Create an [`OctetStringRef`] from a [`BytesRef`].
29
+ ///
30
+ /// Implemented as an inherent method to keep [`BytesRef`] out of the public API.
31
+ fn from_bytes_ref ( bytes_ref : & BytesRef ) -> & Self {
32
+ // SAFETY: `Self` is a `repr(transparent)` newtype for `BytesRef`
33
+ #[ allow( unsafe_code) ]
34
+ unsafe {
35
+ & * ( bytes_ref. as_ptr ( ) as * const Self )
36
+ }
37
+ }
38
+
27
39
/// Borrow the inner byte slice.
28
- pub fn as_bytes ( & self ) -> & ' a [ u8 ] {
40
+ pub fn as_bytes ( & self ) -> & [ u8 ] {
29
41
self . inner . as_slice ( )
30
42
}
31
43
@@ -40,29 +52,28 @@ impl<'a> OctetStringRef<'a> {
40
52
}
41
53
42
54
/// Parse `T` from this `OCTET STRING`'s contents.
43
- pub fn decode_into < T : Decode < ' a > > ( & self ) -> Result < T , T :: Error > {
55
+ pub fn decode_into < ' a , T : Decode < ' a > > ( & ' a self ) -> Result < T , T :: Error > {
44
56
Decode :: from_der ( self . as_bytes ( ) )
45
57
}
46
58
}
47
59
48
- impl_any_conversions ! ( OctetStringRef <' a>, ' a) ;
60
+ // impl_any_conversions!(OctetStringRef<'a>, 'a);
49
61
50
- impl AsRef < [ u8 ] > for OctetStringRef < ' _ > {
62
+ impl AsRef < [ u8 ] > for OctetStringRef {
51
63
fn as_ref ( & self ) -> & [ u8 ] {
52
64
self . as_bytes ( )
53
65
}
54
66
}
55
67
56
- impl < ' a > DecodeValue < ' a > for OctetStringRef < ' a > {
68
+ impl < ' a > DecodeValue < ' a > for & ' a OctetStringRef {
57
69
type Error = Error ;
58
70
59
71
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 } )
72
+ <& ' a BytesRef >:: decode_value ( reader, header) . map ( OctetStringRef :: from_bytes_ref)
62
73
}
63
74
}
64
75
65
- impl EncodeValue for OctetStringRef < ' _ > {
76
+ impl EncodeValue for OctetStringRef {
66
77
fn value_len ( & self ) -> Result < Length , Error > {
67
78
self . inner . value_len ( )
68
79
}
@@ -72,59 +83,47 @@ impl EncodeValue for OctetStringRef<'_> {
72
83
}
73
84
}
74
85
75
- impl FixedTag for OctetStringRef < ' _ > {
86
+ impl FixedTag for OctetStringRef {
76
87
const TAG : Tag = Tag :: OctetString ;
77
88
}
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
- }
89
+ impl FixedTag for & OctetStringRef {
90
+ const TAG : Tag = Tag :: OctetString ;
85
91
}
86
92
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 )
93
+ impl OrdIsValueOrd for OctetStringRef { }
94
+
95
+ impl < ' a > From < & ' a OctetStringRef > for AnyRef < ' a > {
96
+ fn from ( octet_string : & ' a OctetStringRef ) -> AnyRef < ' a > {
97
+ AnyRef :: from_tag_and_value ( Tag :: OctetString , & octet_string. inner )
90
98
}
91
99
}
92
100
93
- impl < ' a > From < OctetStringRef < ' a > > for & ' a [ u8 ] {
94
- fn from ( octet_string : OctetStringRef < ' a > ) -> & ' a [ u8 ] {
101
+ impl < ' a > From < & ' a OctetStringRef > for & ' a [ u8 ] {
102
+ fn from ( octet_string : & ' a OctetStringRef ) -> & ' a [ u8 ] {
95
103
octet_string. as_bytes ( )
96
104
}
97
105
}
98
106
99
- impl < ' a > TryFrom < & ' a [ u8 ] > for OctetStringRef < ' a > {
107
+ impl < ' a > TryFrom < & ' a [ u8 ] > for & ' a OctetStringRef {
100
108
type Error = Error ;
101
109
102
110
fn try_from ( byte_slice : & ' a [ u8 ] ) -> Result < Self , Error > {
103
111
OctetStringRef :: new ( byte_slice)
104
112
}
105
113
}
106
114
107
- /// Hack for simplifying the custom derive use case.
108
- impl < ' a > TryFrom < & & ' a [ u8 ] > for OctetStringRef < ' a > {
109
- type Error = Error ;
110
-
111
- fn try_from ( byte_slice : & & ' a [ u8 ] ) -> Result < Self , Error > {
112
- OctetStringRef :: new ( byte_slice)
113
- }
114
- }
115
-
116
- impl < ' a , const N : usize > TryFrom < & ' a [ u8 ; N ] > for OctetStringRef < ' a > {
115
+ impl < ' a , const N : usize > TryFrom < & ' a [ u8 ; N ] > for & ' a OctetStringRef {
117
116
type Error = Error ;
118
117
119
118
fn try_from ( byte_slice : & ' a [ u8 ; N ] ) -> Result < Self , Error > {
120
119
OctetStringRef :: new ( byte_slice)
121
120
}
122
121
}
123
122
124
- impl < ' a , const N : usize > TryFrom < OctetStringRef < ' a > > for [ u8 ; N ] {
123
+ impl < ' a , const N : usize > TryFrom < & ' a OctetStringRef > for [ u8 ; N ] {
125
124
type Error = Error ;
126
125
127
- fn try_from ( octet_string : OctetStringRef < ' a > ) -> Result < Self , Self :: Error > {
126
+ fn try_from ( octet_string : & ' a OctetStringRef ) -> Result < Self , Self :: Error > {
128
127
octet_string
129
128
. as_bytes ( )
130
129
. try_into ( )
@@ -133,10 +132,10 @@ impl<'a, const N: usize> TryFrom<OctetStringRef<'a>> for [u8; N] {
133
132
}
134
133
135
134
#[ cfg( feature = "heapless" ) ]
136
- impl < ' a , const N : usize > TryFrom < OctetStringRef < ' a > > for heapless:: Vec < u8 , N > {
135
+ impl < const N : usize > TryFrom < & OctetStringRef > for heapless:: Vec < u8 , N > {
137
136
type Error = Error ;
138
137
139
- fn try_from ( octet_string : OctetStringRef < ' a > ) -> Result < Self , Self :: Error > {
138
+ fn try_from ( octet_string : & OctetStringRef ) -> Result < Self , Self :: Error > {
140
139
octet_string
141
140
. as_bytes ( )
142
141
. try_into ( )
@@ -145,7 +144,7 @@ impl<'a, const N: usize> TryFrom<OctetStringRef<'a>> for heapless::Vec<u8, N> {
145
144
}
146
145
147
146
#[ cfg( feature = "heapless" ) ]
148
- impl < ' a , const N : usize > TryFrom < & ' a heapless:: Vec < u8 , N > > for OctetStringRef < ' a > {
147
+ impl < ' a , const N : usize > TryFrom < & ' a heapless:: Vec < u8 , N > > for & ' a OctetStringRef {
149
148
type Error = Error ;
150
149
151
150
fn try_from ( byte_vec : & ' a heapless:: Vec < u8 , N > ) -> Result < Self , Error > {
@@ -159,8 +158,13 @@ pub use self::allocating::OctetString;
159
158
#[ cfg( feature = "alloc" ) ]
160
159
mod allocating {
161
160
use super :: * ;
162
- use crate :: { BytesOwned , referenced:: * } ;
163
- use alloc:: { borrow:: Cow , boxed:: Box , vec:: Vec } ;
161
+ use crate :: BytesOwned ;
162
+ use alloc:: {
163
+ borrow:: { Borrow , Cow } ,
164
+ boxed:: Box ,
165
+ vec:: Vec ,
166
+ } ;
167
+ use std:: prelude:: rust_2015:: ToOwned ;
164
168
165
169
/// ASN.1 `OCTET STRING` type: owned form.
166
170
///
@@ -214,6 +218,12 @@ mod allocating {
214
218
}
215
219
}
216
220
221
+ impl Borrow < OctetStringRef > for OctetString {
222
+ fn borrow ( & self ) -> & OctetStringRef {
223
+ OctetStringRef :: from_bytes_ref ( self . inner . as_ref ( ) )
224
+ }
225
+ }
226
+
217
227
impl < ' a > DecodeValue < ' a > for OctetString {
218
228
type Error = Error ;
219
229
@@ -237,40 +247,30 @@ mod allocating {
237
247
const TAG : Tag = Tag :: OctetString ;
238
248
}
239
249
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
250
impl OrdIsValueOrd for OctetString { }
249
251
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
- }
252
+ impl < ' a > From < & ' a OctetString > for & ' a OctetStringRef {
253
+ fn from ( octet_string : & ' a OctetString ) -> & ' a OctetStringRef {
254
+ OctetStringRef :: from_bytes_ref ( octet_string. inner . as_ref ( ) )
256
255
}
257
256
}
258
257
259
- impl OwnedToRef for OctetString {
260
- type Borrowed < ' a > = OctetStringRef < ' a > ;
261
- fn owned_to_ref ( & self ) -> Self :: Borrowed < ' _ > {
262
- self . into ( )
258
+ impl From < & OctetStringRef > for OctetString {
259
+ fn from ( octet_string_ref : & OctetStringRef ) -> OctetString {
260
+ Self {
261
+ inner : octet_string_ref. inner . to_owned ( ) ,
262
+ }
263
263
}
264
264
}
265
265
266
- impl From < OctetStringRef < ' _ > > for Vec < u8 > {
267
- fn from ( octet_string : OctetStringRef < ' _ > ) -> Vec < u8 > {
266
+ impl From < & OctetStringRef > for Vec < u8 > {
267
+ fn from ( octet_string : & OctetStringRef ) -> Vec < u8 > {
268
268
Vec :: from ( octet_string. as_bytes ( ) )
269
269
}
270
270
}
271
271
272
272
/// Hack for simplifying the custom derive use case.
273
- impl < ' a > TryFrom < & ' a Vec < u8 > > for OctetStringRef < ' a > {
273
+ impl < ' a > TryFrom < & ' a Vec < u8 > > for & ' a OctetStringRef {
274
274
type Error = Error ;
275
275
276
276
fn try_from ( byte_vec : & ' a Vec < u8 > ) -> Result < Self , Error > {
@@ -284,18 +284,26 @@ mod allocating {
284
284
}
285
285
}
286
286
287
- impl < ' a > TryFrom < & ' a Cow < ' a , [ u8 ] > > for OctetStringRef < ' a > {
287
+ impl ToOwned for OctetStringRef {
288
+ type Owned = OctetString ;
289
+
290
+ fn to_owned ( & self ) -> OctetString {
291
+ self . into ( )
292
+ }
293
+ }
294
+
295
+ impl < ' a > TryFrom < & ' a Cow < ' a , [ u8 ] > > for & ' a OctetStringRef {
288
296
type Error = Error ;
289
297
290
298
fn try_from ( byte_slice : & ' a Cow < ' a , [ u8 ] > ) -> Result < Self , Error > {
291
299
OctetStringRef :: new ( byte_slice)
292
300
}
293
301
}
294
302
295
- impl < ' a > TryFrom < OctetStringRef < ' a > > for Cow < ' a , [ u8 ] > {
303
+ impl < ' a > TryFrom < & ' a OctetStringRef > for Cow < ' a , [ u8 ] > {
296
304
type Error = Error ;
297
305
298
- fn try_from ( octet_string : OctetStringRef < ' a > ) -> Result < Self , Self :: Error > {
306
+ fn try_from ( octet_string : & ' a OctetStringRef ) -> Result < Self , Self :: Error > {
299
307
Ok ( Cow :: Borrowed ( octet_string. as_bytes ( ) ) )
300
308
}
301
309
}
@@ -345,8 +353,8 @@ mod bytes {
345
353
const TAG : Tag = Tag :: OctetString ;
346
354
}
347
355
348
- impl From < OctetStringRef < ' _ > > for Bytes {
349
- fn from ( octet_string : OctetStringRef < ' _ > ) -> Bytes {
356
+ impl From < & OctetStringRef > for Bytes {
357
+ fn from ( octet_string : & OctetStringRef ) -> Bytes {
350
358
Vec :: from ( octet_string) . into ( )
351
359
}
352
360
}
@@ -361,7 +369,23 @@ mod bytes {
361
369
#[ cfg( test) ]
362
370
#[ allow( clippy:: unwrap_used) ]
363
371
mod tests {
364
- use crate :: asn1:: { OctetStringRef , PrintableStringRef } ;
372
+ use crate :: {
373
+ Decode ,
374
+ asn1:: { OctetStringRef , PrintableStringRef } ,
375
+ } ;
376
+ use hex_literal:: hex;
377
+
378
+ #[ test]
379
+ fn octet_string_decode ( ) {
380
+ // PrintableString "hi"
381
+ const EXAMPLE : & [ u8 ] = & hex ! (
382
+ "040c" // primitive definite length OCTET STRING
383
+ "48656c6c6f2c20776f726c64" // "Hello, world"
384
+ ) ;
385
+
386
+ let decoded = <& OctetStringRef >:: from_der ( EXAMPLE ) . unwrap ( ) ;
387
+ assert_eq ! ( decoded. as_bytes( ) , b"Hello, world" ) ;
388
+ }
365
389
366
390
#[ test]
367
391
fn octet_string_decode_into ( ) {
0 commit comments