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