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