Skip to content

Commit 8cee1e0

Browse files
committed
[WIP] der: remove lifetime from OctetStringRef
Following the pattern of #1921, removes the lifetime from the struct, instead changing `OctetStringRef` to a proper reference type to be used as `&OctetStringRef`. This makes it possible to `impl Borrow<OctetStringRef> for OctetString` and `impl ToOwned for OctetStringRef`, so they can work with `Cow`.
1 parent 8c60e19 commit 8cee1e0

File tree

2 files changed

+81
-71
lines changed

2 files changed

+81
-71
lines changed

der/src/asn1/octet_string.rs

Lines changed: 76 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,34 @@ use crate::{
1010
/// Octet strings represent contiguous sequences of octets, a.k.a. bytes.
1111
///
1212
/// 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 {
1516
/// Inner value
16-
inner: &'a BytesRef,
17+
inner: BytesRef,
1718
}
1819

19-
impl<'a> OctetStringRef<'a> {
20+
impl OctetStringRef {
2021
/// 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> {
2223
BytesRef::new(slice)
23-
.map(|inner| Self { inner })
24+
.map(Self::from_bytes_ref)
2425
.map_err(|_| ErrorKind::Length { tag: Self::TAG }.into())
2526
}
2627

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+
2739
/// Borrow the inner byte slice.
28-
pub fn as_bytes(&self) -> &'a [u8] {
40+
pub fn as_bytes(&self) -> &[u8] {
2941
self.inner.as_slice()
3042
}
3143

@@ -40,29 +52,28 @@ impl<'a> OctetStringRef<'a> {
4052
}
4153

4254
/// 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> {
4456
Decode::from_der(self.as_bytes())
4557
}
4658
}
4759

48-
impl_any_conversions!(OctetStringRef<'a>, 'a);
60+
//impl_any_conversions!(OctetStringRef<'a>, 'a);
4961

50-
impl AsRef<[u8]> for OctetStringRef<'_> {
62+
impl AsRef<[u8]> for OctetStringRef {
5163
fn as_ref(&self) -> &[u8] {
5264
self.as_bytes()
5365
}
5466
}
5567

56-
impl<'a> DecodeValue<'a> for OctetStringRef<'a> {
68+
impl<'a> DecodeValue<'a> for &'a OctetStringRef {
5769
type Error = Error;
5870

5971
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)
6273
}
6374
}
6475

65-
impl EncodeValue for OctetStringRef<'_> {
76+
impl EncodeValue for OctetStringRef {
6677
fn value_len(&self) -> Result<Length, Error> {
6778
self.inner.value_len()
6879
}
@@ -72,59 +83,44 @@ impl EncodeValue for OctetStringRef<'_> {
7283
}
7384
}
7485

75-
impl FixedTag for OctetStringRef<'_> {
86+
impl FixedTag for OctetStringRef {
7687
const TAG: Tag = Tag::OctetString;
7788
}
7889

79-
impl OrdIsValueOrd for OctetStringRef<'_> {}
90+
impl OrdIsValueOrd for OctetStringRef {}
8091

81-
impl<'a> From<&OctetStringRef<'a>> for OctetStringRef<'a> {
82-
fn from(value: &OctetStringRef<'a>) -> OctetStringRef<'a> {
83-
*value
92+
impl<'a> From<&'a OctetStringRef> for AnyRef<'a> {
93+
fn from(octet_string: &'a OctetStringRef) -> AnyRef<'a> {
94+
AnyRef::from_tag_and_value(Tag::OctetString, &octet_string.inner)
8495
}
8596
}
8697

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)
90-
}
91-
}
92-
93-
impl<'a> From<OctetStringRef<'a>> for &'a [u8] {
94-
fn from(octet_string: OctetStringRef<'a>) -> &'a [u8] {
98+
impl<'a> From<&'a OctetStringRef> for &'a [u8] {
99+
fn from(octet_string: &'a OctetStringRef) -> &'a [u8] {
95100
octet_string.as_bytes()
96101
}
97102
}
98103

99-
impl<'a> TryFrom<&'a [u8]> for OctetStringRef<'a> {
104+
impl<'a> TryFrom<&'a [u8]> for &'a OctetStringRef {
100105
type Error = Error;
101106

102107
fn try_from(byte_slice: &'a [u8]) -> Result<Self, Error> {
103108
OctetStringRef::new(byte_slice)
104109
}
105110
}
106111

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> {
112+
impl<'a, const N: usize> TryFrom<&'a [u8; N]> for &'a OctetStringRef {
117113
type Error = Error;
118114

119115
fn try_from(byte_slice: &'a [u8; N]) -> Result<Self, Error> {
120116
OctetStringRef::new(byte_slice)
121117
}
122118
}
123119

124-
impl<'a, const N: usize> TryFrom<OctetStringRef<'a>> for [u8; N] {
120+
impl<'a, const N: usize> TryFrom<&'a OctetStringRef> for [u8; N] {
125121
type Error = Error;
126122

127-
fn try_from(octet_string: OctetStringRef<'a>) -> Result<Self, Self::Error> {
123+
fn try_from(octet_string: &'a OctetStringRef) -> Result<Self, Self::Error> {
128124
octet_string
129125
.as_bytes()
130126
.try_into()
@@ -133,10 +129,10 @@ impl<'a, const N: usize> TryFrom<OctetStringRef<'a>> for [u8; N] {
133129
}
134130

135131
#[cfg(feature = "heapless")]
136-
impl<'a, const N: usize> TryFrom<OctetStringRef<'a>> for heapless::Vec<u8, N> {
132+
impl<const N: usize> TryFrom<&OctetStringRef> for heapless::Vec<u8, N> {
137133
type Error = Error;
138134

139-
fn try_from(octet_string: OctetStringRef<'a>) -> Result<Self, Self::Error> {
135+
fn try_from(octet_string: &OctetStringRef) -> Result<Self, Self::Error> {
140136
octet_string
141137
.as_bytes()
142138
.try_into()
@@ -145,7 +141,7 @@ impl<'a, const N: usize> TryFrom<OctetStringRef<'a>> for heapless::Vec<u8, N> {
145141
}
146142

147143
#[cfg(feature = "heapless")]
148-
impl<'a, const N: usize> TryFrom<&'a heapless::Vec<u8, N>> for OctetStringRef<'a> {
144+
impl<'a, const N: usize> TryFrom<&'a heapless::Vec<u8, N>> for &'a OctetStringRef {
149145
type Error = Error;
150146

151147
fn try_from(byte_vec: &'a heapless::Vec<u8, N>) -> Result<Self, Error> {
@@ -159,8 +155,13 @@ pub use self::allocating::OctetString;
159155
#[cfg(feature = "alloc")]
160156
mod allocating {
161157
use super::*;
162-
use crate::{BytesOwned, referenced::*};
163-
use alloc::{borrow::Cow, boxed::Box, vec::Vec};
158+
use crate::BytesOwned;
159+
use alloc::{
160+
borrow::{Borrow, Cow},
161+
boxed::Box,
162+
vec::Vec,
163+
};
164+
use std::prelude::rust_2015::ToOwned;
164165

165166
/// ASN.1 `OCTET STRING` type: owned form.
166167
///
@@ -214,6 +215,12 @@ mod allocating {
214215
}
215216
}
216217

218+
impl Borrow<OctetStringRef> for OctetString {
219+
fn borrow(&self) -> &OctetStringRef {
220+
OctetStringRef::from_bytes_ref(self.inner.as_ref())
221+
}
222+
}
223+
217224
impl<'a> DecodeValue<'a> for OctetString {
218225
type Error = Error;
219226

@@ -237,40 +244,30 @@ mod allocating {
237244
const TAG: Tag = Tag::OctetString;
238245
}
239246

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-
248247
impl OrdIsValueOrd for OctetString {}
249248

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-
}
249+
impl<'a> From<&'a OctetString> for &'a OctetStringRef {
250+
fn from(octet_string: &'a OctetString) -> &'a OctetStringRef {
251+
OctetStringRef::from_bytes_ref(octet_string.inner.as_ref())
256252
}
257253
}
258254

259-
impl OwnedToRef for OctetString {
260-
type Borrowed<'a> = OctetStringRef<'a>;
261-
fn owned_to_ref(&self) -> Self::Borrowed<'_> {
262-
self.into()
255+
impl From<&OctetStringRef> for OctetString {
256+
fn from(octet_string_ref: &OctetStringRef) -> OctetString {
257+
Self {
258+
inner: octet_string_ref.inner.to_owned(),
259+
}
263260
}
264261
}
265262

266-
impl From<OctetStringRef<'_>> for Vec<u8> {
267-
fn from(octet_string: OctetStringRef<'_>) -> Vec<u8> {
263+
impl From<&OctetStringRef> for Vec<u8> {
264+
fn from(octet_string: &OctetStringRef) -> Vec<u8> {
268265
Vec::from(octet_string.as_bytes())
269266
}
270267
}
271268

272269
/// Hack for simplifying the custom derive use case.
273-
impl<'a> TryFrom<&'a Vec<u8>> for OctetStringRef<'a> {
270+
impl<'a> TryFrom<&'a Vec<u8>> for &'a OctetStringRef {
274271
type Error = Error;
275272

276273
fn try_from(byte_vec: &'a Vec<u8>) -> Result<Self, Error> {
@@ -284,18 +281,26 @@ mod allocating {
284281
}
285282
}
286283

287-
impl<'a> TryFrom<&'a Cow<'a, [u8]>> for OctetStringRef<'a> {
284+
impl ToOwned for OctetStringRef {
285+
type Owned = OctetString;
286+
287+
fn to_owned(&self) -> OctetString {
288+
self.into()
289+
}
290+
}
291+
292+
impl<'a> TryFrom<&'a Cow<'a, [u8]>> for &'a OctetStringRef {
288293
type Error = Error;
289294

290295
fn try_from(byte_slice: &'a Cow<'a, [u8]>) -> Result<Self, Error> {
291296
OctetStringRef::new(byte_slice)
292297
}
293298
}
294299

295-
impl<'a> TryFrom<OctetStringRef<'a>> for Cow<'a, [u8]> {
300+
impl<'a> TryFrom<&'a OctetStringRef> for Cow<'a, [u8]> {
296301
type Error = Error;
297302

298-
fn try_from(octet_string: OctetStringRef<'a>) -> Result<Self, Self::Error> {
303+
fn try_from(octet_string: &'a OctetStringRef) -> Result<Self, Self::Error> {
299304
Ok(Cow::Borrowed(octet_string.as_bytes()))
300305
}
301306
}
@@ -345,8 +350,8 @@ mod bytes {
345350
const TAG: Tag = Tag::OctetString;
346351
}
347352

348-
impl From<OctetStringRef<'_>> for Bytes {
349-
fn from(octet_string: OctetStringRef<'_>) -> Bytes {
353+
impl From<&OctetStringRef> for Bytes {
354+
fn from(octet_string: &OctetStringRef) -> Bytes {
350355
Vec::from(octet_string).into()
351356
}
352357
}

der/src/bytes.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ impl BytesRef {
3131
}
3232
}
3333

34+
/// Get a pointer to this [`BytesRef`].
35+
pub(crate) const fn as_ptr(&self) -> *const BytesRef {
36+
self as *const BytesRef
37+
}
38+
3439
/// Borrow the inner byte slice
3540
pub const fn as_slice(&self) -> &[u8] {
3641
&self.0

0 commit comments

Comments
 (0)