macro_rules! derive_free { ($typ:ident) => { ::paste::paste! { $crate::macros::wrap_method!($typ; #[doc = "Deallocates a [`" $typ "`] instance."] #[allow(dropping_copy_types)] fn free(move instance) { ::std::mem::drop(instance) }; ); } }; } macro_rules! derive_clone { ($object_type:ident) => { ::paste::paste! { $crate::macros::wrap_method!($object_type; #[doc = "Clones a [`" $object_type "`] instance."] fn clone(ref instance) -> move ::core::ptr::NonNull<$object_type> { instance.clone() }; ); } }; } macro_rules! wrap_method { ( $object_type:ident; $(#[$meta:meta])+ fn $function:ident($ref_or_mut:ident $instance:ident $(, $($param_name:ident: $param_modifier:ident $param_type:ty),*)?) $(-> $return_modifier:ident $return_type:ty)?; ) => { ::paste::paste!{ $crate::macros::wrap_method!( $object_type; $(#[$meta])+ fn $function($ref_or_mut $instance $(, $($param_name: $param_modifier $param_type),*)?) $(-> $return_modifier $return_type)? { $instance.$function($($($param_name),*)?) }; ); } }; ($object_type:ident; $(#[$meta:meta])+ fn $function:ident($ref_or_mut:ident $instance:ident $(, $($param_name:ident: $param_modifier:ident $param_type:ty),*)?) $(-> $return_modifier:ident $return_type:ty)? $impl:block; ) => { paste::paste! { $crate::macros::wrap_functions!([< $object_type:lower >]; #[doc = " Calls method [`servicepoint::" $object_type "::" $function "`]."] /// $(#[$meta])* fn $function( $instance: $ref_or_mut ::core::ptr::NonNull<$object_type> $(,$($param_name: $param_modifier $param_type),*)? ) $(-> $return_modifier $return_type)? $impl; ); } }; } macro_rules! wrap_methods { ( $object_type:ident; $( $(#[$meta:meta])+ fn $function:ident($ref_or_mut:ident $instance:ident $(, $($param_name:ident: $param_modifier:ident $param_type:ty),*)?) $(-> $return_modifier:ident $return_type:ty)? $($impl:block)?; )+ ) => { paste::paste! { $( $crate::macros::wrap_method!($object_type; $(#[$meta])* fn $function($ref_or_mut $instance $(, $($param_name: $param_modifier $param_type),*)?) $(-> $return_modifier $return_type)? $($impl)?; ); )+ } }; } macro_rules! wrap_fields_accessor { (get; $object_type:ident :: $prop_name:ident : $prop_type:ty) => { paste::paste! { $crate::macros::wrap_method! {$object_type; #[doc = " Gets the value of field `" $prop_name "` of the [`servicepoint::" $object_type "`]."] fn [](ref instance) -> val $prop_type { instance.$prop_name }; } } }; (mut get; $object_type:ident :: $prop_name:ident : $prop_type:ty) => { paste::paste! { $crate::macros::wrap_method! {$object_type; #[doc = " Gets a reference to the field `" $prop_name "` of the [`servicepoint::" $object_type "`]."] /// /// - The returned reference inherits the lifetime of object in which it is contained. /// - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command. fn [](mut instance) -> val ::core::ptr::NonNull<$prop_type> { ::core::ptr::NonNull::from(&mut instance.$prop_name) }; } } }; (set; $object_type:ident :: $prop_name:ident : $prop_type:ty) => { paste::paste! { $crate::macros::wrap_method! {$object_type; #[doc = " Sets the value of field `" $prop_name "` of the [`servicepoint::" $object_type "`]."] fn [](mut instance, value: val $prop_type) { instance.$prop_name = value; }; } } }; (move set; $object_type:ident :: $prop_name:ident : $prop_type:ty) => { paste::paste! { $crate::macros::wrap_method! {$object_type; #[doc = " Sets the value of field `" $prop_name "` of the [`servicepoint::" $object_type "`]."] /// The provided value is moved into the instance, potentially invalidating previously taken references. fn [](mut instance, value: move ::core::ptr::NonNull<$prop_type>) { instance.$prop_name = value; }; } } }; } macro_rules! wrap_fields { ( $object_type:ident; $( prop $prop_name:ident : $prop_type:ty { $($accessor:ident $($modifier:ident)?;)+ }; )+ ) => { $($( ::paste::paste!{ $crate::macros::wrap_fields_accessor! { $($modifier)? $accessor; $object_type :: $prop_name: $prop_type } } )+)+ }; } macro_rules! apply_param_modifier { (move, $param_name:ident) => { unsafe { $crate::mem::heap_remove($param_name) } }; (val, $param_name:ident) => { $param_name }; (mut, $param_name:ident) => { unsafe { (&mut *$param_name.as_ptr()) } }; (ref, $param_name:ident) => { unsafe { $param_name.as_ref() } }; (slice, $param_name:ident) => { unsafe { $param_name.as_slice() } }; } macro_rules! apply_return_modifier { (val, $result:ident) => { $result }; (move, $result:ident) => { $crate::mem::heap_move_nonnull($result) }; (move_ok, $result:ident) => { $crate::mem::heap_move_ok($result) }; (move_some, $result:ident) => { $crate::mem::heap_move_some($result) }; (slice, $result:ident) => { unsafe { ByteSlice::from_slice($result) } }; } macro_rules! wrap_function { ( $module:ident; $(#[$meta:meta])+ fn $function:ident($($param_name:ident: $param_modifier:ident $param_type:ty),*$(,)?) $(-> $return_modifier:ident $return_type:ty)? $block:block; ) => { ::paste::paste! { $(#[$meta])+ #[doc = ""] #[doc = " This function is part of the `" $module "` module."] #[no_mangle] pub unsafe extern "C" fn [< sp_ $module _ $function >]( $($param_name: $param_type),* ) $(-> $return_type)? { $( let $param_name = $crate::macros::apply_param_modifier!($param_modifier, $param_name); )* let result = $block; $( let result = $crate::macros::apply_return_modifier!($return_modifier, result); )? result } } }; } macro_rules! wrap_functions { ( $module:ident; $( $(#[$meta:meta])+ fn $function:ident($($param_name:ident: $param_modifier:ident $param_type:ty),*$(,)?) $(-> $return_modifier:ident $return_type:ty)? $block:block; )+ ) => { ::paste::paste! { $( $crate::macros::wrap_function!($module; $(#[$meta])+ fn $function($($param_name: $param_modifier $param_type),*) $(-> $return_modifier $return_type)? $block; ); )+ } }; ( associate $object_type:ident; $( $(#[$meta:meta])+ fn $function:ident($($param_name:ident: $param_modifier:ident $param_type:ty),*$(,)?) $(-> $return_modifier:ident $return_type:ty)? $block:block; )+ ) => { ::paste::paste! { $crate::macros::wrap_functions!{[< $object_type:lower >]; $( $(#[$meta])+ fn $function($($param_name: $param_modifier $param_type),*) $(-> $return_modifier $return_type)? $block; )+ } } }; } macro_rules! wrap { ( $object_type:ident { $( properties: $( prop $prop_name:ident : $prop_type:ty { $($accessor:ident $($modifier:ident)?;)+ }; )* )? $( functions: $( $(#[$fn_meta:meta])+ fn $fn_name:ident($($fn_param_name:ident: $fn_param_modifier:ident $fn_param_type:ty),*$(,)?) $(-> $fn_return_modifier:ident $fn_return_type:ty)? $fn_block:block; )* )? $( methods: $( $(#[$method_meta:meta])+ fn $method_name:ident($method_instance_modifier:ident $method_instance:ident $(, $($method_param_name:ident: $method_param_modifier:ident $method_param_type:ty),*)?) $(-> $method_return_modifier:ident $method_return_type:ty)? $($method_impl:block)?; )* )? } ) => { $($( $crate::macros::wrap_fields!($object_type; prop $prop_name : $prop_type { $($accessor $($modifier)?;)+ }; ); )*)? $($( $crate::macros::wrap_functions!(associate $object_type; $(#[$fn_meta])+ fn $fn_name($($fn_param_name: $fn_param_modifier $fn_param_type),*) $(-> $fn_return_modifier $fn_return_type)? $fn_block; ); )*)? $($( $crate::macros::wrap_method!($object_type; $(#[$method_meta])+ fn $method_name($method_instance_modifier $method_instance $(, $($method_param_name: $method_param_modifier $method_param_type),*)?) $(-> $method_return_modifier $method_return_type)? $($method_impl)?; ); )*)? }; } pub(crate) use { apply_param_modifier, apply_return_modifier, derive_clone, derive_free, wrap, wrap_fields, wrap_fields_accessor, wrap_function, wrap_functions, wrap_method, wrap_methods, };