1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use quote::{quote,ToTokens};
use proc_macro2::{TokenStream,TokenTree};

fn copy_paste(ts: TokenStream) -> TokenStream {
   let mut os = TokenStream::new();

   for t in ts.into_iter() {
      match t {
         TokenTree::Group(_g) => {
            quote!().to_tokens(&mut os); 
         },
         TokenTree::Ident(_i) => {
            quote!().to_tokens(&mut os); 
         },
         TokenTree::Punct(p) => {
            quote!(
               let p = proc_macro2::Punct::new('!', proc_macro2::Spacing::Joint);
               s.append(p);
            ).to_tokens(&mut os); 
         }
         TokenTree::Literal(_l) => {
            quote!().to_tokens(&mut os); 
         }
      }
   }

   os
}

#[proc_macro]
pub fn quote_precise(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
   let input = TokenStream::from(input);

   let ts = copy_paste(input);

   let output = quote! {
      {
         let mut s = proc_macro2::TokenStream::new();
         #ts
         s
      }
   };

   proc_macro::TokenStream::from(output)
}