use crate::option;
use std::{
fmt::{self, Debug, Display, Formatter},
mem::ManuallyDrop,
slice
};
#[repr(C)]
pub(crate) struct StringPtr {
ptr: *mut u8,
len: usize,
cap: usize
}
impl StringPtr {
pub(crate) fn new(s: String) -> Self {
let (ptr, len, cap) = s.into_raw_parts();
Self { ptr, len, cap }
}
pub(crate) fn as_str(&self) -> &str {
unsafe { str::from_utf8_unchecked(slice::from_raw_parts(self.ptr, self.len)) }
}
pub(crate) fn into_string(self) -> String {
let this = ManuallyDrop::new(self);
unsafe { String::from_raw_parts(this.ptr, this.len, this.cap) }
}
}
impl AsRef<str> for StringPtr {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl Display for StringPtr {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(self.as_str(), f)
}
}
impl Debug for StringPtr {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Debug::fmt(self.as_str(), f)
}
}
impl Drop for StringPtr {
fn drop(&mut self) {
drop(unsafe { String::from_raw_parts(self.ptr, self.len, self.cap) });
}
}
impl From<String> for StringPtr {
fn from(value: String) -> Self {
Self::new(value)
}
}
impl From<StringPtr> for String {
fn from(value: StringPtr) -> Self {
value.into_string()
}
}
unsafe impl Send for StringPtr {}
unsafe impl Sync for StringPtr {}
option!(StringPtr);