Skip to main content

cffi/
lib.rs

1pub use cffi_impl::marshal;
2
3#[cfg(feature = "url")]
4mod url;
5
6mod arc;
7mod arc_ref;
8mod bool;
9mod box_ref;
10mod boxed;
11mod copy;
12mod pathbuf;
13mod str;
14mod string;
15mod unit;
16mod vec;
17mod vec_ref;
18
19/// Exported functions for consumption via C API
20pub mod ffi {
21    pub use super::{string::cffi_string_free, vec::cffi_vec_free};
22}
23
24#[cfg(feature = "url")]
25pub use self::url::UrlMarshaler;
26
27pub use self::bool::BoolMarshaler;
28pub use self::pathbuf::PathBufMarshaler;
29pub use self::str::StrMarshaler;
30pub use self::vec::VecMarshaler;
31pub use arc::ArcMarshaler;
32pub use arc_ref::ArcRefMarshaler;
33pub use box_ref::BoxRefMarshaler;
34pub use boxed::BoxMarshaler;
35pub use copy::CopyMarshaler;
36pub use string::StringMarshaler;
37pub use unit::UnitMarshaler;
38pub use vec_ref::VecRefMarshaler;
39
40use std::{io, marker::PhantomData};
41
42pub type ErrCallback = Option<extern "C" fn(*const u8, usize)>;
43pub type RetCallback<T> = Option<extern "C" fn(T)>;
44
45pub trait ReturnType {
46    type Foreign;
47    type ForeignTraitObject;
48
49    fn foreign_default() -> Self::Foreign;
50    fn foreign_default_trait_object() -> Self::ForeignTraitObject {
51        unimplemented!();
52    }
53}
54
55pub trait InputType {
56    // type Local;
57    type Foreign;
58    type ForeignTraitObject;
59
60    // fn local_default() -> Self::Local;
61}
62
63pub trait ToForeign<Local, Foreign>: Sized {
64    type Error;
65    fn to_foreign(_: Local) -> Result<Foreign, Self::Error>;
66}
67
68pub trait ToForeignTraitObject<Local: ?Sized, Foreign: ?Sized> {
69    type Error;
70    fn to_foreign_trait_object(_: Local) -> Result<crate::TraitObject<Foreign>, Self::Error>;
71}
72
73pub trait FromForeign<Foreign, Local>: Sized {
74    type Error;
75    unsafe fn from_foreign(_: Foreign) -> Result<Local, Self::Error>;
76}
77
78#[inline(always)]
79pub fn null_ptr_error() -> Box<io::Error> {
80    Box::new(io::Error::new(io::ErrorKind::InvalidData, "null pointer"))
81}
82
83// Magical catch-all implementation for `Result<Local, Error>`.
84// impl<T, Foreign, Local> ToForeign<Result<Local, T::Error>, Foreign> for T
85// where
86//     T: ToForeign<Local, Foreign>,
87// {
88//     type Error = T::Error;
89
90//     fn to_foreign(result: Result<Local, T::Error>) -> Result<Foreign, Self::Error> {
91//         match result {
92//             Ok(v) => <Self as ToForeign<Local, Foreign>>::to_foreign(v),
93//             Err(e) => Err(e),
94//         }
95//     }
96// }
97
98#[repr(C)]
99pub struct Slice<T: ?Sized> {
100    pub data: *mut T,
101    pub len: usize,
102}
103
104impl<T> Slice<T> {
105    unsafe fn cast<U>(self) -> Slice<U> {
106        std::mem::transmute::<Slice<T>, Slice<U>>(self)
107    }
108}
109
110impl<T> std::default::Default for Slice<T> {
111    fn default() -> Self {
112        Slice {
113            data: std::ptr::null_mut(),
114            len: 0,
115        }
116    }
117}
118
119impl<T> std::fmt::Debug for Slice<T> {
120    fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
121        formatter
122            .debug_struct(&format!("Slice<{}>", std::any::type_name::<T>()))
123            .field("data", &self.data.cast::<std::ffi::c_void>())
124            .field("len", &self.len)
125            .finish()
126    }
127}
128
129impl<T> AsRef<[T]> for Slice<T> {
130    fn as_ref(&self) -> &[T] {
131        unsafe { std::slice::from_raw_parts(self.data as _, self.len) }
132    }
133}
134
135#[repr(C)]
136#[derive(Copy, Clone)]
137pub struct TraitObject<T: ?Sized> {
138    pub data: *mut (),
139    pub vtable: *mut (),
140    pub ty: PhantomData<T>,
141}
142
143#[macro_export]
144macro_rules! trait_object {
145    ($input:path : $ty:ty) => {
146        std::mem::transmute_copy::<_, $crate::TraitObject<$ty>>(&$input)
147    };
148}
149
150#[cfg(test)]
151mod tests {
152    #[test]
153    fn test() {}
154}