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}
113
114/// Generate a query entrypoint using the canonical runtime owner.
115#[proc_macro_attribute]
116pub fn runtime_query(attr: TokenStream, item: TokenStream) -> TokenStream {
117    handle_debug_and_errors(
118        |attr, item| export::runtime_entry(export::MethodType::Query, attr, item),
119        "runtime_query",
120        attr,
121        item,
122    )
123}
124
125/// Generate a update entrypoint using the canonical runtime owner.
126#[proc_macro_attribute]
127pub fn runtime_update(attr: TokenStream, item: TokenStream) -> TokenStream {
128    handle_debug_and_errors(
129        |attr, item| export::runtime_entry(export::MethodType::Update, attr, item),
130        "runtime_update",
131        attr,
132        item,
133    )
134}
135
136/// Generate a init entrypoint using the canonical runtime owner.
137#[proc_macro_attribute]
138pub fn runtime_init(attr: TokenStream, item: TokenStream) -> TokenStream {
139    handle_debug_and_errors(
140        |attr, item| export::runtime_entry(export::MethodType::Init, attr, item),
141        "runtime_init",
142        attr,
143        item,
144    )
145}
146
147/// Generate a pre_upgrade entrypoint using the canonical runtime owner.
148#[proc_macro_attribute]
149pub fn runtime_pre_upgrade(attr: TokenStream, item: TokenStream) -> TokenStream {
150    handle_debug_and_errors(
151        |attr, item| export::runtime_entry(export::MethodType::PreUpgrade, attr, item),
152        "runtime_pre_upgrade",
153        attr,
154        item,
155    )
156}
157
158/// Generate a post_upgrade entrypoint using the canonical runtime owner.
159#[proc_macro_attribute]
160pub fn runtime_post_upgrade(attr: TokenStream, item: TokenStream) -> TokenStream {
161    handle_debug_and_errors(
162        |attr, item| export::runtime_entry(export::MethodType::PostUpgrade, attr, item),
163        "runtime_post_upgrade",
164        attr,
165        item,
166    )
167}
168
169/// Generate a heartbeat entrypoint using the canonical runtime owner.
170#[proc_macro_attribute]
171pub fn runtime_heartbeat(attr: TokenStream, item: TokenStream) -> TokenStream {
172    handle_debug_and_errors(
173        |attr, item| export::runtime_entry(export::MethodType::Heartbeat, attr, item),
174        "runtime_heartbeat",
175        attr,
176        item,
177    )
178}
179
180/// Generate a inspect_message entrypoint using the canonical runtime owner.
181#[proc_macro_attribute]
182pub fn runtime_inspect_message(attr: TokenStream, item: TokenStream) -> TokenStream {
183    handle_debug_and_errors(
184        |attr, item| export::runtime_entry(export::MethodType::InspectMessage, attr, item),
185        "runtime_inspect_message",
186        attr,
187        item,
188    )
189}
190
191/// Generate a on_low_wasm_memory entrypoint using the canonical runtime owner.
192#[proc_macro_attribute]
193pub fn runtime_on_low_wasm_memory(attr: TokenStream, item: TokenStream) -> TokenStream {
194    handle_debug_and_errors(
195        |attr, item| export::runtime_entry(export::MethodType::OnLowWasmMemory, attr, item),
196        "runtime_on_low_wasm_memory",
197        attr,
198        item,
199    )
200}