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, };