use proc_macro2::TokenStream;
use quote::quote;
use syn::{ItemImpl, Type, TypePath};
pub fn ffi_impl_wrap(item: &ItemImpl) -> TokenStream {
let type_name = match &*item.self_ty {
Type::Path(p) => p.clone(),
_ => panic!(),
};
let s = ImplStruct { type_name };
let process_fn = s.gen_process_fn();
quote!(#process_fn)
}
struct ImplStruct {
type_name: TypePath,
}
impl ImplStruct {
fn ffi_ret_type(&self) -> TokenStream {
quote!(i64)
}
fn gen_process_fn(&self) -> TokenStream {
let type_name = &self.type_name;
let ret = self.ffi_ret_type();
let set_logger = crate::common::set_logger();
quote! {
#[no_mangle]
#[cfg(feature = "freenet-main-delegate")]
pub extern "C" fn process(parameters: i64, origin: i64, inbound: i64) -> #ret {
#set_logger
let parameters = unsafe {
let param_buf = &*(parameters as *const ::freenet_stdlib::memory::buf::BufferBuilder);
let bytes = &*std::ptr::slice_from_raw_parts(
param_buf.start(),
param_buf.bytes_written(),
);
Parameters::from(bytes)
};
let origin: Option<::freenet_stdlib::prelude::MessageOrigin> = unsafe {
let origin_buf = &*(origin as *const ::freenet_stdlib::memory::buf::BufferBuilder);
let bytes = &*std::ptr::slice_from_raw_parts(
origin_buf.start(),
origin_buf.bytes_written(),
);
if bytes.is_empty() {
None
} else {
match ::freenet_stdlib::prelude::bincode::deserialize(bytes) {
Ok(v) => Some(v),
Err(_) => None,
}
}
};
let inbound = unsafe {
let inbound_buf = &mut *(inbound as *mut ::freenet_stdlib::memory::buf::BufferBuilder);
let bytes =
&*std::ptr::slice_from_raw_parts(inbound_buf.start(), inbound_buf.bytes_written());
match ::freenet_stdlib::prelude::bincode::deserialize(bytes) {
Ok(v) => v,
Err(err) => return ::freenet_stdlib::prelude::DelegateInterfaceResult::from(
Err::<::std::vec::Vec<::freenet_stdlib::prelude::OutboundDelegateMsg>, _>(::freenet_stdlib::prelude::DelegateError::Deser(format!("{}", err)))
).into_raw(),
}
};
let mut ctx = unsafe { ::freenet_stdlib::prelude::DelegateCtx::__new() };
let result = <#type_name as ::freenet_stdlib::prelude::DelegateInterface>::process(
&mut ctx,
parameters,
origin,
inbound
);
::freenet_stdlib::prelude::DelegateInterfaceResult::from(result).into_raw()
}
}
}
}