sboo
October 22, 2022, 8:26am
1
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.
alice
October 22, 2022, 8:52am
2
How about a function that returns an Ident
?
sboo
October 22, 2022, 12:28pm
3
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).
sboo
November 25, 2022, 6:09am
4
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> {
....
}
}
system
Closed
February 23, 2023, 6:09am
5
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.