Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extern crate quote; // 0.6.10
- extern crate proc_macro2; // 0.4.24
- use quote::quote;
- use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span};
- use quote::{ToTokens, TokenStreamExt};
- #[derive(Debug)]
- pub struct Datum(pub u8);
- #[derive(Debug)]
- pub struct Data(pub Vec<Datum>);
- // Taks: Implement quote::ToTokens for Data
- impl ToTokens for Datum {
- fn to_tokens(&self, stream: &mut proc_macro2::TokenStream) {
- stream.append(Ident::new("Datum", Span::call_site()));
- let mut val_stream = proc_macro2::TokenStream::new();
- self.0.to_tokens(&mut val_stream);
- stream.append(Group::new(Delimiter::Parenthesis, val_stream));
- }
- }
- impl ToTokens for Data {
- fn to_tokens(&self, stream: &mut proc_macro2::TokenStream) {
- // target: Data( <[Datum]>::into_vec(Box::new([ (d.to_tokens ,)* ])) )
- let mut body_stream = proc_macro2::TokenStream::new();
- let mut vec_op_stream = proc_macro2::TokenStream::new();
- vec_op_stream.append(Punct::new('<', Spacing::Alone));
- let mut datum_type_stream = proc_macro2::TokenStream::new();
- datum_type_stream.append(Ident::new("Datum", Span::call_site()));
- vec_op_stream.append(Group::new(Delimiter::Bracket, datum_type_stream));
- vec_op_stream.append(Punct::new('>', Spacing::Alone));
- // done: vec_op_stream = <[datum_type_stream]> = <[Datum]>
- body_stream.append(Group::new(Delimiter::None, vec_op_stream));
- body_stream.append(Punct::new(':', Spacing::Joint));
- body_stream.append(Punct::new(':', Spacing::Alone));
- body_stream.append(Ident::new("into_vec", Span::call_site()));
- // done: body_stream = vec_op_stream::into_vec = <[Datum]>::into_vec
- let mut box_stream = proc_macro2::TokenStream::new();
- box_stream.append(Ident::new("Box", Span::call_site()));
- box_stream.append(Punct::new(':', Spacing::Joint));
- box_stream.append(Punct::new(':', Spacing::Alone));
- box_stream.append(Ident::new("new", Span::call_site()));
- // done: box_stream = Box::new
- let mut vec_arg_stream = proc_macro2::TokenStream::new();
- let mut arg_array_stream = proc_macro2::TokenStream::new();
- for (i, d) in self.0.iter().enumerate() {
- if i > 0 {
- arg_array_stream.append(Punct::new(',', Spacing::Alone));
- }
- d.to_tokens(&mut arg_array_stream);
- }
- vec_arg_stream.append(Group::new(Delimiter::Bracket, arg_array_stream));
- // done: vec_arg_stream = [arg_array_stream] = [ (d.to_tokens ,)* ]
- box_stream.append(Group::new(Delimiter::Parenthesis, vec_arg_stream));
- // done: box_stream = Box::new (vec_arg_stream) = Box::new([ (d.to_tokens ,)* ])
- body_stream.append(Group::new(Delimiter::Parenthesis, box_stream));
- // done: body_stream = vec_op_stream::into_vec(box_stream) = <[Datum]>::into_vec(Box::new([ (d.to_tokens ,)* ]))
- stream.append(Ident::new("Data", Span::call_site()));
- let group = Group::new(Delimiter::Parenthesis, body_stream);
- stream.append(group);
- // done: stream = Data(body_stream) = Data( <[Datum]>::into_vec(Box::new([ (d.to_tokens ,)* ])) )
- }
- }
- fn main() {
- let d : Data = Data(vec![Datum(2),Datum(4),Datum(6)]);
- println!("initial data: {:?}", d);
- println!();
- let quoted = quote!(#d);
- println!("quoted display of .to_tokens(): {}", quoted);
- println!();
- // assuming this is printed, is it valid?
- let recovered : Data = Data ( < [ Datum ] > :: into_vec ( Box :: new ( [ Datum ( 2u8 ) , Datum ( 4u8 ) , Datum ( 6u8 ) ] ) ) );
- println!("recovered data: {:?}", recovered);
- }
Add Comment
Please, Sign In to add comment