Macro safer_ffi::ReprC [−][src]
macro_rules! ReprC { ( $( @[doc = $doc:expr] )? $(#[doc = $prev_doc:tt])* // support doc comments _before_ `#[repr(C)]` #[repr(C)] $(#[$($meta:tt)*])* $pub:vis struct $StructName:ident $( [ $($lt:lifetime ,)* $($($generics:ident),+ $(,)?)? ] $(where { $($bounds:tt)* })? )? { $( $(#[$($field_meta:tt)*])* $field_pub:vis $field_name:ident : $field_ty:ty ),+ $(,)? } ) => { ... }; ( $( @[doc = $doc:expr] )? $(#[doc = $prev_doc:tt])* #[repr(transparent)] $(#[$meta:meta])* $pub:vis struct $StructName:ident $( [$($generics:tt)*] $( where { $($bounds:tt)* } )? )? ( $(#[$field_meta:meta])* $field_pub:vis $field_ty:ty $(, $($rest:tt)* )? ); ) => { ... }; ( $(#[doc = $prev_doc:tt])* #[repr($Int:ident)] $(#[$($meta:tt)*])* $pub:vis enum $EnumName:ident { $( $($(#[doc = $variant_doc:expr])+)? // $(#[$variant_meta:meta])* $Variant:ident $(= $discriminant:expr)? ),+ $(,)? } ) => { ... }; ( $(#[doc = $prev_doc:tt])* #[repr(C $(, $Int:ident)?)] $(#[$meta:meta])* $pub:vis enum $EnumName:ident { $($variants:tt)* } ) => { ... }; ( $(#[doc = $prev_doc:tt])* #[ ReprC :: opaque $( ( $($c_name:expr)? ) )? ] $(#[$meta:meta])* $pub:vis struct $StructName:ident $( [ $($lt:lifetime ,)* $($($generics:ident),+ $(,)?)? ] $(where { $($bounds:tt)* })? )? { $($opaque:tt)* } ) => { ... }; (@validate_int_repr u8) => { ... }; (@validate_int_repr u16) => { ... }; (@validate_int_repr u32) => { ... }; (@validate_int_repr u64) => { ... }; (@validate_int_repr u128) => { ... }; (@validate_int_repr i8) => { ... }; (@validate_int_repr i16) => { ... }; (@validate_int_repr i32) => { ... }; (@validate_int_repr i64) => { ... }; (@validate_int_repr i128) => { ... }; (@deny_C C) => { ... }; (@deny_C c_int) => { ... }; (@deny_C c_uint) => { ... }; (@deny_C $otherwise:tt) => { ... }; (@first ($($fst:tt)*) $($ignored:tt)*) => { ... }; }
Expand description
Safely implement ReprC
for a #[repr(C)]
struct when all its fields are ReprC
.
Syntax
Note: given that this macro is implemented as a macro_rules!
macro for
the sake of compilation speed, it cannot parse arbitrary generic parameters
and where clauses.
Instead, it expects a special syntax whereby the generic parameters are
written between square brackets, and only introduce lifetime
parameters
and type parameters, with no bounds whatsoever (and a necessary trailing
comma for the lifetime parameters); the bounds must all be added to the
optional following where { <where clauses here> }
(note the necessary
braces):
-
Instead of:
ⓘuse ::safer_ffi::layout::ReprC; ReprC! { #[repr(C)] struct GenericStruct<'lifetime, T : 'lifetime> where T : ReprC, { inner: &'lifetime T, } }
-
You need to write:
use ::safer_ffi::layout::ReprC; ReprC! { #[repr(C)] struct GenericStruct['lifetime, T] where { T : 'lifetime + ReprC, } { inner: &'lifetime T, } }
#[derive_ReprC]
If all this looks cumbersome to you, and if you don’t care about the
compilation-from-scratch time, then it is highly advised you enable
the proc_macros
feature:
[dependencies]
safer-ffi = { version = "...", features = ["proc_macros"] }
and use the #[derive_ReprC]
attribute macro instead,
which will do the rewriting for you.