ontio_derive_codec/
lib.rs

1#![recursion_limit = "256"]
2#![feature(proc_macro_hygiene)]
3
4extern crate proc_macro;
5use heck::MixedCase;
6use proc_macro::TokenStream;
7use quote::quote;
8use syn::{Data, DataEnum, DataStruct, Fields};
9
10#[proc_macro_derive(Encoder)]
11pub fn derive_encoder(item: TokenStream) -> TokenStream {
12    let ast: syn::DeriveInput = syn::parse(item).unwrap();
13    let name = &ast.ident; //struct name
14    let expanded: proc_macro2::TokenStream = match ast.data {
15        Data::Enum(DataEnum { ref variants, .. }) => {
16            let get_selfs: Vec<_> = variants
17                .iter()
18                .map(|variant| {
19                    let field_name = &variant.ident; // 字段名字
20                    quote! {
21                        #field_name
22                    }
23                })
24                .collect();
25            let implemented_encoder = quote! {
26                  impl ontio_std::abi::Encoder for #name {
27                    fn encode(&self, sink: &mut ontio_std::abi::Sink) {
28                         match self {
29                             #(#name::#get_selfs(temp) => {
30                                sink.write(stringify!(#get_selfs));
31                                sink.write(temp);
32                             }), *
33                         }
34                    }
35                  }
36            };
37            implemented_encoder
38        }
39        Data::Struct(DataStruct { ref fields, .. }) => {
40            if let Fields::Named(ref fields_name) = fields {
41                let get_selfs: Vec<_> = fields_name
42                    .named
43                    .iter()
44                    .map(|field| {
45                        let field_name = field.ident.as_ref().unwrap(); // 字段名字
46                        quote! {
47                            &self.#field_name
48                        }
49                    })
50                    .collect();
51                let implemented_encoder = quote! {
52                    impl ontio_std::abi::Encoder for #name {
53                        fn encode(&self, sink: &mut ontio_std::abi::Sink) {
54                             sink.write((#(#get_selfs),*));
55                        }
56                    }
57                };
58                implemented_encoder
59            } else {
60                panic!("not struct");
61            }
62        }
63        _ => panic!("not support"),
64    };
65    expanded.into()
66}
67
68#[proc_macro_derive(Decoder)]
69pub fn derive_decoder(item: TokenStream) -> TokenStream {
70    let ast: syn::DeriveInput = syn::parse(item).unwrap();
71    let name = &ast.ident; //struct name
72    let expanded: proc_macro2::TokenStream = match ast.data {
73        Data::Enum(DataEnum { ref variants, .. }) => {
74            let get_selfs: Vec<_> = variants
75                .iter()
76                .map(|variant| {
77                    let field_name = &variant.ident; // 字段名字
78                    let match_name =
79                        syn::Ident::new(&field_name.to_string().to_mixed_case(), field_name.span());
80                    quote! {
81                        #match_name
82                    }
83                })
84                .collect();
85
86            let get_selfs2: Vec<_> = variants
87                .iter()
88                .map(|variant| {
89                    let field_name = &variant.ident; // 字段名字
90                    quote! {
91                        #field_name
92                    }
93                })
94                .collect();
95
96            let implemented_decoder = quote! {
97                impl<'a> ontio_std::abi::Decoder<'a> for #name {
98                    fn decode(source: &mut ontio_std::abi::Source<'a>) -> Result<Self,
99                    ontio_std::abi::Error> {
100                    let ty:&str= source.read()?;
101                        match ty {
102                             #(stringify!(#get_selfs) => {
103                                let temp = source.read()?;
104                                Ok(#name::#get_selfs2(temp))
105                             }),*
106                             _ => {
107                             panic!("decoder not support:{}", ty)
108                             }
109                        }
110                    }
111                }
112            };
113            implemented_decoder
114        }
115        Data::Struct(DataStruct { ref fields, .. }) => {
116            if let Fields::Named(ref fields_name) = fields {
117                let get_selfs: Vec<_> = fields_name
118                    .named
119                    .iter()
120                    .map(|field| {
121                        let field_name = field.ident.as_ref().unwrap(); // 字段名字
122                        quote! {
123                            #field_name
124                        }
125                    })
126                    .collect();
127                let implemented_decoder = quote! {
128                    impl<'a> ontio_std::abi::Decoder<'a> for #name {
129                        fn decode(source: &mut ontio_std::abi::Source) -> Result<Self,
130                        ontio_std::abi::Error> {
131                            return Ok(#name {
132                            #(#get_selfs: source.read()?),*
133                            })
134                        }
135                    }
136                };
137                implemented_decoder
138            } else {
139                panic!("not struct");
140            }
141        }
142        _ => panic!("not support"),
143    };
144
145    expanded.into()
146}