324 lines
11 KiB
Rust
324 lines
11 KiB
Rust
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 [<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: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,
|
|
};
|