concat_const 0.2.0

const `&[u8]` and `&str` concatenation
Documentation
#![no_std]

#[inline]
pub const fn len_sum(to_concat: &[&[u8]]) -> usize {
    let mut len = 0;
    let mut i = 0;
    while i < to_concat.len() {
        len += to_concat[i].len();
        i += 1;
    }
    len
}

#[inline]
pub const fn concat_bytes<const LEN: usize>(to_concat: &[&[u8]]) -> [u8; LEN] {
    let mut res: [u8; LEN] = [0; LEN];
    let mut shift = 0;
    let mut i = 0;
    while i < to_concat.len() {
        let to_concat_one = to_concat[i];
        let mut j = 0;
        while j < to_concat_one.len() {
            res[j + shift] = to_concat_one[j];
            j += 1;
        }
        shift += j;
        i += 1;
    }
    res
}

#[macro_export]
macro_rules! concat_bytes {
    ($($rest:expr),*) => {{
        const TO_CONCAT: &[&[u8]] = &[$($rest),*];
        const LEN: usize = $crate::len_sum(TO_CONCAT);
        &$crate::concat_bytes::<LEN>(TO_CONCAT)
    }};
    ($($rest:expr),*,) => {
        $crate::concat_bytes!($($rest),*)
    };
}

#[macro_export]
macro_rules! concat {
    ($($rest:expr),*) => {{
        const RES: &[u8] = $crate::concat_bytes!($($rest.as_bytes()),*);
        unsafe { ::core::str::from_utf8_unchecked(RES) }
    }};
    ($($rest:expr),*,) => {
        $crate::concat!($($rest),*)
    };
}

#[inline]
pub const fn int_len(mut int: i128) -> usize {
    let mut len = 0;
    if int < 0 {
        len = 1;
    }
    while int != 0 {
        int /= 10;
        len += 1;
    }
    len
}

#[inline]
pub const fn int_to_bytes<const LEN: usize>(mut int: i128) -> [u8; LEN] {
    let mut res: [u8; LEN] = [0; LEN];
    let mut i = LEN - 1;
    if int < 0 {
        res[0] = b'-';
        res[i] = -(int % 10) as u8 | 0x30;
        int /= -10;
        i = i.saturating_sub(1);
    }
    while int > 0 {
        res[i] = (int % 10) as u8 | 0x30;
        int /= 10;
        i = i.saturating_sub(1);
    }

    res
}

pub struct BytesWrapper(pub &'static [u8]);
impl BytesWrapper {
    #[inline]
    pub const fn as_bytes(&'static self) -> &'static [u8] {
        self.0
    }
}

#[macro_export]
macro_rules! int_bytes {
    ($a:expr) => {{
        const LEN: usize = $crate::int_len($a);
        &$crate::int_to_bytes::<LEN>($a)
    }};
}

#[macro_export]
macro_rules! int {
    ($a:expr) => {{
        $crate::BytesWrapper($crate::int_bytes!($a))
    }};
}

#[inline]
pub const fn eq_bytes(left: &[u8], right: &[u8]) -> bool {
    if left.len() != right.len() {
        return false;
    }

    let mut i = 0;
    while i != left.len() {
        if left[i] != right[i] {
            return false;
        }
        i += 1;
    }

    true
}

#[inline]
pub const fn eq_str(left: &str, right: &str) -> bool {
    eq_bytes(left.as_bytes(), right.as_bytes())
}