Preamble for doc tests: doc(test(attr(...))) or another way?

tl;dr Any way to inject a line to all doctests in the same module, but without repeating that line, please?

I have a set of Rust files, one per doctest. I need to include them twice, where each doctest needs a (one line) preamble "injected" before the file content. Two preambles, one for the first set of includes, the other for the second. (The preambles are a macro invocation, with absolute ::crate_name:macro_name!(...), and the macro dos compile in the doctests if injected manually.)

I could just repeat the one line preamble for each doctest, like

/// ```
/// ::preamble_crate::preamble_macro!( args_for_this_doctest_set);
#[doc = include_str!("path/to/doctest_01.rs")]
/// ```

/// ```
/// ::preamble_crate::preamble_macro!( args_for_this_doctest_set);
#[doc = include_str!("path/to/doctest_02.rs")]
/// ```
pub const SOME_ITEM_TO_DOCUMENT: () = {};

And then the similar for the second doctest set.

But (especially to eliminate human copy-and-paste error), I've hoped to reuse that preamble macro invocation line with ![doc(test(attr(...)))], where I would put each doctest set in a separate submodule, apply ![doc(test(attr(doc ="::preamble_crate::preamble_macro!( args_for_this_doctest_set);"))))] to that submodule, and re-export the submodule.

However, ![doc(test(attr(doc ="...")))] does not inject that code to the doctest(s). Is there any to make it do so, or any other way of such a preamble re-use, please?

I do not think that you can inject code into every doctest, but what you can do is use a macro in the main crate, not the tests that produces the text you want to reduce the amount of repetition involved. Something like this (not tested):

macro_rules! include_with_preamble {
    ($file:literal) => {
        concat!(
            "```\n",
            "::preamble_crate::preamble_macro!( args_for_this_doctest_set);\n",
            include_str!($file),
            "\n```",
        )
    }
}

#[doc = include_with_preamble!("path/to/doctest_01.rs")]
#[doc = include_with_preamble!("path/to/doctest_02.rs")]
pub const SOME_ITEM_TO_DOCUMENT: () = {};
3 Likes

Wow, thank you. Your suggestion has an extra advantage that I didn't even hoped for: I can use it as an inner doc attribute #![doc = macro-here!(...)], so it becomes documentation at the crate level.

For anyone implementing something similar:

(It works, but not_re-published to crates.io and docs.rs as of writing this.)