Skip to content

Instantly share code, notes, and snippets.

@peanutbother
Last active March 31, 2023 20:29
Show Gist options
  • Save peanutbother/d9e6dbdc5fcb794934e55f42d0e57e4f to your computer and use it in GitHub Desktop.
Save peanutbother/d9e6dbdc5fcb794934e55f42d0e57e4f to your computer and use it in GitHub Desktop.
Rustdoc proc_macro_attribute which adds boilerplate for a doctest
/// This struct shows an example
///
/// # Example
#[doc_add_boilerplate(
/// # // you can use hidden lines
/// MyStruct::greet(); // this line is visible
)]
struct MyStruct;
#[proc_macro_attribute]
/// Attribute macro which generates a doc test wrapper to reduce boilerplate.
///
/// # Example
///
/// ```rust
///
/// /// Your documentation about the struct
/// /// ...
/// /// # Example
/// #[doc_add_boilerplate(
/// /// MyStruct::may_fail()?;
/// )]
/// struct MyStruct;
/// ```
///
/// This will generate a doc with the following content:
/// ```rust
/// /// Your documentation about the struct
/// /// ...
/// /// # Example
/// /// ```rust
/// /// # #[tokio::main]
/// /// # async fn main() -> Result<(), Box<dyn std::error::Errror + Send + Sync>> {
/// /// MyStruct::may_fail()?;
/// /// # Ok(())
/// /// # }
/// /// ```
pub fn doc_add_boilerplate(attr: TokenStream, input: TokenStream) -> TokenStream {
let inner: proc_macro2::TokenStream = attr.into();
let parser = |input: ParseStream<'_>| ::syn::Result::Ok({
let attrs = Attribute::parse_outer(input)?;
let rest = input.parse::<TokenStream>().unwrap();
(attrs, rest)
});
let (meta, input) = parse_macro_input!(input with parser);
quote_spanned!(Span::mixed_site()=>
#(#meta)*
/// ```rust
/// # #[tokio::main]
/// # async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
#inner
/// # Ok(())
/// # }
///
#input
).into()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment