use std::ops::{Deref, DerefMut};
use std::mem;
use std::mem::ManuallyDrop;
use std::marker::PhantomData;
use std::fmt;
use std::fmt::{Debug, Formatter};
use crate::{Frozen, from, rawparts};
#[repr(C)]
pub struct FFIVec<T> {
ptr: *mut T,
len: usize,
cap: usize
}
rawparts!(FFIVec<;T>; ptr: *mut T, len: usize, cap: usize);
from!(FFIVec<;T> => Vec<T>; to_vec);
impl<T: Debug> Debug for FFIVec<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Debug::fmt(&self.as_vec(), f)
}
}
impl<T> FFIVec<T> {
pub fn new(mut x: Vec<T>) -> Self {
let s = Self {
ptr: x.as_mut_ptr(),
len: x.len(),
cap: x.capacity()
};
mem::forget(x);
s
}
pub fn to_vec(self) -> Vec<T> {
unsafe {
Vec::from_raw_parts(self.ptr, self.len, self.cap)
}
}
pub fn as_vec<'a>(&'a self) -> Frozen<AsVec<'a, T>> {
unsafe {
Frozen::new(AsVec::new(Vec::from_raw_parts(self.ptr, self.len, self.cap)))
}
}
pub fn as_vec_mut<'a>(&'a mut self) -> AsVec<'a, T> {
unsafe {
AsVec::new(Vec::from_raw_parts(self.ptr, self.len, self.cap))
}
}
}
impl<T> Drop for FFIVec<T> {
fn drop(&mut self) {
unsafe {
Vec::from_raw_parts(self.ptr, self.len, self.cap);
}
}
}
pub struct AsVec<'a, T> {
vec: ManuallyDrop<Vec<T>>,
_ph: PhantomData<&'a FFIVec<T>>
}
impl<'a, T> Deref for AsVec<'a, T> {
type Target = ManuallyDrop<Vec<T>>;
fn deref(&self) -> &ManuallyDrop<Vec<T>> {
&self.vec
}
}
impl<'a, T> DerefMut for AsVec<'a, T> {
fn deref_mut(&mut self) -> &mut ManuallyDrop<Vec<T>> {
&mut self.vec
}
}
impl<'a, T: Debug> Debug for AsVec<'a, T> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
Debug::fmt(&*self.vec, f)
}
}
impl<'a, T> AsVec<'a, T> {
fn new(vec: Vec<T>) -> Self {
Self { vec: ManuallyDrop::new(vec), _ph: PhantomData }
}
}