use core::{
ops::{ Index, IndexMut, Range, RangeFrom, RangeTo, RangeFull, RangeInclusive, RangeToInclusive },
slice,
};
pub mod usize_to_stack_str;
#[derive(Debug)]
pub struct StackStr<const N: usize>
{
pub bytes: [u8; N],
pub slice: Range<usize>,
}
impl<'a, const N: usize> StackStr<N>
{
pub fn from(bytes: [u8; N], slice: Range<usize>) -> Self {
Self {
bytes,
slice
}
}
pub fn str(&self) -> &str {
unsafe {
core::str::from_utf8_unchecked(
&self[self.slice.start..self.slice.end]
)
}
}
}
impl<'a, const N: usize> Index<usize> for StackStr<N>
{
type Output = u8;
fn index(&self, index: usize) -> &Self::Output {
unsafe {
let ptr = self.bytes.as_ptr().add(index);
&*ptr
}
}
}
impl<'a, const N: usize> IndexMut<usize> for StackStr<N> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
unsafe {
let ptr = self.bytes.as_mut_ptr().add(index);
&mut *ptr
}
}
}
impl<'a, const N: usize> Index<Range<usize>> for StackStr<N>
{
type Output = [u8];
fn index(&self, index: Range<usize>) -> &Self::Output {
unsafe {
let start = self.bytes.as_ptr().add(index.start);
let len = index.end - index.start;
slice::from_raw_parts(start, len)
}
}
}
impl<'a, const N: usize> Index<RangeFrom<usize>> for StackStr<N>
{
type Output = [u8];
fn index(&self, index: RangeFrom<usize>) -> &Self::Output {
unsafe {
let start = self.bytes.as_ptr().add(index.start);
let len = self.bytes.len() - index.start;
slice::from_raw_parts(start, len)
}
}
}
impl<'a, const N: usize> Index<RangeTo<usize>> for StackStr<N>
{
type Output = [u8];
fn index(&self, index: RangeTo<usize>) -> &Self::Output {
unsafe {
let start = self.bytes.as_ptr();
let len = index.end;
slice::from_raw_parts(start, len)
}
}
}
impl<'a, const N: usize> Index<RangeFull> for StackStr<N>
{
type Output = [u8];
fn index(&self, _index: RangeFull) -> &Self::Output {
unsafe {
let start = self.bytes.as_ptr();
let len = self.bytes.len();
slice::from_raw_parts(start, len)
}
}
}