ffi-std 0.1.0

FFI-safe versions of some std datastructures.
//! FFI-safe slice. Pointer first, then length.

use std::marker::PhantomData;

use std::ops::{Deref, DerefMut};

use crate::{Frozen, copyclone, from, rawparts, debug};

#[repr(C)]
pub struct FFISlice<'a, T: 'a> {
	ptr: *mut T,
	len: usize,
	_ph: PhantomData<&'a T>
}

copyclone!(FFISlice<'a; T>);

rawparts!(FFISlice<'a; T>; ptr: *mut T, len: usize; _ph: PhantomData); debug!(FFISlice<'a; T>);

from!(FFISlice<'a; T> => &'a [T]; to_slice);

impl<'a, T> FFISlice<'a, T> {
	pub fn new(x: &'a [T]) -> Frozen<Self> {
		Frozen::new(Self {
			ptr: x.as_ptr() as *mut _,
			len: x.len(),
			_ph: PhantomData
		})
	}

	pub fn new_mut(x: &'a mut [T]) -> Self {
		Self {
			ptr: x.as_mut_ptr(),
			len: x.len(),
			_ph: PhantomData
		}
	}

	pub fn to_slice(self) -> &'a [T] {
		unsafe {
			std::slice::from_raw_parts(self.ptr, self.len)
		}
	}

	pub fn to_slice_mut(self) -> &'a mut [T] {
		unsafe {
			std::slice::from_raw_parts_mut(self.ptr, self.len)
		}
	}
}

impl<'a, T> Deref for FFISlice<'a, T> {
	type Target = [T];

	fn deref(&self) -> &[T] {
		self.to_slice()
	}
}

impl<'a, T> DerefMut for FFISlice<'a, T> {
	fn deref_mut(&mut self) -> &mut [T] {
		self.to_slice_mut()
	}
}