Vendor in a purple-sys wrapper
This code comes from https://github.com/Flared/purple-icq/tree/master/src/purple It is GPL-3 licensed
This commit is contained in:
106
src/purple/ffi.rs
Normal file
106
src/purple/ffi.rs
Normal file
@@ -0,0 +1,106 @@
|
||||
use glib::translate::{Ptr, ToGlibPtr};
|
||||
use std::ffi::CStr;
|
||||
use std::os::raw::c_char;
|
||||
use std::ptr::{null, null_mut, NonNull};
|
||||
|
||||
pub fn mut_override<T>(ptr: *const T) -> *mut T {
|
||||
ptr as *mut T
|
||||
}
|
||||
pub trait IntoGlibPtr<P> {
|
||||
fn into_glib_full(self) -> *mut P;
|
||||
}
|
||||
|
||||
impl<P: AsMutPtr> IntoGlibPtr<P::PtrType> for P {
|
||||
fn into_glib_full(mut self) -> *mut P::PtrType {
|
||||
let ptr = self.as_mut_ptr();
|
||||
std::mem::forget(self);
|
||||
ptr
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToGlibContainerFromIterator<P>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
fn into_glib_full_from_iter<I: IntoIterator<Item = Self>>(iter: I) -> P;
|
||||
}
|
||||
|
||||
impl<T, P> ToGlibContainerFromIterator<*mut glib_sys::GList> for T
|
||||
where
|
||||
T: AsPtr<PtrType = P>,
|
||||
T: IntoGlibPtr<P>,
|
||||
P: 'static,
|
||||
{
|
||||
fn into_glib_full_from_iter<I>(iter: I) -> *mut glib_sys::GList
|
||||
where
|
||||
I: IntoIterator<Item = Self>,
|
||||
{
|
||||
let mut list: *mut glib_sys::GList = std::ptr::null_mut();
|
||||
unsafe {
|
||||
for ptr in iter.into_iter().map(|v| v.into_glib_full()) {
|
||||
list = glib_sys::g_list_prepend(list, Ptr::to(ptr));
|
||||
}
|
||||
glib_sys::g_list_reverse(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToGlibContainerFromIterator<*mut glib_sys::GHashTable> for (&'static CStr, String) {
|
||||
fn into_glib_full_from_iter<I>(iter: I) -> *mut glib_sys::GHashTable
|
||||
where
|
||||
I: IntoIterator<Item = Self>,
|
||||
{
|
||||
unsafe {
|
||||
let ptr = glib_sys::g_hash_table_new_full(
|
||||
Some(glib_sys::g_str_hash),
|
||||
Some(glib_sys::g_str_equal),
|
||||
None,
|
||||
Some(glib_sys::g_free),
|
||||
);
|
||||
for (k, v) in iter {
|
||||
let k: *const c_char = k.as_ptr();
|
||||
let v: *mut c_char = v.to_glib_full();
|
||||
glib_sys::g_hash_table_insert(ptr, k as *mut _, v as *mut _);
|
||||
}
|
||||
ptr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AsPtr {
|
||||
type PtrType;
|
||||
fn as_ptr(&self) -> *const Self::PtrType;
|
||||
}
|
||||
|
||||
pub trait AsMutPtr {
|
||||
type PtrType;
|
||||
fn as_mut_ptr(&mut self) -> *mut Self::PtrType;
|
||||
}
|
||||
|
||||
impl<T: AsPtr> AsMutPtr for T {
|
||||
type PtrType = T::PtrType;
|
||||
fn as_mut_ptr(&mut self) -> *mut Self::PtrType {
|
||||
self.as_ptr() as *mut Self::PtrType
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsPtr for Option<NonNull<T>> {
|
||||
type PtrType = T;
|
||||
fn as_ptr(&self) -> *const Self::PtrType {
|
||||
self.map_or_else(null, |x| x.as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsPtr for Option<*const T> {
|
||||
type PtrType = T;
|
||||
fn as_ptr(&self) -> *const T {
|
||||
self.unwrap_or_else(null)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AsPtr for Option<*mut T> {
|
||||
type PtrType = T;
|
||||
fn as_ptr(&self) -> *const T {
|
||||
self.unwrap_or_else(null_mut)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user