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::{parse_macro_input, Lit};
9
10mod base58;
11mod contract;
12mod event;
13
14#[proc_macro_attribute]
15pub fn contract(_metadata: TokenStream, input: TokenStream) -> TokenStream {
16 let item: syn::Item = syn::parse(input).unwrap();
17 let stream = contract::quote(item);
18
19 stream.into()
20}
21
22#[proc_macro_attribute]
23pub fn event(metadata: TokenStream, input: TokenStream) -> TokenStream {
24 match syn::parse::<syn::Item>(input).unwrap() {
25 syn::Item::Fn(ref func) => {
26 use quote::ToTokens;
27 let mut method_name;
28 if metadata.is_empty() {
29 method_name = func.sig.ident.clone().into_token_stream().to_string();
30 } else {
31 method_name = metadata.to_string();
32 method_name = method_name.replace("name", "");
33 method_name = method_name.replace("=", "");
34 }
35 method_name = method_name.to_mixed_case();
36 let stream = event::quote(method_name, func);
37 stream.into()
38 }
39 _ => panic!("Only fn is allowed"),
40 }
41}
42
43#[proc_macro]
44pub fn base58(item: TokenStream) -> TokenStream {
45 let input = parse_macro_input!(item as Lit);
46 let addr = match input {
47 syn::Lit::Str(lit_str) => base58::decode_base58(&lit_str.value())
48 .unwrap_or_else(|e| panic!("failed to parse base58 address: {}", e)),
49 syn::Lit::ByteStr(lit_str) => {
50 base58::decode_base58(&String::from_utf8(lit_str.value()).unwrap())
51 .unwrap_or_else(|e| panic!("failed to parse base58 address: {}", e))
52 }
53 _ => panic!("base58! only support string literal"),
54 };
55 let result = quote! { Address::new([#(#addr),*])};
56
57 result.into()
58}
59