Prevent line break in doc test

Viewed 176

I am trying to write a doc test for a struct member function created by a macro. Apparently it is only possible to use a capture in a standalone doc attribute. However, this forces a line break in the doc test so that the capture fills an entire line in the rendered result. Is this a way to prevent line breaks or to use the capture directly without using procedural macros?

#[macro_export]
macro_rules! gen_functions {
    ($name:tt) => {
        /// # Usage
        /// 
        /// ```
        /// let h = 
        #[doc = $name]
        ///  {};
        /// h.test_a();
        /// ```
        pub fn test_a(&self) {
            println!("test a")
        }
    };
}

pub struct CustomStruct {}
impl CustomStruct {
    gen_functions!("CustomStruct");
}

fn main() {
    let h = CustomStruct {};
    h.test_a();
}

And the resulting doc test. It does compile but it is difficult to read (compared to the version in the main function):

let h = 
CustomStruct
{};
h.test_a();
1 Answers

Someone showed me a nice solution on this internals thread, which uses a macro. I adjusted the macro to make it nicer to use.

Usage:

macro_rules! gen_functions {
    ($name:tt) => {
        doc! {
            /// # Usage
            ///
            /// ```
            [concat!(" let h = ", $name, " {};")]
            /// h.test_a();
            /// ```
            @ pub fn test_a(&self) {
                println!("test a")
            }
        }
    };
}

And this is the macro:

macro_rules! doc {
    {
        $(#[$m:meta])*
        $(
            [$doc:expr]
            $(#[$n:meta])*
        )*
        @ $thing:item
    } => {
        $(#[$m])*
        $(
            #[doc = $doc]
            $(#[$n])*
        )*
        $thing
    }
}

The macro converts strings in [square brackets] into #[doc = _] attributes. What makes it special is that it can contain concat! and stringify! macro calls. They can also be combined, e.g.

doc! {
    /// # Usage
    ///
    /// ```
    [concat!(" let ", stringify!(h), " = ", stringify!(CustomStruct), " {};")]
    /// h.test_a();
    /// ```
    @ pub fn test_a(&self) {
        println!("test a")
    }
}
Related