Skip to content

Commit 45b2029

Browse files
authored
der: add const ::new to Length, BytesRef, AnyRef (#1713)
* feat: add const ::new to Length, BytesRef, AnyRef docs: Length::new_usize * fix clippy u32 truncation
1 parent 26ff0b8 commit 45b2029

File tree

4 files changed

+35
-16
lines changed

4 files changed

+35
-16
lines changed

der/src/asn1/any.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ impl<'a> AnyRef<'a> {
4040
};
4141

4242
/// Create a new [`AnyRef`] from the provided [`Tag`] and DER bytes.
43-
pub fn new(tag: Tag, bytes: &'a [u8]) -> Result<Self, Error> {
44-
let value = BytesRef::new(bytes).map_err(|_| ErrorKind::Length { tag })?;
45-
Ok(Self { tag, value })
43+
pub const fn new(tag: Tag, bytes: &'a [u8]) -> Result<Self, Error> {
44+
match BytesRef::new(bytes) {
45+
Ok(value) => Ok(Self { tag, value }),
46+
Err(_) => Err(Error::from_kind(ErrorKind::Length { tag })),
47+
}
4648
}
4749

4850
/// Infallible creation of an [`AnyRef`] from a [`BytesRef`].

der/src/bytes_ref.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,14 @@ impl<'a> BytesRef<'a> {
2828

2929
/// Create a new [`BytesRef`], ensuring that the provided `slice` value
3030
/// is shorter than `Length::max()`.
31-
pub fn new(slice: &'a [u8]) -> Result<Self> {
32-
Ok(Self {
33-
length: Length::try_from(slice.len())?,
34-
inner: slice,
35-
})
31+
pub const fn new(slice: &'a [u8]) -> Result<Self> {
32+
match Length::new_usize(slice.len()) {
33+
Ok(length) => Ok(Self {
34+
length,
35+
inner: slice,
36+
}),
37+
Err(err) => Err(err),
38+
}
3639
}
3740

3841
/// Borrow the inner byte slice

der/src/error.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,19 @@ pub struct Error {
2626

2727
impl Error {
2828
/// Create a new [`Error`].
29-
pub fn new(kind: ErrorKind, position: Length) -> Error {
29+
pub const fn new(kind: ErrorKind, position: Length) -> Error {
3030
Error {
3131
kind,
3232
position: Some(position),
3333
}
3434
}
35+
/// Create a new [`Error`], without known position.
36+
pub(crate) const fn from_kind(kind: ErrorKind) -> Error {
37+
Error {
38+
kind,
39+
position: None,
40+
}
41+
}
3542

3643
/// Create a new [`ErrorKind::Incomplete`] for the given length.
3744
///
@@ -86,10 +93,7 @@ impl fmt::Display for Error {
8693

8794
impl From<ErrorKind> for Error {
8895
fn from(kind: ErrorKind) -> Error {
89-
Error {
90-
kind,
91-
position: None,
92-
}
96+
Error::from_kind(kind)
9397
}
9498
}
9599

der/src/length.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ impl Length {
4444
Self(value as u32)
4545
}
4646

47+
/// Create a new [`Length`] for any value which fits inside the length type.
48+
///
49+
/// This function is const-safe and therefore useful for [`Length`] constants.
50+
#[allow(clippy::cast_possible_truncation)]
51+
pub(crate) const fn new_usize(len: usize) -> Result<Self> {
52+
if len > (u32::MAX as usize) {
53+
Err(Error::from_kind(ErrorKind::Overflow))
54+
} else {
55+
Ok(Length(len as u32))
56+
}
57+
}
58+
4759
/// Is this length equal to zero?
4860
pub fn is_zero(self) -> bool {
4961
self == Self::ZERO
@@ -192,9 +204,7 @@ impl TryFrom<usize> for Length {
192204
type Error = Error;
193205

194206
fn try_from(len: usize) -> Result<Length> {
195-
u32::try_from(len)
196-
.map_err(|_| ErrorKind::Overflow)?
197-
.try_into()
207+
Length::new_usize(len)
198208
}
199209
}
200210

0 commit comments

Comments
 (0)