use core::{fmt::Debug, marker::PhantomData, ops::Deref, slice, str};
use super::StableLayout;
#[repr(C)]
pub struct SharedStr<'a> {
ptr: *const u8,
len: usize,
life: PhantomData<&'a str>,
}
unsafe impl<'a> StableLayout for SharedStr<'a> {}
impl<'a> Debug for SharedStr<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
Debug::fmt(self.deref(), f)
}
}
impl<'a> Clone for SharedStr<'a> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
impl<'a> Copy for SharedStr<'a> {}
impl<'a> Default for SharedStr<'a> {
#[inline(always)]
fn default() -> Self {
let life = PhantomData;
let len = 0;
let ptr = core::ptr::NonNull::dangling().as_ptr();
Self { ptr, len, life }
}
}
impl<'a> Deref for SharedStr<'a> {
type Target = str;
#[inline(always)]
fn deref(&self) -> &str {
unsafe {
str::from_utf8_unchecked(slice::from_raw_parts(self.ptr, self.len))
}
}
}
impl<'a> From<&'a str> for SharedStr<'a> {
#[inline(always)]
fn from(s: &'a str) -> Self {
let life = PhantomData;
let len = s.len();
let ptr = s.as_ptr();
Self { ptr, len, life }
}
}
impl<'a> From<SharedStr<'a>> for &'a str {
#[inline(always)]
fn from(shared: SharedStr<'a>) -> Self {
unsafe {
str::from_utf8_unchecked(slice::from_raw_parts(shared.ptr, shared.len))
}
}
}