use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use crate::{Frozen, copyclone, from, rawparts, debug};
#[repr(C)]
pub struct FFIStr<'a> {
ptr: *mut u8,
len: usize,
_ph: PhantomData<&'a str>
}
copyclone!(FFIStr<'a;>);
rawparts!(FFIStr<'a;>; ptr: *mut u8, len: usize; _ph: PhantomData); debug!(FFIStr<'a;>);
from!(FFIStr<'a;> => &'a str; to_str);
impl<'a> FFIStr<'a> {
pub fn new(x: &'a str) -> Frozen<Self> {
Frozen::new(Self {
ptr: x.as_ptr() as *mut _,
len: x.len(),
_ph: PhantomData
})
}
pub fn new_mut(x: &'a mut str) -> Self {
Self {
ptr: x.as_mut_ptr(),
len: x.len(),
_ph: PhantomData
}
}
pub fn to_str(self) -> &'a str {
unsafe {
std::str::from_utf8_unchecked(std::slice::from_raw_parts(self.ptr, self.len))
}
}
pub fn to_str_mut(self) -> &'a mut str {
unsafe {
std::str::from_utf8_unchecked_mut(std::slice::from_raw_parts_mut(self.ptr, self.len))
}
}
}
impl<'a> Deref for FFIStr<'a> {
type Target = str;
fn deref(&self) -> &str {
self.to_str()
}
}
impl<'a> DerefMut for FFIStr<'a> {
fn deref_mut(&mut self) -> &mut str {
self.to_str_mut()
}
}