Can I define a const identifier for a derive macro?

I'm writing a derive macro for my lib, and I read that I should output fully qualified names, to avoid clashes, so my code if full of things like:

quote! {
	::my_lib::Result<::my_lib::some::long::path::Wrapper<T>> 
}

These types are repeated a lot.
Can I somehow store these fully qualified names in variables, to reuse them ?

let wrapper: Ident = parse_quote! {::my_lib::some::long::path::Wrapper};

(but global). I tried lazy_static and const without success.

How about a function that returns an Ident?

But then I can't just call a function in quote, I think:

quote! {
	#my_result()<#my_wrapper()<T>> 
}

but have to assign intermediate variables:

let my_result = my_result();
let my_wrapper = my_wrapper();
quote! {
	#my_result<#my_wrapper<T>> 
}

which works for not repeating the full names, but is still a bit too verbose.
(I am assuming that if there was a global/const, I could just refer to it in quote!, but I'm not sure).

I came up with a satisfactory (though hacky feeling) solution:

pub struct TokensGenerator {
    pub f: &'static dyn Fn() -> TokenStream,
}
impl ToTokens for TokensGenerator {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        tokens.extend((self.f)())
    }
}


pub const FOO: TokensGenerator = TokensGenerator { f: &|| quote! { ::mylib::things::Foo } };
pub const RESULT: TokensGenerator = TokensGenerator { f: &|| quote! { ::mylib::error::Result } };

And then I can just use the constants directly:

quote! {
    fn doit() -> #RESULT<#FOO> {
        ....
    }
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.