1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
//! The backend for the `ffishim_derive` procedural macro. //! //! This crate provides: //! //! - The C types used by the "ffi shim" layer such as `FFIVec` and `FFIResult` for example. //! - The logic for generating a "ffi shim" layer around your API. See the `ffishim_derive` //! macro for more documentation on that. //! //! You most likely should not use this API directly, and rely on the `ffishim_derive` procedural //! macro for all your ffi shim needs. #![feature(vec_into_raw_parts)] #[macro_use] extern crate darling; extern crate proc_macro2; /// Entry point of the ffishim crate. /// /// This data is generated from a `DeriveInput` by the darling crate. Its `IntoTokens` /// implementations generates the `FFIName` equivalent data structure, where `Name` is the name of /// the original data structure. /// /// It is also consumed by multiple other objects in this crate for generation of other critical /// logic (`From`, `TryInto` ...) #[derive(Debug, FromDeriveInput)] #[darling(attributes(ffishim), map = "Data::validate")] pub struct Data { /// Specify a constructor to construct the original data with when given the ffi form. /// /// Enumerations cannot expose constructors at the data-structure level, and must instead /// expose them on a per-variant basis. #[darling(default)] pub constructor: Option<::syn::Path>, /// The ffi type will not expose any fields of this data structure, making it opaque. /// /// This is useful in case a data structure you have must be shared through the ffi, but it /// cannot be represented/modeled in the other language, or it should not. #[darling(default)] pub opaque: bool, /// The name of the data structure. pub ident: ::syn::Ident, /// The list of variants (for an enum) or fields (for a struct.) pub data: ::darling::ast::Data<Variant, Field>, } mod data; /// A FFIShim field as loaded by darling. /// /// This structure represents a field as ingested by ffishim. Other structures iterate on sets of /// `Field`s to generate code. #[derive(Debug, FromField)] #[darling(attributes(ffishim))] pub struct Field { /// This field will not be exposed as such and instead be replaced by a pointer to the value. /// /// This is useful in case a type you want to expose through the ffi holds one field that /// cannot be represented/modeled in the other language, or it should not. #[darling(default)] pub opaque: bool, /// Name of the field (empty for tuple structs.) pub ident: Option<::syn::Ident>, /// Visibility of the given field. All ffi fields are public by default. pub vis: ::syn::Visibility, /// Type of the original field. pub ty: ::syn::Type, } mod field; /// A FFIShim variant as loaded by darling. /// /// This structure represents an enum variant as ingested by ffishim. Other structures iterate on /// sets of `Variant`s and their internal sets of `Field`s to generate code. #[derive(Debug, FromVariant)] #[darling(attributes(ffishim))] pub struct Variant { /// For enumerations, constructor is controlled on a per-variant basis. #[darling(default)] pub constructor: Option<::syn::Path>, /// Name of the variant. pub ident: ::syn::Ident, /// Fields of the variant (empty for unit variants.) pub fields: ::darling::ast::Fields<Field>, } mod variant; /// Derived from an `ItemFn` to generate its equivalent wrapper function. /// /// The `ToTokens` implementation of this structure generates the code for the wrapper around the /// API's functions. This API performs all structure transformation required to obtain clean types /// in the rust code and return the FFI types back. #[derive(Debug)] pub struct Function { pub ffi_name: ::syn::Ident, pub ffi_args: Vec<::syn::FnArg>, pub ffi_output: ::syn::ReturnType, pub call_expr: ::syn::Expr, } mod function; /// Derived from `Data` to generate the `FFIName::from(Name)` conversion. pub struct From { orig_name: ::syn::Ident, ffi_name: ::syn::Ident, receiver: ::syn::Expr, init_expr: ::syn::Expr, } mod from; /// Derived from `Data` to generate the `FFIName::try_into(Name)` conversion. pub struct TryInto { orig_name: ::syn::Ident, ffi_name: ::syn::Ident, receiver: ::syn::Expr, init_expr: ::syn::Expr, } mod try_into; /// Derived from `Data` to generate the `new_name` function. /// /// This function can be called from the caller code to initialize a ffishim data structure /// elegantly, without having to resort to its own malloc. pub struct News(Vec<::syn::ItemFn>); mod new; /// Derived from `Data` to generate the `free_name` function. /// /// This function takes care of freeing the provided data structure and all its hierarchy. This /// prevents the caller from having to understand the specifics. pub struct Free { func_name: ::syn::Ident, receiver: ::syn::Expr, ffi_type: ::syn::Type, free_expr: ::syn::Expr, } mod free; pub mod library; pub mod types; /// Macros to extend the `syn` tree and other useful shortcuts. #[macro_use] mod helpers; pub use helpers::shim_allocator_setting;