dtolnay / quote

Rust quasi-quoting
Apache License 2.0
1.32k stars 90 forks source link

[question] comparing doc comments in unit tests #189

Closed danieleades closed 2 years ago

danieleades commented 3 years ago

Hi there, hoping for some assistance!

I'm writing unit tests for a derive macro, and having a bit of trouble.

My derive macro generates setters for fields in a struct, and preserves the doc comments on the fields as doc comments on the setters.

i'm parsing the original doc comment into a string, and then generating an attribute from that string like so-

pub fn doc_attribute(doc: &str) -> Option<Attribute> {
    let parser = Attribute::parse_outer;
    let tokens = quote! {
        #[doc = #doc]
    };
    Some(parser.parse2(tokens).unwrap().into_iter().next().unwrap())
}

that seems to work. the problem comes when i try to compare it to output generated from the following-

let expected_tokens = quote! {
    impl Basic {
        /// This has a comment
        fn a(mut self, a: u32) -> Self {
            self.a = a;
            self
        }
    }
};

the doc attribute parsed from the second example is of the form #[doc = r"<comment>", whereas the doc comment produced from the first example is of the form #[doc = "<comment>" (a regular string literal, as opposed to a raw string literal). This makes comparisons in unit test a little tricky. Where am I going wrong? How can i construct a doc comment attribute with a raw string literal?

dtolnay commented 3 years ago

Moved to quote repo because this is fundamentally about quote! { #[doc = #doc] } vs quote! { /// ... } which has nothing to do with syn.

You can control the exact formatting of the string literal token this way:

use proc_macro2::Literal;

let doc = format!("r{:?}", doc).parse::<Literal>().unwrap();
quote! { #[doc = #doc] }