use core::{
fmt::Debug,
marker::PhantomData,
ops::{Deref, DerefMut},
slice, str,
};
use super::StableLayout;
#[repr(C)]
pub struct UniqueStr<'a> {
ptr: *mut u8,
len: usize,
life: PhantomData<&'a mut str>,
}
unsafe impl<'a> StableLayout for UniqueStr<'a> {}
impl<'a> Debug for UniqueStr<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
Debug::fmt(self.deref(), f)
}
}
impl<'a> Clone for UniqueStr<'a> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
impl<'a> Copy for UniqueStr<'a> {}
impl<'a> Default for UniqueStr<'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 UniqueStr<'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> DerefMut for UniqueStr<'a> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut str {
unsafe {
str::from_utf8_unchecked_mut(slice::from_raw_parts_mut(
self.ptr, self.len,
))
}
}
}
impl<'a> From<&'a mut str> for UniqueStr<'a> {
#[inline(always)]
fn from(s: &'a mut str) -> Self {
let life = PhantomData;
let len = s.len();
let ptr = s.as_mut_ptr();
Self { ptr, len, life }
}
}
impl<'a> From<UniqueStr<'a>> for &'a mut str {
#[inline(always)]
fn from(unique: UniqueStr<'a>) -> Self {
unsafe {
str::from_utf8_unchecked_mut(slice::from_raw_parts_mut(
unique.ptr, unique.len,
))
}
}
}