ontio_derive_codec/
lib.rs1#![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; 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; 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(); 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; 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; 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; 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(); 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}