konst_macro_rules/
slice_.rs1#![allow(non_camel_case_types)]
2
3use core::{
4 fmt::{self, Display},
5 marker::PhantomData,
6};
7
8#[macro_export]
9macro_rules! try_into_array {
10 ($slice:expr, $len:expr$(,)*) => {
11 match $slice {
12 (_x) => unsafe { $crate::__priv_try_into_array!(explicit, _x, $len) },
13 }
14 };
15 ($slice:expr $(,)*) => {
16 match $slice {
17 (_x) => unsafe { $crate::__priv_try_into_array!(infer, _x) },
18 }
19 };
20}
21
22#[macro_export]
23#[cfg(not(feature = "rust_1_51"))]
24macro_rules! __priv_try_into_array {
25 (explicit, $slice:ident, $len:expr) => {{
27 const __LEN: usize = $len;
28
29 let slice = $crate::slice_::__priv_SliceLifetime($slice, $crate::slice_::Phantom::NEW);
30
31 type __Constrainer<'a, T> = $crate::slice_::__priv_TypeLifetime<'a, [T; __LEN], T>;
32
33 if slice.0.len() == __LEN {
34 let ptr = slice.0.as_ptr() as *const [_; __LEN];
35
36 let ret = __Constrainer {
37 array: $crate::utils::Dereference { ptr }.reff,
38 phantom: slice.1,
39 };
40
41 $crate::__::Ok(ret.array)
42 } else {
43 $crate::__::Err($crate::slice_::TryIntoArrayError::__priv__new())
44 }
45 }};
46 (infer, $slice:ident) => {
47 $crate::__::compile_error!(concat!(
48 "\
49 To infer the length of the returned array,\n\
50 you must enable the \"rust_1_51\" feature (which requires Rust 1.51.0).\n\
51 \n\
52 Otherwise you need to pass the length explicitly, \
53 eg: try_into_array!(foo, 10)"
54 ))
55 };
56}
57
58#[macro_export]
59#[cfg(feature = "rust_1_51")]
60macro_rules! __priv_try_into_array {
61 (explicit, $slice:ident, $len:expr) => {{
70 let slice = $crate::slice_::__priv_SliceLifetime($slice, $crate::slice_::Phantom::NEW);
71 let plen = $crate::slice_::PhantomUsize::<{ $len }>;
72
73 $crate::__priv_try_into_array! {inner, slice, plen}
74 }};
75 (infer, $slice:ident) => {
76 loop {
77 let slice = $crate::slice_::__priv_SliceLifetime($slice, $crate::slice_::Phantom::NEW);
78 let plen = $crate::slice_::PhantomUsize;
79
80 if false {
81 break $crate::slice_::get_length(plen);
82 }
83
84 break $crate::__priv_try_into_array! {inner, slice, plen};
85 }
86 };
87 (inner, $slice:ident, $len:ident) => {
88 if let (true, ptr) = $crate::slice_::check_length($slice.0, $len) {
89 let array = $crate::utils::Dereference { ptr }.reff;
90
91 $crate::__::Ok($crate::slice_::__priv_ArrayLifetime(array, $slice.1).0)
92 } else {
93 $crate::__::Err($crate::slice_::TryIntoArrayError::__priv__new())
94 }
95 };
96}
97
98pub struct Phantom<'a, T>(PhantomData<*mut *mut &'a [T]>);
99
100impl<'a, T: 'a> Phantom<'a, T> {
101 pub const NEW: Self = Self(PhantomData);
102}
103
104#[repr(transparent)]
105pub struct __priv_TypeLifetime<'a, T, U> {
106 pub array: &'a T,
107 pub phantom: Phantom<'a, U>,
108}
109
110#[repr(transparent)]
111pub struct __priv_SliceLifetime<'a, T>(pub &'a [T], pub Phantom<'a, T>);
112
113#[cfg(feature = "rust_1_51")]
114#[derive(Copy, Clone)]
115pub struct PhantomUsize<const N: usize>;
116
117#[cfg(feature = "rust_1_51")]
118pub const fn get_length<'a, T, const N: usize>(
119 _: PhantomUsize<N>,
120) -> Result<&'a [T; N], TryIntoArrayError> {
121 loop {}
122}
123
124#[inline(always)]
125#[cfg(feature = "rust_1_51")]
126pub const fn check_length<T, const N: usize>(
127 slice: &[T],
128 _len: PhantomUsize<N>,
129) -> (bool, *const [T; N]) {
130 (N == slice.len(), slice.as_ptr() as *const [T; N])
131}
132
133#[repr(transparent)]
134#[cfg(feature = "rust_1_51")]
135pub struct __priv_ArrayLifetime<'a, T, const N: usize>(pub &'a [T; N], pub Phantom<'a, T>);
136
137#[cfg(feature = "rust_1_56")]
140#[inline]
141pub const fn try_into_array_func<T, const N: usize>(
142 slice: &[T],
143) -> Result<&[T; N], TryIntoArrayError> {
144 if slice.len() == N {
145 let ptr = slice.as_ptr() as *const [T; N];
146 unsafe { Ok(crate::utils::Dereference { ptr }.reff) }
147 } else {
148 Err(TryIntoArrayError { _priv: () })
149 }
150}
151
152#[cfg(feature = "mut_refs")]
155#[inline]
156pub const fn try_into_array_mut_func<T, const N: usize>(
157 slice: &mut [T],
158) -> Result<&mut [T; N], TryIntoArrayError> {
159 if slice.len() == N {
160 let ptr = slice as *mut [T] as *mut [T; N];
161 unsafe { Ok(crate::utils::deref_raw_mut_ptr(ptr)) }
162 } else {
163 Err(TryIntoArrayError { _priv: () })
164 }
165}
166
167#[derive(Debug, PartialEq, Eq, Copy, Clone)]
170pub struct TryIntoArrayError {
171 _priv: (),
172}
173
174impl TryIntoArrayError {
175 #[allow(non_snake_case)]
176 #[doc(hidden)]
177 #[inline]
178 pub const fn __priv__new() -> Self {
179 TryIntoArrayError { _priv: () }
180 }
181
182 pub const fn panic(&self) -> ! {
184 let offset = self.number();
185 [][offset]
186 }
187
188 const fn number(&self) -> usize {
189 0
190 }
191}
192
193impl Display for TryIntoArrayError {
194 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 f.write_str("Could not cast slice to array reference")
196 }
197}