Skip to main content

ic_platform_macros/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use proc_macro::TokenStream;
4use syn::Error;
5
6mod export;
7mod external_candid;
8mod signature;
9
10fn handle_debug_and_errors<F>(
11    cb: F,
12    name: &str,
13    attr: TokenStream,
14    item: TokenStream,
15) -> TokenStream
16where
17    F: FnOnce(
18        proc_macro2::TokenStream,
19        proc_macro2::TokenStream,
20    ) -> Result<proc_macro2::TokenStream, Error>,
21{
22    if std::env::var_os("IC_CDK_DEBUG").is_some() {
23        eprintln!("--- IC_CDK_MACROS DEBUG ---");
24        eprintln!("{name}\n    attr: {attr}\n    item: {item}");
25    }
26
27    let result = cb(attr.into(), item.into());
28
29    if std::env::var_os("IC_CDK_DEBUG").is_some() {
30        eprintln!("--------- RESULT  ---------");
31        if let Ok(ref stream) = result {
32            eprintln!("{stream}");
33        }
34        eprintln!("---------------------------");
35    }
36
37    result.map_or_else(|e| e.to_compile_error().into(), Into::into)
38}
39
40/// Generate an explicit-codec query or composite-query entrypoint.
41#[proc_macro_attribute]
42pub fn query(attr: TokenStream, item: TokenStream) -> TokenStream {
43    handle_debug_and_errors(export::ic_query, "ic_query", attr, item)
44}
45
46/// Generate an explicit-codec update entrypoint.
47#[proc_macro_attribute]
48pub fn update(attr: TokenStream, item: TokenStream) -> TokenStream {
49    handle_debug_and_errors(export::ic_update, "ic_update", attr, item)
50}
51
52/// Generate an initialization entrypoint with explicit argument decoding.
53#[proc_macro_attribute]
54pub fn init(attr: TokenStream, item: TokenStream) -> TokenStream {
55    handle_debug_and_errors(export::ic_init, "ic_init", attr, item)
56}
57
58/// Generate a pre-upgrade entrypoint in the shared runtime context.
59#[proc_macro_attribute]
60pub fn pre_upgrade(attr: TokenStream, item: TokenStream) -> TokenStream {
61    handle_debug_and_errors(export::ic_pre_upgrade, "ic_pre_upgrade", attr, item)
62}
63
64/// Generate a post-upgrade entrypoint with explicit argument decoding.
65#[proc_macro_attribute]
66pub fn post_upgrade(attr: TokenStream, item: TokenStream) -> TokenStream {
67    handle_debug_and_errors(export::ic_post_upgrade, "ic_post_upgrade", attr, item)
68}
69
70/// Generate a heartbeat entrypoint in the shared runtime context.
71#[proc_macro_attribute]
72pub fn heartbeat(attr: TokenStream, item: TokenStream) -> TokenStream {
73    handle_debug_and_errors(export::ic_heartbeat, "ic_heartbeat", attr, item)
74}
75
76/// Generate a message inspection entrypoint in the shared runtime context.
77#[proc_macro_attribute]
78pub fn inspect_message(attr: TokenStream, item: TokenStream) -> TokenStream {
79    handle_debug_and_errors(export::ic_inspect_message, "ic_inspect_message", attr, item)
80}
81
82/// Generate a low-Wasm-memory entrypoint in the shared runtime context.
83#[proc_macro_attribute]
84pub fn on_low_wasm_memory(attr: TokenStream, item: TokenStream) -> TokenStream {
85    handle_debug_and_errors(
86        export::ic_on_low_wasm_memory,
87        "ic_on_low_wasm_memory",
88        attr,
89        item,
90    )
91}
92
93/// Generate a bounded required-external-Candid query with explicit artifact policy.
94#[proc_macro_attribute]
95pub fn candid_query(attr: TokenStream, item: TokenStream) -> TokenStream {
96    handle_debug_and_errors(
97        |attr, item| external_candid::expand(true, attr, item),
98        "candid_query",
99        attr,
100        item,
101    )
102}
103/// Generate a bounded required-external-Candid update with explicit artifact policy.
104#[proc_macro_attribute]
105pub fn candid_update(attr: TokenStream, item: TokenStream) -> TokenStream {
106    handle_debug_and_errors(
107        |attr, item| external_candid::expand(false, attr, item),
108        "candid_update",
109        attr,
110        item,
111    )
112}