Skip to main content

stack_array/
conversions.rs

1//^
2//^ HEAD
3//^
4
5//> HEAD -> SUPER
6use super::{
7    Array,
8    errors::{
9        UnmatchedCapacity,
10        CapacityExceeded
11    }
12};
13
14//> HEAD -> ALLOC
15use alloc::vec::Vec;
16
17//> HEAD -> CONSTRANGEITER
18use constrangeiter::ConstIntoIterator;
19
20//> HEAD -> CORE
21use core::{
22    mem::{
23        MaybeUninit,
24        transmute_neo as transmute
25    },
26    array::from_fn as arrayfn,
27    marker::Destruct
28};
29
30
31//^
32//^ FROM
33//^
34
35//> FROM -> FIXED ARRAY
36const impl<
37    Type: [const] Destruct, 
38    const M: usize, 
39    const N: usize
40> From<[Type; N]> for Array<Type, M> where [(); M - N]: {
41    fn from(value: [Type; N]) -> Self {
42        let mut data = MaybeUninit::<[Type; M]>::uninit().transpose();
43        let mut index = 0;
44        let _ = value.map(const |element| {
45            data[index].write(element); 
46            index += 1;
47        });
48        return Array {
49            length: N,
50            data: data
51        };
52    }
53}
54
55//> FROM -> FUNCTION
56const impl<
57    Type: [const] Destruct, 
58    Generator: [const] FnMut(usize) -> Type + [const] Destruct,
59    const N: usize,
60> From<Generator> for Array<Type, N> {
61    fn from(mut value: Generator) -> Self {return Array {
62        length: N,
63        data: arrayfn(const |index| MaybeUninit::new(value(index)))
64    }}
65}
66
67//> FROM -> VEC
68const impl<Type, const N: usize> TryFrom<Vec<Type>> for Array<Type, N> {
69    type Error = CapacityExceeded<N>;
70    fn try_from(value: Vec<Type>) -> Result<Self, Self::Error> {
71        let (pointer, length, _) = value.into_parts();
72        if length > N {return Err(CapacityExceeded {
73            expected: length
74        })}
75        let mut array = Array {
76            length: length,
77            data: MaybeUninit::uninit().transpose()
78        };
79        for index in (0..length).const_into_iter() {
80            array.data[index].write(unsafe {pointer.add(index).read()});
81        }
82        return Ok(array);
83    }
84}
85
86//> FROM -> PARTS
87const impl<Type, const N: usize> From<(usize, [MaybeUninit<Type>; N])> for Array<Type, N> {
88    fn from(value: (usize, [MaybeUninit<Type>; N])) -> Self {return unsafe {transmute(value)}}
89}
90
91
92//^
93//^ INTO
94//^
95
96//> INTO -> VEC
97impl<Type, const N: usize> Into<Vec<Type>> for Array<Type, N> {
98    fn into(self) -> Vec<Type> {return Vec::from_iter(self.into_iter())}
99}
100
101//> INTO -> FIXED ARRAY
102const impl<
103    Type, 
104    const N: usize, 
105    const LENGTH: usize
106> TryInto<[Type; LENGTH]> for Array<Type, N> where [(); N - LENGTH]: {
107    type Error = UnmatchedCapacity<LENGTH>;
108    fn try_into(self) -> Result<[Type; LENGTH], Self::Error> {
109        let (length, data) = Into::<(usize, [MaybeUninit<Type>; N])>::into(self);
110        if length != LENGTH {return Err(UnmatchedCapacity {
111            present: length
112        })}
113        return Ok(unsafe {transmute(data)});
114    }
115}
116
117//> INTO -> PARTS
118const impl<Type, const N: usize> Into<(usize, [MaybeUninit<Type>; N])> for Array<Type, N> {
119    fn into(self) -> (usize, [MaybeUninit<Type>; N]) {return unsafe {transmute(self)}}
120}