3

Is there a way to match doccomments in Rust's macro_rules?

I have a macro that generates an enum for a bunch of C constants that bindgen creates:

macro_rules! id_enum {
    ( enum $name:ident: $typ:ty { $( $enum_name:ident => $value:expr ),* , } ) => { ... }
}

I'd like to annotate each with a doc comment (a /// comment), but that requires that my macro match the doc comments. Is that possible?

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85

1 Answers1

6

Doc comments are translated to attributes of the form

#[doc = "documentation text"]

and can be matched in their translated form:

macro_rules! print_doc {
    (#[doc = $doc:expr]) => {
        pub fn foo() {
            println!($doc);
        }
    }
}

print_doc!(
    /// gloink
);

fn main() {
    foo();
}

If you want to emit the doc comment in modified form, you need to use the attribute syntax inside your macro, as explained in this answer:

To concatenate the original doc comment with your annotation, you can use the macro concat!() from the standard library. However, macro calls are not allowed inside attributes, so you need a helper macro, e.g.

macro_rules! annotated_func {
    ($doc:expr) => {
        #[doc = $doc]
        pub fn foo() {
            println!($doc);
        }
    }
}

macro_rules! print_doc {
    (#[doc = $doc:expr]) => {
        annotated_func!(concat!($doc, "\nannotation"));
    }
}
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841