servicepoint-binding-c/src/macros.rs
Vinzenz Schroeter 75e2df41fe
Some checks failed
Rust / build-gnu-apt (pull_request) Failing after 1m31s
Rust / build-size-gnu-unstable (pull_request) Failing after 42s
export value fields via macro
2025-06-17 23:56:11 +02:00

147 lines
4.5 KiB
Rust

macro_rules! wrap_free {
($prefix:ident :: $typ:ty) => {
paste::paste! {
#[doc = concat!("Deallocates a [", stringify!($typ), "] instance.")]
#[no_mangle]
pub unsafe extern "C" fn [<$prefix _free>](instance: NonNull<$typ>) {
unsafe { $crate::mem::heap_drop(instance) }
}
}
};
}
macro_rules! wrap_clone {
($prefix:ident :: $typ:ty) => {
paste::paste! {
#[doc = concat!("Clones a [", stringify!($typ), "] instance.")]
#[no_mangle]
pub unsafe extern "C" fn [<$prefix _clone>](instance: NonNull<$typ>) -> NonNull<$typ> {
unsafe { $crate::mem::heap_clone(instance) }
}
}
};
}
macro_rules! nonnull_as_ref {
($ident:ident) => {
$ident.as_ref()
};
}
macro_rules! nonnull_as_mut {
($ident:ident) => {
&mut *$ident.as_ptr()
};
}
// meta required on purpose, because otherwise the added documentation would suppress warnings
macro_rules! wrap_method {
(
$prefix:ident :: $object_type:ty;
$(#[$meta:meta])+
$ref_or_mut:ident fn $function:ident($($param_name:ident: $param_type:ty),*)
$(-> $return_type:ty$(; |$it:ident | $return_expr:expr)?)?
$(; let $param_let_name:ident = $param_let_expr:expr)*
$(;)?
) => {
paste::paste! {
#[doc = concat!(" Calls [`servicepoint::", stringify!($object_type),
"::", stringify!($function), "`].")]
#[doc = ""]
$(#[$meta])*
#[no_mangle]
pub unsafe extern "C" fn [<$prefix _ $function>](
instance: NonNull<$object_type>,
$($param_name: $param_type),*
) $(-> $return_type)? {
let instance = unsafe { $crate::macros:: [< nonnull_as_ $ref_or_mut >] !(instance) };
$(let $param_let_name = $param_let_expr;)*
#[allow(
unused_variables,
reason = "This variable may not be used depending on macro variables" )]
let result = instance.$function($($param_name),*);
$(
$(
let $it = result;
let result = $return_expr;
)?
return result;
)?
}
}
};
}
macro_rules! wrap_fields {
(
$prefix:ident :: $object_type:ty;
$(
prop $prop_name:ident : $prop_type:ty {
$(
get() $({
$(#[$get_meta:meta])*
$(return $get_expr:expr;)?
})?;
)?
$(
set($value:ident)
$({
$(#[$set_meta:meta])*
$(return $set_expr:expr;)?
})?;
)?
};
)+
) => {
paste::paste! {
$(
$(
#[doc = concat!("Gets the value of field `", stringify!($prop_name),
"` of the [`servicepoint::",stringify!($object_type),"`].")]
$($(
#[doc = ""]
#[$get_meta]
)*)?
#[no_mangle]
pub unsafe extern "C" fn [<$prefix _ get _ $prop_name>](
instance: NonNull<$object_type>
) -> $prop_type {
let instance = unsafe { $crate::macros::nonnull_as_ref!(instance) };
let $prop_name = instance.$prop_name;
$($(
let $prop_name = $get_expr;
)?)?
return $prop_name;
}
)?
$(
#[doc = concat!("Sets the value of field `", stringify!($prop_name),
"` of the [`servicepoint::",stringify!($object_type),"`].")]
$($(
#[doc = ""]
#[$set_meta]
)*)?
#[no_mangle]
pub unsafe extern "C" fn [<$prefix _ set _ $prop_name>](
instance: NonNull<$object_type>,
value: $prop_type,
) {
let instance = unsafe { $crate::macros::nonnull_as_mut!(instance) };
$($(
let $value = value;
let value = $set_expr;
)?)?
instance.$prop_name = value;
}
)?
)+
}
};
}
pub(crate) use {
nonnull_as_mut, nonnull_as_ref, wrap_clone, wrap_fields, wrap_free,
wrap_method,
};