Here is a more generic version of the take_n function:
mod impls_for_array_{
mod sealed{
pub trait Sealed{}
}
use self::sealed::Sealed;
pub trait Array:Sealed{
type Elem;
const SIZE:usize;
}
macro_rules! impls_for_array {
($($size:expr),*)=>{
$(
impl<T> Sealed for [T;$size] {}
impl<T> Array for [T;$size] {
type Elem=T;
const SIZE:usize=$size;
}
)*
}
}
impls_for_array! {
00,01,02,03,04,05,06,07,08,09,
10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31,32
}
}
pub use self::impls_for_array_::Array;
fn take_n<A>(slice: &[A::Elem]) -> Option<&A>
where A:Array
{
if slice.len() < A::SIZE {
None
} else {
Some(unsafe { &*(slice as *const [A::Elem] as *const A) })
}
}
fn take_n_mut<A>(slice: &mut [A::Elem]) -> Option<&mut A>
where A:Array
{
if slice.len() < A::SIZE {
None
} else {
Some(unsafe { &mut *(slice as *mut [A::Elem] as *mut A) })
}
}
fn main() {
assert_eq!(take_n(&[1,2,3,4]),Some(&[]) );
assert_eq!(take_n(&[1,2,3,4]),Some(&[1]) );
assert_eq!(take_n(&[1,2,3,4]),Some(&[1,2]) );
assert_eq!(take_n(&[1,2,3,4]),Some(&[1,2,3]) );
assert_eq!(take_n(&[1,2,3,4]),Some(&[1,2,3,4]) );
assert_eq!(take_n::<[_;10]>(&[1,2,3,4]),None );
}