Guest User

Untitled

a guest
Jan 23rd, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.44 KB | None | 0 0
  1. extern crate quote; // 0.6.10
  2. extern crate proc_macro2; // 0.4.24
  3. use quote::quote;
  4. use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span};
  5. use quote::{ToTokens, TokenStreamExt};
  6.  
  7. #[derive(Debug)]
  8. pub struct Datum(pub u8);
  9. #[derive(Debug)]
  10. pub struct Data(pub Vec<Datum>);
  11.  
  12. // Taks: Implement quote::ToTokens for Data
  13.  
  14. impl ToTokens for Datum {
  15. fn to_tokens(&self, stream: &mut proc_macro2::TokenStream) {
  16. stream.append(Ident::new("Datum", Span::call_site()));
  17. let mut val_stream = proc_macro2::TokenStream::new();
  18. self.0.to_tokens(&mut val_stream);
  19. stream.append(Group::new(Delimiter::Parenthesis, val_stream));
  20. }
  21. }
  22.  
  23. impl ToTokens for Data {
  24. fn to_tokens(&self, stream: &mut proc_macro2::TokenStream) {
  25. // target: Data( <[Datum]>::into_vec(Box::new([ (d.to_tokens ,)* ])) )
  26. let mut body_stream = proc_macro2::TokenStream::new();
  27. let mut vec_op_stream = proc_macro2::TokenStream::new();
  28. vec_op_stream.append(Punct::new('<', Spacing::Alone));
  29. let mut datum_type_stream = proc_macro2::TokenStream::new();
  30. datum_type_stream.append(Ident::new("Datum", Span::call_site()));
  31. vec_op_stream.append(Group::new(Delimiter::Bracket, datum_type_stream));
  32. vec_op_stream.append(Punct::new('>', Spacing::Alone));
  33. // done: vec_op_stream = <[datum_type_stream]> = <[Datum]>
  34. body_stream.append(Group::new(Delimiter::None, vec_op_stream));
  35. body_stream.append(Punct::new(':', Spacing::Joint));
  36. body_stream.append(Punct::new(':', Spacing::Alone));
  37. body_stream.append(Ident::new("into_vec", Span::call_site()));
  38. // done: body_stream = vec_op_stream::into_vec = <[Datum]>::into_vec
  39. let mut box_stream = proc_macro2::TokenStream::new();
  40. box_stream.append(Ident::new("Box", Span::call_site()));
  41. box_stream.append(Punct::new(':', Spacing::Joint));
  42. box_stream.append(Punct::new(':', Spacing::Alone));
  43. box_stream.append(Ident::new("new", Span::call_site()));
  44. // done: box_stream = Box::new
  45. let mut vec_arg_stream = proc_macro2::TokenStream::new();
  46. let mut arg_array_stream = proc_macro2::TokenStream::new();
  47. for (i, d) in self.0.iter().enumerate() {
  48. if i > 0 {
  49. arg_array_stream.append(Punct::new(',', Spacing::Alone));
  50. }
  51. d.to_tokens(&mut arg_array_stream);
  52. }
  53. vec_arg_stream.append(Group::new(Delimiter::Bracket, arg_array_stream));
  54. // done: vec_arg_stream = [arg_array_stream] = [ (d.to_tokens ,)* ]
  55. box_stream.append(Group::new(Delimiter::Parenthesis, vec_arg_stream));
  56. // done: box_stream = Box::new (vec_arg_stream) = Box::new([ (d.to_tokens ,)* ])
  57. body_stream.append(Group::new(Delimiter::Parenthesis, box_stream));
  58. // done: body_stream = vec_op_stream::into_vec(box_stream) = <[Datum]>::into_vec(Box::new([ (d.to_tokens ,)* ]))
  59.  
  60. stream.append(Ident::new("Data", Span::call_site()));
  61. let group = Group::new(Delimiter::Parenthesis, body_stream);
  62. stream.append(group);
  63. // done: stream = Data(body_stream) = Data( <[Datum]>::into_vec(Box::new([ (d.to_tokens ,)* ])) )
  64. }
  65. }
  66.  
  67. fn main() {
  68. let d : Data = Data(vec![Datum(2),Datum(4),Datum(6)]);
  69. println!("initial data: {:?}", d);
  70. println!();
  71. let quoted = quote!(#d);
  72.  
  73. println!("quoted display of .to_tokens(): {}", quoted);
  74. println!();
  75. // assuming this is printed, is it valid?
  76. let recovered : Data = Data ( < [ Datum ] > :: into_vec ( Box :: new ( [ Datum ( 2u8 ) , Datum ( 4u8 ) , Datum ( 6u8 ) ] ) ) );
  77. println!("recovered data: {:?}", recovered);
  78.  
  79. }
Add Comment
Please, Sign In to add comment