@@ -5,27 +5,43 @@ use crate::{
55 Tag , Writer , asn1:: AnyRef , ord:: OrdIsValueOrd ,
66} ;
77
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+
812/// ASN.1 `OCTET STRING` type: borrowed form.
913///
1014/// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
1115///
1216/// 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 {
1520 /// Inner value
16- inner : & ' a BytesRef ,
21+ inner : BytesRef ,
1722}
1823
19- impl < ' a > OctetStringRef < ' a > {
24+ impl OctetStringRef {
2025 /// 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 > {
2227 BytesRef :: new ( slice)
23- . map ( |inner| Self { inner } )
28+ . map ( Self :: from_bytes_ref )
2429 . map_err ( |_| ErrorKind :: Length { tag : Self :: TAG } . into ( ) )
2530 }
2631
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+
2743 /// Borrow the inner byte slice.
28- pub fn as_bytes ( & self ) -> & ' a [ u8 ] {
44+ pub fn as_bytes ( & self ) -> & [ u8 ] {
2945 self . inner . as_slice ( )
3046 }
3147
@@ -40,29 +56,28 @@ impl<'a> OctetStringRef<'a> {
4056 }
4157
4258 /// 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 > {
4460 Decode :: from_der ( self . as_bytes ( ) )
4561 }
4662}
4763
48- impl_any_conversions ! ( OctetStringRef < ' a> , ' a) ;
64+ impl_any_conversions ! ( & ' a OctetStringRef , ' a) ;
4965
50- impl AsRef < [ u8 ] > for OctetStringRef < ' _ > {
66+ impl AsRef < [ u8 ] > for OctetStringRef {
5167 fn as_ref ( & self ) -> & [ u8 ] {
5268 self . as_bytes ( )
5369 }
5470}
5571
56- impl < ' a > DecodeValue < ' a > for OctetStringRef < ' a > {
72+ impl < ' a > DecodeValue < ' a > for & ' a OctetStringRef {
5773 type Error = Error ;
5874
5975 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)
6277 }
6378}
6479
65- impl EncodeValue for OctetStringRef < ' _ > {
80+ impl EncodeValue for & OctetStringRef {
6681 fn value_len ( & self ) -> Result < Length , Error > {
6782 self . inner . value_len ( )
6883 }
@@ -72,31 +87,28 @@ impl EncodeValue for OctetStringRef<'_> {
7287 }
7388}
7489
75- impl FixedTag for OctetStringRef < ' _ > {
90+ impl FixedTag for OctetStringRef {
7691 const TAG : Tag = Tag :: OctetString ;
7792}
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 ;
8595}
8696
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 )
90102 }
91103}
92104
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 ] {
95107 octet_string. as_bytes ( )
96108 }
97109}
98110
99- impl < ' a > TryFrom < & ' a [ u8 ] > for OctetStringRef < ' a > {
111+ impl < ' a > TryFrom < & ' a [ u8 ] > for & ' a OctetStringRef {
100112 type Error = Error ;
101113
102114 fn try_from ( byte_slice : & ' a [ u8 ] ) -> Result < Self , Error > {
@@ -105,26 +117,26 @@ impl<'a> TryFrom<&'a [u8]> for OctetStringRef<'a> {
105117}
106118
107119/// Hack for simplifying the custom derive use case.
108- impl < ' a > TryFrom < & & ' a [ u8 ] > for OctetStringRef < ' a > {
120+ impl < ' a > TryFrom < & & ' a [ u8 ] > for & ' a OctetStringRef {
109121 type Error = Error ;
110122
111123 fn try_from ( byte_slice : & & ' a [ u8 ] ) -> Result < Self , Error > {
112124 OctetStringRef :: new ( byte_slice)
113125 }
114126}
115127
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 {
117129 type Error = Error ;
118130
119131 fn try_from ( byte_slice : & ' a [ u8 ; N ] ) -> Result < Self , Error > {
120132 OctetStringRef :: new ( byte_slice)
121133 }
122134}
123135
124- impl < ' a , const N : usize > TryFrom < OctetStringRef < ' a > > for [ u8 ; N ] {
136+ impl < ' a , const N : usize > TryFrom < & ' a OctetStringRef > for [ u8 ; N ] {
125137 type Error = Error ;
126138
127- fn try_from ( octet_string : OctetStringRef < ' a > ) -> Result < Self , Self :: Error > {
139+ fn try_from ( octet_string : & ' a OctetStringRef ) -> Result < Self , Self :: Error > {
128140 octet_string
129141 . as_bytes ( )
130142 . try_into ( )
@@ -133,10 +145,10 @@ impl<'a, const N: usize> TryFrom<OctetStringRef<'a>> for [u8; N] {
133145}
134146
135147#[ 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 > {
137149 type Error = Error ;
138150
139- fn try_from ( octet_string : OctetStringRef < ' a > ) -> Result < Self , Self :: Error > {
151+ fn try_from ( octet_string : & OctetStringRef ) -> Result < Self , Self :: Error > {
140152 octet_string
141153 . as_bytes ( )
142154 . try_into ( )
@@ -145,7 +157,7 @@ impl<'a, const N: usize> TryFrom<OctetStringRef<'a>> for heapless::Vec<u8, N> {
145157}
146158
147159#[ 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 {
149161 type Error = Error ;
150162
151163 fn try_from ( byte_vec : & ' a heapless:: Vec < u8 , N > ) -> Result < Self , Error > {
@@ -159,8 +171,12 @@ pub use self::allocating::OctetString;
159171#[ cfg( feature = "alloc" ) ]
160172mod allocating {
161173 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+ } ;
164180
165181 /// ASN.1 `OCTET STRING` type: owned form.
166182 ///
@@ -214,6 +230,12 @@ mod allocating {
214230 }
215231 }
216232
233+ impl Borrow < OctetStringRef > for OctetString {
234+ fn borrow ( & self ) -> & OctetStringRef {
235+ OctetStringRef :: from_bytes_ref ( self . inner . as_ref ( ) )
236+ }
237+ }
238+
217239 impl < ' a > DecodeValue < ' a > for OctetString {
218240 type Error = Error ;
219241
@@ -237,40 +259,30 @@ mod allocating {
237259 const TAG : Tag = Tag :: OctetString ;
238260 }
239261
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-
248262 impl OrdIsValueOrd for OctetString { }
249263
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 ( ) )
256267 }
257268 }
258269
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+ }
263275 }
264276 }
265277
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 > {
268280 Vec :: from ( octet_string. as_bytes ( ) )
269281 }
270282 }
271283
272284 /// 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 {
274286 type Error = Error ;
275287
276288 fn try_from ( byte_vec : & ' a Vec < u8 > ) -> Result < Self , Error > {
@@ -284,18 +296,26 @@ mod allocating {
284296 }
285297 }
286298
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 {
288308 type Error = Error ;
289309
290310 fn try_from ( byte_slice : & ' a Cow < ' a , [ u8 ] > ) -> Result < Self , Error > {
291311 OctetStringRef :: new ( byte_slice)
292312 }
293313 }
294314
295- impl < ' a > TryFrom < OctetStringRef < ' a > > for Cow < ' a , [ u8 ] > {
315+ impl < ' a > TryFrom < & ' a OctetStringRef > for Cow < ' a , [ u8 ] > {
296316 type Error = Error ;
297317
298- fn try_from ( octet_string : OctetStringRef < ' a > ) -> Result < Self , Self :: Error > {
318+ fn try_from ( octet_string : & ' a OctetStringRef ) -> Result < Self , Self :: Error > {
299319 Ok ( Cow :: Borrowed ( octet_string. as_bytes ( ) ) )
300320 }
301321 }
@@ -345,8 +365,8 @@ mod bytes {
345365 const TAG : Tag = Tag :: OctetString ;
346366 }
347367
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 {
350370 Vec :: from ( octet_string) . into ( )
351371 }
352372 }
@@ -361,7 +381,23 @@ mod bytes {
361381#[ cfg( test) ]
362382#[ allow( clippy:: unwrap_used) ]
363383mod 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+ }
365401
366402 #[ test]
367403 fn octet_string_decode_into ( ) {
0 commit comments