use quote::quote;
use syn::Pat;
use syn::Type;
pub(crate) struct ExportedFnData {
pub(crate) bytecode_fn_name_opt: Option<syn::Ident>,
pub(crate) _bytecode_meta_span: Option<proc_macro2::Span>, pub(crate) no_panic_catch: bool,
pub(crate) _no_panic_catch_span: Option<proc_macro2::Span>, pub(crate) noalloc: bool,
pub(crate) _noalloc_span: Option<proc_macro2::Span>,
pub(crate) native_fn_name: syn::Ident, pub(crate) visibility: syn::Visibility, pub(crate) original_fn_block: Box<syn::Block>,
pub(crate) runtime_arg_pat: Box<Pat>,
pub(crate) runtime_arg_ty: Box<Type>,
pub(crate) processed_args: Vec<ProcessedArg>,
pub(crate) return_interop_detail: InteropTypeDetail, pub(crate) user_return_type_ast: syn::Type,
pub(crate) _original_fn_ident_span: proc_macro2::Span,
pub(crate) _fn_token_span: proc_macro2::Span,
pub(crate) _fn_inputs_span: proc_macro2::Span,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum PrimitiveInteropType {
F64,
I64,
I32,
Bool,
ISize,
}
#[derive(Clone)]
pub(crate) enum InteropTypeDetail {
Unit, Primitive {
primitive_type: PrimitiveInteropType,
original_rust_type: Box<syn::Type>, },
OCaml {
wrapper_type: Box<syn::Type>, inner_type: Box<syn::Type>, },
BoxRoot {
inner_type: Box<syn::Type>, },
}
impl InteropTypeDetail {
pub(crate) fn is_primitive(&self) -> bool {
matches!(self, InteropTypeDetail::Primitive { .. })
}
pub(crate) fn get_ocaml_to_rust_fn_name(&self) -> Result<String, syn::Error> {
match self {
InteropTypeDetail::Primitive { primitive_type, .. } => Ok(match primitive_type {
PrimitiveInteropType::F64 => "float_val".to_string(),
PrimitiveInteropType::I64 => "int64_val".to_string(),
PrimitiveInteropType::I32 => "int32_val".to_string(),
PrimitiveInteropType::Bool => "bool_val".to_string(),
PrimitiveInteropType::ISize => "int_val".to_string(),
}),
_ => Err(syn::Error::new(
proc_macro2::Span::call_site(),
"Internal error: get_ocaml_to_rust_fn_name called on non-primitive type",
)),
}
}
pub(crate) fn get_rust_to_ocaml_fn_name(&self) -> Result<String, syn::Error> {
match self {
InteropTypeDetail::Primitive { primitive_type, .. } => Ok(match primitive_type {
PrimitiveInteropType::F64 => "alloc_float".to_string(),
PrimitiveInteropType::I64 => "alloc_int64".to_string(),
PrimitiveInteropType::I32 => "alloc_int32".to_string(),
PrimitiveInteropType::Bool => "make_ocaml_bool".to_string(),
PrimitiveInteropType::ISize => "make_ocaml_int".to_string(),
}),
_ => Err(syn::Error::new(
proc_macro2::Span::call_site(),
"Internal error: get_rust_to_ocaml_fn_name called on non-primitive type",
)),
}
}
pub(crate) fn get_conversion_module_path_tokens(&self) -> proc_macro2::TokenStream {
quote! { ::ocaml_interop::internal:: }
}
}
pub(crate) struct ProcessedArg {
pub(crate) pattern: Box<Pat>,
pub(crate) type_detail: InteropTypeDetail,
pub(crate) original_rust_type: Box<syn::Type>,
}