1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
mod headeritem;
mod item;
mod snippet;
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
/// Generate C header content from the included docstring.
///
/// This macro operates much like `#[ffizz_header::item]`, but can be applied when there is no Rust
/// item to document. The `#[ffizz(name="..")]` attribute must always be supplied, and order is
/// usually supplied as well.
///
/// # Example
///
/// ```text
/// # ignored because ffizz_header isn't available in doctests
/// ffizz_header::snippet! {
/// #[ffizz(name="invariants", order=10)]
/// /// LIBRARY INVARIANTS
/// ///
/// /// This library maintains the following invariants:
/// /// * what goes up, must come down
/// }
/// ```
///
/// produces
///
/// ```text
/// // LIBRARY INVARIANTS
/// //
/// // This library maintains the following invariants:
/// // * what goes up, must come down
/// ```
#[proc_macro]
pub fn snippet(item: TokenStream) -> TokenStream {
let snip = syn::parse_macro_input!(item as snippet::Snippet);
let mut tokens = TokenStream2::new();
snip.to_tokens(&mut tokens);
tokens.into()
}
/// Generate C header content from the docstring on this item.
///
/// # Docstring Parsing
///
/// The generated C header content contains C-style comments with the content of the Rust
/// docstring.
///
/// Any blocks delimited by triple-backticks with the `c` type will be included in the header as C
/// code. This should give the C declaration for the Rust item.
///
/// # Ordering
///
/// The header file is generated by concatenating the content supplied by this macro any by
/// `ffizz_header::snippet!`. Each piece of content has "order" and "name" properties, and these
/// are used to sort the content in the header file. The name must also be unique within the
/// resulting library. The "order" property defaults to `100` and "name" defaults to the name of
/// the Rust item. Both can be overridden with a `ffizz` attribute:
///
/// ```text
/// #[ffizz(name="FOO_free")]
/// #[ffizz(order=200)]
/// #[ffizz(name="FOO_free", order=200)]
/// ```
///
/// # Example
///
/// ```text
/// #[ffizz_header::item]
/// /// Free a foo_t. The given foo_t must not be used after this
/// /// call.
/// ///
/// /// ```c
/// /// void foo_free(*foo_t);
/// /// ```
/// pub unsafe extern "C" fn foo_free(*mut foo_t) { .. }
/// ```
///
/// produces
///
/// ```text
/// // Free a foo_t. The given foo_t must not be used after this
/// // call.
/// void foo_free(*foo_t);
/// ```
#[proc_macro_attribute]
pub fn item(_attr: TokenStream, item: TokenStream) -> TokenStream {
let docitem = syn::parse_macro_input!(item as item::DocItem);
let mut tokens = TokenStream2::new();
docitem.to_tokens(&mut tokens);
tokens.into()
}