#![no_std]
#[doc(hidden)]
pub use core;
use core::mem::MaybeUninit;
#[macro_export]
macro_rules! concat {
($($e:expr),* $(,)?) => {
$crate::_concat!($($e),*)
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! _concat {
() => { "" };
($($maybe:expr),+) => {{
$crate::_concat!(@impl $($crate::_maybe_std_concat!($maybe)),+)
}};
(@impl $($s:expr),+) => {{
use $crate::core::primitive::{str, u8};
$(
const _: &str = $s; )*
let slice: &[u8] = $crate::concat_slices!([u8]: $($s.as_bytes()),+);
unsafe { $crate::core::str::from_utf8_unchecked(slice) }
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! _maybe_std_concat {
($e:literal) => {
$crate::core::concat!($e)
};
($e:expr) => {
$e
};
}
#[macro_export]
macro_rules! concat_bytes {
($($e:expr),* $(,)?) => {
$crate::_concat_bytes!($($e),*)
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! _concat_bytes {
() => { b"" };
($($maybe:expr),+) => {{
$crate::_concat_bytes!(@impl $($crate::_maybe_std_concat_bytes!($maybe)),+)
}};
(@impl $($s:expr),+) => {{
use $crate::core::primitive::u8;
$crate::concat_slices!([u8]: $($s),+)
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! _maybe_std_concat_bytes {
($e:literal) => {
$crate::core::concat_bytes!($e)
};
($e:expr) => {
$e
};
}
#[macro_export]
macro_rules! concat_slices {
([$T:ty]: $($s:expr),* $(,)?) => {
$crate::_concat_slices!([$T]: $($s),*)
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! _concat_slices {
([$T:ty]:) => {{
const ARR: [$T; 0] = [];
&ARR
}};
([$T:ty]: $($s:expr),+) => {{
$(
const _: &[$T] = $s; )*
const LEN: $crate::core::primitive::usize = $( $s.len() + )* 0;
const ARR: [$T; LEN] = {
let arr = $crate::concat::<LEN, $T>(&[$($s),+]);
unsafe { $crate::core::mem::transmute(arr) }
};
&ARR
}};
}
#[doc(hidden)]
pub const fn concat<const LEN: usize, T: Copy>(slices: &[&[T]]) -> [MaybeUninit<T>; LEN] {
let mut arr: [MaybeUninit<T>; LEN] = [MaybeUninit::uninit(); LEN];
let mut base = 0;
let mut i = 0;
while i < slices.len() {
let slice = slices[i];
let mut j = 0;
while j < slice.len() {
arr[base + j] = MaybeUninit::new(slice[j]);
j += 1;
}
base += slice.len();
i += 1;
}
if base != LEN {
panic!("invalid length");
}
arr
}