zink_codegen/
lib.rs

1//! Code generation library for the zink API
2
3#![allow(unused)]
4extern crate proc_macro;
5
6use proc_macro::TokenStream;
7use proc_macro2::Span;
8use quote::ToTokens;
9use syn::{parse_macro_input, Attribute, DeriveInput, Expr, ItemFn, ItemStruct, LitStr};
10
11mod contract;
12mod event;
13mod revert;
14mod selector;
15mod storage;
16mod utils;
17
18/// Revert with the input message
19///
20/// Only raw string is supported, formatter currently doesn't work.
21#[proc_macro]
22pub fn revert(input: TokenStream) -> TokenStream {
23    let input = parse_macro_input!(input as LitStr);
24    revert::parse(input)
25}
26
27/// Check and expression and revert with the input message
28///
29/// This is similar with the builtin `assert!` in rust, but the revert
30/// message only support raw string.
31#[proc_macro]
32pub fn assert(input: TokenStream) -> TokenStream {
33    let input = parse_macro_input!(input as revert::AssertInput);
34    revert::parse_assert(input)
35}
36
37/// Declare contract storage
38#[proc_macro_derive(Storage)]
39pub fn storage_derive(input: TokenStream) -> TokenStream {
40    contract::ContractStorage::parse(input)
41}
42
43/// Event logging interface
44///
45/// ```ignore
46/// use zink::Event;
47///
48/// /// A `Ping` event.
49/// #[derive(Event)]
50/// struct Ping;
51///
52/// #[no_mangle]
53/// pub extern "C" fn log0() {
54///     Ping.log0();
55/// }
56/// ```
57///
58/// will generate:
59///
60/// ```ignore
61/// struct Ping;
62///
63/// impl zink::Event for Ping {
64///     const NAME: &'static [u8] = b"Ping";
65/// }
66/// ```
67#[proc_macro_derive(Event, attributes(indexed, anonymous))]
68pub fn event(input: TokenStream) -> TokenStream {
69    let input = parse_macro_input!(input as DeriveInput);
70    event::parse(input)
71}
72
73/// Declare on-chain storage
74///
75/// ```ignore
76/// /// storage value
77/// #[zink::storage(i32)]
78/// pub struct Counter;
79///
80/// /// storage mapping
81/// #[zink::storage(i32, i32)]
82/// pub struct Mapping;
83/// ```
84#[proc_macro_attribute]
85pub fn storage(attr: TokenStream, input: TokenStream) -> TokenStream {
86    let ty = storage::StorageType::from(attr);
87    let input = parse_macro_input!(input as ItemStruct);
88    storage::Storage::parse(ty, input)
89}
90
91/// Declare transient storage (cleared after each transaction)
92///
93/// ```ignore
94/// /// transient storage value
95/// #[zink::transient_storage(i32)]
96/// pub struct TempCounter;
97///
98/// /// transient storage mapping
99/// #[zink::transient_storage(i32, i32)]
100/// pub struct TempMapping;
101/// ```
102#[proc_macro_attribute]
103pub fn transient_storage(attr: TokenStream, input: TokenStream) -> TokenStream {
104    let ty = storage::StorageType::from(attr);
105    let input = parse_macro_input!(input as ItemStruct);
106    storage::Storage::parse_transient(ty, input)
107}
108
109/// Mark the function as an external entry point.
110#[proc_macro_attribute]
111pub fn external(_args: TokenStream, input: TokenStream) -> TokenStream {
112    let input = parse_macro_input!(input as ItemFn);
113    selector::external(input)
114}