Skip to content

Commit c748179

Browse files
committed
Extract slice to array conversion function to module.
1 parent 3bf45ae commit c748179

File tree

2 files changed

+37
-23
lines changed

2 files changed

+37
-23
lines changed

src/string.rs

+4-23
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,9 @@ use core::ops::Deref;
33

44

55

6-
/// Our own `core::array::TryFromSliceError`
7-
///
8-
/// Used in [`array_ref_try_from_slice`].
9-
// We need a local copy of this type, because we need to instantiate it, but it
10-
// has a private field.
11-
struct TryFromSliceError(());
6+
mod from_slice;
7+
128

13-
/// Const version of `<&[T; N]>::try_from(&[T])`
14-
///
15-
/// Original Source:
16-
/// https://github.com/rust-lang/rust/blob/eb82facb1626166188d49599a3313fc95201f556/library/core/src/array/mod.rs#L203-L215
17-
const fn array_ref_try_from_slice<'a, T, const N: usize>(
18-
slice: &[T],
19-
) -> Result<&[T; N], TryFromSliceError> {
20-
if slice.len() == N {
21-
let ptr = slice.as_ptr() as *const [T; N];
22-
// SAFETY: ok because we just checked that the length fits
23-
unsafe { Ok(&*ptr) }
24-
} else {
25-
Err(TryFromSliceError(()))
26-
}
27-
}
289

2910
/// A string stored as byte array.
3011
///
@@ -56,8 +37,8 @@ const fn array_ref_try_from_slice<'a, T, const N: usize>(
5637
/// let text: &str = &text_buffer; // Just derefs to `str`
5738
/// assert_eq!(text, "dai 大賢者 kenja")
5839
/// ```
59-
6040
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
41+
#[repr(transparent)]
6142
pub struct ByteString<const N: usize>(pub [u8; N]);
6243

6344
impl<const N: usize> ByteString<N> {
@@ -68,7 +49,7 @@ impl<const N: usize> ByteString<N> {
6849

6950
/// Wraps the given byte slice
7051
pub const fn from_bytes(bytes: &[u8]) -> Option<Self> {
71-
let res = array_ref_try_from_slice(bytes);
52+
let res = from_slice::array_ref_try_from_slice(bytes);
7253

7354
match res {
7455
Ok(array) => Some(Self(*array)),

src/string/from_slice.rs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// This file as a copy of the `<&[T; N]>::try_from(&[T])` impl of the Rust core
2+
// lib.
3+
//
4+
// This copy is needed, because as of Rust 1.51 `impl const` has not progressed
5+
// far enough to make that impl work in const context, instead, it is copied
6+
// here as a stand-alone `const fn`.
7+
//
8+
// Source:
9+
// https://github.com/rust-lang/rust/blob/eb82facb1626166188d49599a3313fc95201f556/library/core/src/array/mod.rs#L203-L215
10+
11+
12+
/// Our own `core::array::TryFromSliceError`
13+
///
14+
/// Used in [`array_ref_try_from_slice`].
15+
// We need a local copy of this type, because we need to instantiate it, but it
16+
// has a private field.
17+
pub(super) struct TryFromSliceError(());
18+
19+
/// Const version of `<&[T; N]>::try_from(&[T])`
20+
///
21+
/// Original Source:
22+
/// https://github.com/rust-lang/rust/blob/eb82facb1626166188d49599a3313fc95201f556/library/core/src/array/mod.rs#L203-L215
23+
pub(super) const fn array_ref_try_from_slice<'a, T, const N: usize>(
24+
slice: &[T],
25+
) -> Result<&[T; N], TryFromSliceError> {
26+
if slice.len() == N {
27+
let ptr = slice.as_ptr() as *const [T; N];
28+
// SAFETY: ok because we just checked that the length fits
29+
unsafe { Ok(&*ptr) }
30+
} else {
31+
Err(TryFromSliceError(()))
32+
}
33+
}

0 commit comments

Comments
 (0)