Search code examples
macrosrustdocumentationrust-macrosrustdoc

How do I add examples to macro documentation in rust?


When writing a macro, I would like to document it proprerly, and this includes examples.
But when I try to do that in the same way as a regular function I get:

[E0468]: an `extern crate` loading macros must be at the crate root 

I run cargo test on nightly to test the following:

// src/lib.rs in crate with name advent9

/// this macro essentialy appends .as_bytes()
/// `b!("bla")` -> `"bla".as_bytes()`
///
/// # Examples
/// ```
/// #[macro_use]
/// extern crate advent9;
///
/// let bytes : &[u8] = b!("this is a bytestring");
///
/// println!("{:?}", bytes);
/// // prints:
/// // [116, 104, 105, 115, 32, 105, 115, 32, 97, 32, 98, 121, 116, 101, 115, 116, 114, 105, 110, 103]
/// ```
// I don't need this exported, but perhaps the example does?
#[macro_export] 
macro_rules! b {
    ($string:expr) => {
        $string.as_bytes()
    }

My understanding of the doctests is that each gets wrapped in their own main function. Like this:

fn main() {
    #[macro_use]
    extern crate advent9;

    let bytes : &[u8] = b!("this is a bytestring");

    println!("{:?}", bytes);
    // prints:
    // [116, 104, 105, 115, 32, 105, 115, 32, 97, 32, 98, 121, 116, 101, 115, 116, 114, 105, 110, 103]
}

If this is correct, it would explain the error.

Is there any way to actually add examples to macros?


Solution

  • It is possible, though a bit convoluted; you need to do it in the following way:

    /// # Example
    /// ```
    /// # #[macro_use] extern crate crate_name;
    /// # fn main() {
    /// use crate_name::module::object;
    ///
    /// <example code>
    /// # }
    /// ```
    #[macro_export]
    macro_rules! some_macro {
        <macro code>
    }