hybrid_array/traits.rs
1//! Trait definitions.
2
3use crate::Array;
4use core::{
5 borrow::{Borrow, BorrowMut},
6 ops::{Index, IndexMut, Range},
7};
8use typenum::Unsigned;
9
10/// Trait which associates a [`usize`] size and `ArrayType` with a
11/// `typenum`-provided [`Unsigned`] integer.
12///
13/// # Safety
14///
15/// `ArrayType` MUST be an array with a number of elements exactly equal to
16/// [`Unsigned::USIZE`]. Breaking this requirement will cause undefined behavior.
17///
18/// NOTE: This trait is effectively sealed and can not be implemented by third-party crates.
19/// It is implemented only for a number of types defined in [`typenum::consts`].
20pub unsafe trait ArraySize: Unsigned {
21 /// Array type which corresponds to this size.
22 ///
23 /// This is always defined to be `[T; N]` where `N` is the same as
24 /// [`ArraySize::USIZE`][`typenum::Unsigned::USIZE`].
25 type ArrayType<T>: AssocArraySize<Size = Self>
26 + AsRef<[T]>
27 + AsMut<[T]>
28 + Borrow<[T]>
29 + BorrowMut<[T]>
30 + From<Array<T, Self>>
31 + Index<usize>
32 + Index<Range<usize>>
33 + IndexMut<usize>
34 + IndexMut<Range<usize>>
35 + Into<Array<T, Self>>
36 + IntoIterator<Item = T>;
37}
38
39/// Associates an [`ArraySize`] with a given type. Can be used to accept `[T; N]` const generic
40/// arguments and convert to [`Array`] internally.
41///
42/// This trait is also the magic glue that makes the [`ArrayN`][`crate::ArrayN`] type alias work.
43///
44/// # Example
45///
46/// ```
47/// use hybrid_array::{ArrayN, AssocArraySize};
48///
49/// pub fn example<const N: usize>(bytes: &[u8; N])
50/// where
51/// [u8; N]: AssocArraySize + AsRef<ArrayN<u8, N>>
52/// {
53/// // _arrayn is ArrayN<u8, N>
54/// let _arrayn = bytes.as_ref();
55/// }
56/// ```
57pub trait AssocArraySize: Sized {
58 /// Size of an array type, expressed as a [`typenum`]-based [`ArraySize`].
59 type Size: ArraySize;
60}
61
62impl<T, U> AssocArraySize for Array<T, U>
63where
64 U: ArraySize,
65{
66 type Size = U;
67}