servicepoint_binding_c 0.15.0

C bindings for the servicepoint crate.
Documentation
macro_rules! derive_free {
    ($object_type:ident) => {
        $crate::macros::wrap_method!($object_type;
            #[doc = concat!("Deallocates a [`", stringify!($object_type), "`] instance.")]
            #[allow(dropping_copy_types)]
            fn free(move instance) {
                ::std::mem::drop(instance)
            };
        );
    };
}

macro_rules! derive_clone {
    ($object_type:ident) => {
        $crate::macros::wrap_method!($object_type;
            #[doc = concat!("Clones a [`", stringify!($object_type), "`] instance.")]
            fn clone(ref instance) -> move ::core::ptr::NonNull<$object_type>;
        );
    };
}

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;
                #[doc = " Calls method [`" $object_type "::" $function "`]."]
                ///
                $(#[$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!(associate $object_type;
                $(#[$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 [<get _ $prop_name>](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 [<get _ $prop_name _mut>](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 [<set _ $prop_name>](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 [<set _ $prop_name>](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:snake >];
                $(
                    $(#[$meta])+
                    fn $function($($param_name: $param_modifier $param_type),*) $(-> $return_modifier $return_type)?
                    $block;
                )+
            }
        }
    };
}

macro_rules! wrap {
    (
        $object_type:ident {
            $(
                derives:
                $(
                    $derive:path $( [ $( $derive_arg:tt ),+ ] )?
                ),+;
            )?
            $(
                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)?;
                )*
            )?
        }
    ) => {
        $($(
            $derive!($object_type $(, $($derive_arg),+)?);
        )+)?
        $($(
            $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,
};