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
use super::*;
#[derive(Default)]
pub(in crate)
struct Args {
pub(in crate) untyped: Option<Untyped>,
}
pub(in crate)
struct Untyped {
pub(in crate) _kw: kw::untyped,
}
mod kw {
::syn::custom_keyword!(untyped);
}
impl Parse for Args {
fn parse (
input: ParseStream<'_>,
) -> Result<Args>
{
let mut ret = Args::default();
while input.is_empty().not() {
let snoopy = input.lookahead1();
match () {
| _case if snoopy.peek(kw::untyped) => {
if ret.untyped.is_some() {
return Err(input.error("duplicate parameter"));
}
ret.untyped = Some(Untyped {
_kw: input.parse().unwrap()
});
},
| _default => return Err(snoopy.error()),
}
let _: Option<Token![,]> = input.parse()?;
}
Ok(ret)
}
}
#[allow(unexpected_cfgs)]
pub(in super)
fn handle (
Args { untyped }: Args,
input: ItemConst,
) -> Result<TokenStream2>
{
if cfg!(feature = "headers").not() {
Ok(input.into_token_stream())
} else {
#[apply(let_quote!)]
use {
::safer_ffi::{
__cfg_headers__,
ඞ,
},
::safer_ffi as krate,
};
let VAR @ _ = &input.ident;
let VAR_str @ _ = &VAR.to_string();
let Ty @ _ = &input.ty;
let ref each_doc = utils::extract_docs(&input.attrs)?;
let skip_type = untyped.is_some();
Ok(quote!(
#input
#[cfg(not(target_arch = "wasm32"))]
#ඞ::inventory::submit! {
#ඞ::FfiExport {
name: #VAR_str,
gen_def: |
definer: &'_ mut dyn #ඞ::Definer,
lang: #ඞ::Language,
| {
#krate::__with_cfg_python__!(|$if_cfg_python| {
use #krate::headers::{
Language,
languages::{self, HeaderLanguage},
};
let header_builder: &'static dyn HeaderLanguage = {
match lang {
| Language::C => &languages::C,
| Language::CSharp => &languages::CSharp,
$($($if_cfg_python)?
| Language::Python => &languages::Python,
)?
}
};
<#ඞ::CLayoutOf<#Ty> as #ඞ::CType>::define_self(
header_builder,
definer
)?;
header_builder
}).emit_constant(
definer,
&[ #(#each_doc),* ],
#VAR_str,
&#ඞ::PhantomData::<
#ඞ::CLayoutOf< #Ty >,
>,
#skip_type,
&#VAR,
)
},
}
}
))
}
}