In my proc macro I want to use imports (including standard library, 3rd party library and my own functions etc) inside quote!
, but seems like quote!
not allow me to do this when I use import within macro file like below:
// here is import I want to use in quote!
use std::io::Cursor;
use proc_macro::{TokenStream};
use proc_macro2::Ident;
use quote::{quote, format_ident};
use paste::paste;
use syn::{parse_macro_input, DeriveInput, ItemStruct, Token, punctuated::Punctuated, NestedMeta};
#[proc_macro_derive(Packet, attributes(dynamic_field))]
pub fn derive(input: TokenStream) -> TokenStream {
let ItemStruct { ident, fields, .. } = parse_macro_input!(input);
let field_data = fields.iter().filter_map(|f| {
let ident = f.ident.clone().unwrap().to_string();
let field_type = f.ty.clone();
let ident = format_ident!("{}", f.ident.as_ref().unwrap());
if f.attrs.iter().any(|attr| attr.path.is_ident("dynamic_field")) {
Some(quote! { Self::#ident(); })
} else {
None
}
}).collect::<Vec<_>>();
let fields_names = fields.iter().map(|f| {
f.ident.clone()
}).collect::<Vec<_>>();
let value = quote!(1);
let output = quote! {
impl #ident {
pub fn from_binary(buffer: &Vec<u8>) -> Self {
// here is Cursor that I imported before
let reader = Cursor::new(buffer);
// ...
Self {
#(#fields_names: Default::default()),*
}
}
}
};
TokenStream::from(output)
}
on compile the error is:
error[E0433]: failed to resolve: use of undeclared type `Cursor`
--> src\main.rs:6:10
|
6 | #[derive(Packet, Debug)]
| ^^^^^^ use of undeclared type `Cursor`
|
= note: this error originates in the derive macro `Packet` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider importing one of these items
|
4 | use std::collections::linked_list::Cursor;
|
4 | use std::io::Cursor;
but when I do same import in file (in my case main.rs) where I use #[derive(Packet)]
, all works OK:
// this import helps
use std::io::Cursor;
use my_proc_macros_lib::Packet;
#[derive(Packet, Debug)]
struct Test {
#[dynamic_field]
size: u8,
#[dynamic_field]
size1: u16,
#[dynamic_field]
size2: u32,
#[dynamic_field]
field2: u64,
field3: u8,
}
impl Test {
// ...
}
fn main() {
Test::debug();
let test = Test::from_binary(&vec![]);
println!("{:?}", test);
}
Could somebody explain how to correctly manage the imports in this case ? I am not sure it's good way to import all outside the macro.