Skip to content

Commit

Permalink
hybrid-array: AssociatedArraySize trait (#1006)
Browse files Browse the repository at this point in the history
Adds a type for associating a `typenum`-based size with a given array
type, which can be either `[T; N]` or `Array<T, U>`.

This subsumes the previous `IntoArray` trait, which can be replaced by a
simple `Into` bound instead.
  • Loading branch information
tarcieri authored Dec 30, 2023
1 parent 3d3ee5c commit 63ba0eb
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 25 deletions.
20 changes: 9 additions & 11 deletions hybrid-array/src/impls.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{Array, ArrayOps, ArraySize, IntoArray};
use super::{Array, ArrayOps, ArraySize, AssociatedArraySize};

#[cfg(feature = "zeroize")]
use zeroize::{Zeroize, ZeroizeOnDrop};
Expand Down Expand Up @@ -27,7 +27,6 @@ macro_rules! impl_array_size {
$(
impl<T> ArrayOps<T, $len> for Array<T, typenum::$ty> {
const SIZE: usize = $len;
type Size = typenum::$ty;

#[inline]
fn as_core_array(&self) -> &[T; $len] {
Expand Down Expand Up @@ -69,17 +68,17 @@ macro_rules! impl_array_size {
type ArrayType<T> = [T; $len];
}

impl<T> From<Array<T, typenum::$ty>> for [T; $len] {
fn from(arr: Array<T, typenum::$ty>) -> [T; $len] {
arr.0
}
impl<T> AssociatedArraySize for [T; $len] {
type Size = typenum::$ty;
}

impl<T> IntoArray<T> for [T; $len] {
impl<T> AssociatedArraySize for Array<T, typenum::$ty> {
type Size = typenum::$ty;
}

fn into_hybrid_array(self) -> Array<T, Self::Size> {
Array::from_core_array(self)
impl<T> From<Array<T, typenum::$ty>> for [T; $len] {
fn from(arr: Array<T, typenum::$ty>) -> [T; $len] {
arr.0
}
}
)+
Expand Down Expand Up @@ -169,10 +168,9 @@ impl_array_size! {

impl<T, const N: usize> ArrayOps<T, N> for [T; N]
where
Self: IntoArray<T>,
Self: AssociatedArraySize,
{
const SIZE: usize = N;
type Size = <Self as IntoArray<T>>::Size;

#[inline]
fn as_core_array(&self) -> &[T; N] {
Expand Down
21 changes: 7 additions & 14 deletions hybrid-array/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,8 @@ fn check_slice_length<T, U: ArraySize>(slice: &[T]) -> Result<(), TryFromSliceEr

/// Array operations which are const generic over a given array size.
pub trait ArrayOps<T, const N: usize>:
Borrow<[T; N]>
AssociatedArraySize
+ Borrow<[T; N]>
+ BorrowMut<[T; N]>
+ From<[T; N]>
+ Into<[T; N]>
Expand All @@ -546,14 +547,9 @@ pub trait ArrayOps<T, const N: usize>:
{
/// Size of an array as a `usize`.
///
/// Not to be confused with [`ArrayOps::Size`], which is `typenum`-based.
/// Not to be confused with [`AssociatedArraySize::Size`], which is [`typenum`]-based.
const SIZE: usize;

/// [`ArraySize`] type: `typenum`-provided [`Unsigned`] integer.
///
/// Not to be confused with [`ArrayOps::SIZE`], which is a `usize`.
type Size: ArraySize;

/// Returns a reference to the inner array.
fn as_core_array(&self) -> &[T; N];

Expand Down Expand Up @@ -652,16 +648,13 @@ impl<T, const N: usize> ArrayExt<T> for [T; N] {
/// It is implemented only for a number of types defined in [`typenum::consts`].
pub unsafe trait ArraySize: Unsigned {
/// Array type which corresponds to this size.
type ArrayType<T>: ArrayExt<T> + IntoArray<T> + IntoIterator<Item = T> + SliceOps<T>;
type ArrayType<T>: ArrayExt<T> + Into<Array<T, Self>> + IntoIterator<Item = T> + SliceOps<T>;
}

/// Convert the given type into an [`Array`].
pub trait IntoArray<T> {
/// Size of the [`Array`].
/// Associates an [`ArraySize`] with a given type.
pub trait AssociatedArraySize: Sized {
/// Size of an array type, expressed as a [`typenum`]-based [`ArraySize`].
type Size: ArraySize;

/// Convert into the `hybrid-array` crate's [`Array`] type.
fn into_hybrid_array(self) -> Array<T, Self::Size>;
}

/// Splits the shared slice into a slice of `N`-element arrays, starting at the beginning
Expand Down

0 comments on commit 63ba0eb

Please sign in to comment.