sea-orm-ffi 0.1.3

Compatibility layer for Sea-ORM when crossing a Rust-to-Rust FFI boundary
Documentation
use crate::option;
use std::{
	fmt::{self, Debug, Formatter},
	mem::ManuallyDrop,
	slice
};

/// A [`Vec`] pointer that is FFI-safe whenever `T` is also FFI-safe.
#[repr(C)]
pub(crate) struct VecPtr<T> {
	ptr: *mut T,
	len: usize,
	cap: usize
}

impl<T> VecPtr<T> {
	/// Create a new pointer.
	///
	/// This calls [`Vec::into_raw_parts()`] and stores the pointer, length and
	/// capacity in a C-ABI-compatible layout.
	pub(crate) fn new(s: Vec<T>) -> Self {
		let (ptr, len, cap) = s.into_raw_parts();
		Self { ptr, len, cap }
	}

	/// Borrow the [`Vec`] pointed to by this pointer.
	///
	/// This calls [`slice::from_raw_parts`].
	pub(crate) fn as_slice(&self) -> &[T] {
		unsafe { slice::from_raw_parts(self.ptr, self.len) }
	}

	/// Return the [`Vec`] this pointer points to.
	///
	/// This calls [`Vec::from_raw_parts()`].
	pub(crate) fn into_vec(self) -> Vec<T> {
		let this = ManuallyDrop::new(self);
		unsafe { Vec::from_raw_parts(this.ptr, this.len, this.cap) }
	}
}

impl<T> AsRef<[T]> for VecPtr<T> {
	fn as_ref(&self) -> &[T] {
		self.as_slice()
	}
}

impl<T: Debug> Debug for VecPtr<T> {
	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
		Debug::fmt(self.as_slice(), f)
	}
}

impl<T> Drop for VecPtr<T> {
	fn drop(&mut self) {
		drop(unsafe { Vec::from_raw_parts(self.ptr, self.len, self.cap) });
	}
}

impl<T> From<Vec<T>> for VecPtr<T> {
	fn from(value: Vec<T>) -> Self {
		Self::new(value)
	}
}

impl<T> From<VecPtr<T>> for Vec<T> {
	fn from(value: VecPtr<T>) -> Self {
		value.into_vec()
	}
}

unsafe impl<T: Send> Send for VecPtr<T> {}

unsafe impl<T: Sync> Sync for VecPtr<T> {}

option!(VecPtr<T>);