I want to add some syn::Ident
's to form a &'static str
. All Ident
s should be concat to form a comma separated and stringified (because that's how I get a string representation of an Ident
) &'static str
.
I got a non-working project here: https://github.com/Jasperav/comma_separated (inside the example
folder there is a failing test).
This is my test:
#[test]
fn test_another_struct() {
assert_eq!("name, another_name", AnotherStruct::useless())
}
It fails because of this:
Expected :nameanother_name Actual :name, another_name
This is my code trying to generated the comma separated list (inside lib.rs
):
let idents = vec![
syn::Ident::new("name", Span::call_site()),
syn::Ident::new("another_name", Span::call_site())
];
proc_macro::TokenStream::from(quote! {
impl #struct_name {
fn useless() -> &'static str {
concat!(#(stringify!(#idents)),*)
}
}
})
I don't understand why it's not working. There is 1 ,
in my macro, that means: separate everything with a comma right?
If you cargo expand
your code, you would realize you expanded into this:
(suppose struct_name
is Foo
)
impl Foo {
fn useless() -> &'static str {
concat!(stringify!(name), stringify!(another_name))
}
}
stringify!
converts the ident into string directly,
so the returned value is equivalent to
concat!("name", "another_name")
Here, comma is a separator for the syntax, not a string literal,
so you end up getting nameanother_name
.
Only considering your code above, the most convenient fix is to formulate the raw string inside proc_macro code
instead of relying on stringify!
and concat!
,
allowing you to use APIs like slice::join
.