#![no_std]
pub extern crate arrayvec;
pub extern crate generic_array;
pub use generic_array::typenum;
use arrayvec::{Array, ArrayString, ArrayVec, CapacityError};
use generic_array::{ArrayLength, GenericArray};
use core::str::Utf8Error;
pub type GenericArrayVec<T, N> = ArrayVec<Wrapper<T, N>>;
pub type GenericArrayString<N> = ArrayString<Wrapper<u8, N>>;
#[derive(Debug)]
pub struct Wrapper<T, N>(pub GenericArray<T, N>)
where
N: ArrayLength<T>;
pub trait GenericArrayVecExt<T, N>
where
N: ArrayLength<T>,
{
fn generic_from<A>(arr: A) -> GenericArrayVec<T, N>
where
A: Into<GenericArray<T, N>>;
fn into_generic_array(self) -> Result<GenericArray<T, N>, Self>
where
Self: Sized;
}
pub trait GenericArrayStringExt<N>
where
N: ArrayLength<u8>,
{
fn generic_from(string: &str) -> Result<GenericArrayString<N>, CapacityError<&str>>;
fn generic_from_byte_string<A>(byte_string: &A) -> Result<GenericArrayString<N>, Utf8Error>
where
A: Into<GenericArray<u8, N>> + AsRef<[u8]>;
}
impl<T, N> Wrapper<T, N>
where
N: ArrayLength<T>,
{
pub fn into_inner(self) -> GenericArray<T, N> {
self.0
}
}
unsafe impl<T, N> Array for Wrapper<T, N>
where
N: ArrayLength<T>,
{
type Item = T;
type Index = usize;
fn as_ptr(&self) -> *const Self::Item {
self.0.as_ptr()
}
fn as_mut_ptr(&mut self) -> *mut Self::Item {
self.0.as_mut_ptr()
}
fn capacity() -> usize {
N::to_usize()
}
}
impl<T, N> From<GenericArray<T, N>> for Wrapper<T, N>
where
N: ArrayLength<T>,
{
fn from(arr: GenericArray<T, N>) -> Self {
Wrapper(arr)
}
}
impl<T, N> Into<GenericArray<T, N>> for Wrapper<T, N>
where
N: ArrayLength<T>,
{
fn into(self) -> GenericArray<T, N> {
self.0
}
}
impl<T, N> GenericArrayVecExt<T, N> for GenericArrayVec<T, N>
where
N: ArrayLength<T>,
{
fn generic_from<A>(arr: A) -> GenericArrayVec<T, N>
where
A: Into<GenericArray<T, N>>,
{
ArrayVec::from(Wrapper::from(arr.into()))
}
fn into_generic_array(self) -> Result<GenericArray<T, N>, Self> {
Ok(self.into_inner()?.into_inner())
}
}
impl<N> GenericArrayStringExt<N> for GenericArrayString<N>
where
N: ArrayLength<u8>,
{
fn generic_from(string: &str) -> Result<GenericArrayString<N>, CapacityError<&str>> {
ArrayString::from(string)
}
fn generic_from_byte_string<A>(byte_string: &A) -> Result<GenericArrayString<N>, Utf8Error>
where
A: Into<GenericArray<u8, N>> + AsRef<[u8]>,
{
ArrayString::from_byte_string(&Wrapper::from(GenericArray::clone_from_slice(
byte_string.as_ref(),
)))
}
}
#[cfg(test)]
mod tests {
use super::{
generic_array::GenericArray, typenum::{U10, U41, U5}, *,
};
#[test]
fn test_vec_simple() {
let mut vec = GenericArrayVec::<i32, U41>::new();
assert_eq!(vec.len(), 0);
assert_eq!(vec.capacity(), 41);
vec.extend(0..20);
assert_eq!(vec.len(), 20);
assert_eq!(&vec[..5], &[0, 1, 2, 3, 4]);
}
#[test]
fn test_vec_from_array() {
let vec: GenericArrayVec<i32, _> = GenericArrayVec::generic_from([0, 1, 2, 3, 4]);
assert_zero_to_four(&vec);
}
#[test]
fn test_vec_from_generic_array() {
let arr: GenericArray<i32, U5> = GenericArray::clone_from_slice(&[0, 1, 2, 3, 4]);
let vec = GenericArrayVec::generic_from(arr);
assert_zero_to_four(&vec);
}
#[test]
fn test_vec_from_iter() {
let vec: GenericArrayVec<i32, U10> = (0..10).collect();
assert_zero_to_four(&vec);
}
#[test]
fn test_vec_into_generic_array() {
let vec: GenericArrayVec<i32, _> = GenericArrayVec::generic_from([0, 1, 2, 3, 4]);
let arr = vec.into_generic_array().unwrap();
assert_zero_to_four(&arr);
}
#[test]
fn test_string_from() {
let string = GenericArrayString::<U10>::generic_from("hello").unwrap();
assert_eq!(&string, "hello");
}
#[test]
fn test_string_from_byte_string_literal() {
let byte_string = b"hello";
let string = GenericArrayString::<U5>::generic_from_byte_string(byte_string).unwrap();
assert_eq!(&string, "hello");
}
#[test]
fn test_string_from_byte_string_generic() {
let byte_string = GenericArray::from(b"hello".clone());
let string = GenericArrayString::<U5>::generic_from_byte_string(&byte_string).unwrap();
assert_eq!(&string, "hello");
}
fn assert_zero_to_four<T>(vec: &T)
where
T: AsRef<[i32]>,
{
assert_eq!(&vec.as_ref()[..5], &[0, 1, 2, 3, 4][..]);
}
}