use core::ops::Deref;
use crate::slab_arc::SlabArc;
use core::str::{from_utf8_unchecked, from_utf8, Utf8Error};
#[derive(Clone)]
pub struct SlabSliceArc<const N: usize, const SZ: usize> {
pub(crate) arc: SlabArc<N, SZ>,
pub(crate) start: usize,
pub(crate) len: usize,
}
impl<const N: usize, const SZ: usize> Deref for SlabSliceArc<N, SZ> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.arc.deref()[self.start..][..self.len]
}
}
impl<const N: usize, const SZ: usize> SlabSliceArc<N, SZ> {
pub fn sub_slice_arc(&self, start: usize, len: usize) -> Result<SlabSliceArc<N, SZ>, ()> {
let new_arc = self.arc.clone();
let start = self.start + start;
let new_end = self.start + self.len;
let good_start = start < new_end;
let good_len = (start + len) <= new_end;
if good_start && good_len {
let new_slice_arc = SlabSliceArc {
arc: new_arc,
start,
len,
};
Ok(new_slice_arc)
} else {
Err(())
}
}
pub fn into_str_arc(self) -> Result<SlabStrArc<N, SZ>, Utf8Error> {
let _str = from_utf8(&self)?;
Ok(SlabStrArc { inner: self })
}
}
#[derive(Clone)]
pub struct SlabStrArc<const N: usize, const SZ: usize> {
pub(crate) inner: SlabSliceArc<N, SZ>,
}
impl<const N: usize, const SZ: usize> PartialEq<str> for SlabStrArc<N, SZ> {
fn eq(&self, other: &str) -> bool {
let stir: &str = self.deref();
stir.eq(other)
}
}
impl<const N: usize, const SZ: usize> PartialEq for SlabStrArc<N, SZ> {
fn eq(&self, other: &Self) -> bool {
let stir_me: &str = self.deref();
let stir_ot: &str = other.deref();
stir_me.eq(stir_ot)
}
}
impl<const N: usize, const SZ: usize> Eq for SlabStrArc<N, SZ> { }
impl<const N: usize, const SZ: usize> Deref for SlabStrArc<N, SZ> {
type Target = str;
fn deref(&self) -> &Self::Target {
let slice: &[u8] = &self.inner;
unsafe {
from_utf8_unchecked(slice)
}
}
}
impl<const N: usize, const SZ: usize> SlabStrArc<N, SZ> {
pub fn from_slab_slice(other: &SlabSliceArc<N, SZ>) -> Result<Self, Utf8Error> {
let clone = other.clone();
clone.into_str_arc()
}
}