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        forget
26    },
27    array::from_fn as arrayfn,
28    marker::Destruct
29};
30
31
32//^
33//^ FROM
34//^
35
36//> FROM -> FIXED ARRAY
37const impl<
38    Type: [const] Destruct, 
39    const M: usize, 
40    const N: usize
41> From<[Type; N]> for Array<Type, M> where [(); M - N]: {
42    fn from(value: [Type; N]) -> Self {
43        let mut data = MaybeUninit::<[Type; M]>::uninit().transpose();
44        let mut index = 0;
45        let _ = value.map(const |element| {
46            data[index].write(element); 
47            index += 1;
48        });
49        return Array {
50            length: N,
51            data: data
52        };
53    }
54}
55
56//> FROM -> FUNCTION
57const impl<
58    Type: [const] Destruct, 
59    Generator: [const] FnMut(usize) -> Type + [const] Destruct,
60    const N: usize,
61> From<Generator> for Array<Type, N> {
62    fn from(mut value: Generator) -> Self {return Array {
63        length: N,
64        data: arrayfn(const |index| MaybeUninit::new(value(index)))
65    }}
66}
67
68//> FROM -> PARTS
69const impl<Type, const N: usize> From<(usize, [MaybeUninit<Type>; N])> for Array<Type, N> {
70    fn from((length, data): (usize, [MaybeUninit<Type>; N])) -> Self {return Array {
71        length: length,
72        data: data
73    }}
74}
75
76
77//^
78//^ TRYFROM
79//^
80
81//> TRYFROM -> VEC
82const impl<Type, const N: usize> TryFrom<Vec<Type>> for Array<Type, N> {
83    type Error = CapacityExceeded<N>;
84    fn try_from(value: Vec<Type>) -> Result<Self, Self::Error> {
85        let (pointer, length, _) = value.into_parts();
86        if length > N {return Err(CapacityExceeded {
87            expected: length
88        })}
89        let mut array = Array {
90            length: length,
91            data: MaybeUninit::uninit().transpose()
92        };
93        for index in (0..length).const_into_iter() {
94            array.data[index].write(unsafe {pointer.add(index).read()});
95        }
96        return Ok(array);
97    }
98}
99
100
101//^
102//^ INTO
103//^
104
105//> INTO -> VEC
106impl<Type, const N: usize> From<Array<Type, N>> for Vec<Type> {
107    fn from(value: Array<Type, N>) -> Self {return Vec::from_iter(value.into_iter())}
108}
109
110//> INTO -> PARTS
111const impl<Type, const N: usize> From<Array<Type, N>> for (usize, [MaybeUninit<Type>; N]) {
112    fn from(value: Array<Type, N>) -> Self {
113        let length = value.length;
114        let data = unsafe {value.data.as_ptr().cast::<[MaybeUninit<Type>; N]>().read()};
115        forget(value);
116        return (length, data);
117    }
118}
119
120
121//^
122//^ TRYINTO
123//^
124
125//> TRYINTO -> FIXED ARRAY
126const impl<
127    Type,
128    const N: usize,
129    const LENGTH: usize
130> TryFrom<Array<Type, N>> for [Type; LENGTH] where [(); N - LENGTH]: {
131    type Error = UnmatchedCapacity<LENGTH>;
132    fn try_from(value: Array<Type, N>) -> Result<Self, Self::Error> {
133        let (length, data) = value.into();
134        if length != LENGTH {return Err(UnmatchedCapacity {
135            present: length
136        })}
137        let (initialized, _): (
138            [MaybeUninit<Type>; LENGTH],
139            [MaybeUninit<Type>; N - LENGTH]
140        ) = unsafe {transmute(data)};
141        return Ok(unsafe {transmute(initialized)});
142    }
143}