fix(types): Improve support for generic rust types
The support might be improved, but I still sort of want to remove generic types, as the current implementation is just _bad_.
This commit is contained in:
parent
f688df1248
commit
c2d21fd0a8
|
@ -129,12 +129,11 @@ pub extern "C" fn string_free(ptr: *const c_char) {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Convertible> Convertible for Option<T> {
|
impl<T: Convertible> Convertible for Option<T> {
|
||||||
type Ptr = *const T;
|
type Ptr = *const <T as Convertible>::Ptr;
|
||||||
|
|
||||||
fn into_ptr(self) -> Self::Ptr {
|
fn into_ptr(self) -> Self::Ptr {
|
||||||
if let Some(inner) = self {
|
if let Some(inner) = self {
|
||||||
let mut_ref = &mut inner.into_ptr();
|
&inner.into_ptr()
|
||||||
mut_ref as *mut _ as *const T
|
|
||||||
} else {
|
} else {
|
||||||
ptr::null()
|
ptr::null()
|
||||||
}
|
}
|
||||||
|
@ -153,14 +152,11 @@ impl<T: Convertible> Convertible for Option<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Convertible, E: Error> Convertible for Result<T, E> {
|
impl<T: Convertible, E: Error> Convertible for Result<T, E> {
|
||||||
type Ptr = *const T;
|
type Ptr = *const <T as Convertible>::Ptr;
|
||||||
|
|
||||||
fn into_ptr(self) -> Self::Ptr {
|
fn into_ptr(self) -> Self::Ptr {
|
||||||
match self {
|
match self {
|
||||||
Ok(ok) => {
|
Ok(ok) => &ok.into_ptr(),
|
||||||
let mut_ref = &mut ok.into_ptr();
|
|
||||||
mut_ref as *mut _ as *const T
|
|
||||||
}
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
errno::set(TypeConversionError::ResultWasErr {
|
errno::set(TypeConversionError::ResultWasErr {
|
||||||
original_message: err.to_string(),
|
original_message: err.to_string(),
|
||||||
|
@ -183,15 +179,16 @@ impl<T: Convertible, E: Error> Convertible for Result<T, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Convertible for Vec<T> {
|
impl<T: Convertible> Convertible for Vec<T> {
|
||||||
type Ptr = crate::Vec<T>;
|
type Ptr = crate::Vec<<T as Convertible>::Ptr>;
|
||||||
|
|
||||||
fn into_ptr(self) -> Self::Ptr {
|
fn into_ptr(self) -> Self::Ptr {
|
||||||
let mut me = ManuallyDrop::new(self);
|
let data_vec: Vec<_> = self.into_iter().map(|val| val.into_ptr()).collect();
|
||||||
|
let data_vec = ManuallyDrop::new(data_vec);
|
||||||
Self::Ptr {
|
Self::Ptr {
|
||||||
data: me.as_mut_ptr() as *const T,
|
data: data_vec.as_ptr(),
|
||||||
length: me.len(),
|
length: data_vec.len(),
|
||||||
capacity: me.capacity(),
|
capacity: data_vec.capacity(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,18 +200,51 @@ impl<T> Convertible for Vec<T> {
|
||||||
// if !ptr.data.is_aligned() {
|
// if !ptr.data.is_aligned() {
|
||||||
// return Err(TypeConversionError::NotAligned);
|
// return Err(TypeConversionError::NotAligned);
|
||||||
// }
|
// }
|
||||||
let vec = unsafe {
|
let base_vec = unsafe {
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
// We simply hope that c treated our vector as read-only and didn't modify it.
|
// We simply hope that c treated our vector as read-only and didn't modify it.
|
||||||
// See the SAFETY section of the String implementation for more detail.
|
// See the SAFETY section of the String implementation for more detail.
|
||||||
Vec::from_raw_parts(ptr.data as *mut T, ptr.length, ptr.capacity)
|
Vec::from_raw_parts(
|
||||||
|
ptr.data as *mut <T as Convertible>::Ptr,
|
||||||
|
ptr.length,
|
||||||
|
ptr.capacity,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let vec: Vec<_> = base_vec
|
||||||
|
.into_iter()
|
||||||
|
.map(|val| <T as Convertible>::from_ptr(val))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
Ok(vec)
|
Ok(vec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(@soispha): Add the required generic support here <2024-02-18>
|
macro_rules! make_vec_free {
|
||||||
#[no_mangle]
|
($value:ident, $name:ident) => {
|
||||||
pub extern "C" fn vec_free(ptr: crate::Vec<u8>) {
|
#[no_mangle]
|
||||||
Vec::drop_ptr(ptr);
|
pub extern "C" fn $name(ptr: crate::Vec<<$value as Convertible>::Ptr>) {
|
||||||
|
Vec::<$value>::drop_ptr(ptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unsigned
|
||||||
|
make_vec_free!(u8, vec_free_u8);
|
||||||
|
make_vec_free!(u16, vec_free_u16);
|
||||||
|
make_vec_free!(u32, vec_free_u32);
|
||||||
|
make_vec_free!(u64, vec_free_u64);
|
||||||
|
// Signed
|
||||||
|
make_vec_free!(i8, vec_free_i8);
|
||||||
|
make_vec_free!(i16, vec_free_i16);
|
||||||
|
make_vec_free!(i32, vec_free_i32);
|
||||||
|
make_vec_free!(i64, vec_free_i64);
|
||||||
|
// Float
|
||||||
|
make_vec_free!(f32, vec_free_f32);
|
||||||
|
make_vec_free!(f64, vec_free_f64);
|
||||||
|
// Other
|
||||||
|
make_vec_free!(String, vec_free_String);
|
||||||
|
|
||||||
|
// FIXME(@soispha): Find a way to support these <2024-02-27>
|
||||||
|
// make_vec_free!(Option<?>, vec_free_Option);
|
||||||
|
// make_vec_free!(Vec<?>, vec_free_Vec);
|
||||||
|
// make_vec_free!(Result<?, ?>, vec_free_Result);
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
// NOTE(@soispha): All types specified here *MUST* be include in the BASE_TYPES constant, otherwise
|
// NOTE(@soispha): All types specified here *MUST* be include in the BASE_TYPES constant, otherwise
|
||||||
// they are not usable from Trixy code <2023-12-25>
|
// they are not usable from Trixy code <2023-12-25>
|
||||||
|
|
||||||
|
// NOTE(@soispha): All types added here must also have an added free impl for the vector type (./traits/convert_trait.rs) <2024-02-27>
|
||||||
|
|
||||||
use std::ffi::c_char;
|
use std::ffi::c_char;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
Reference in New Issue