mod build;
mod endpoints;
mod start;
mod timer;
#[macro_export]
macro_rules! canic_protected_endpoint {
() => {};
(
$(#[$meta:meta])*
$vis:vis fn $name:ident = $method:expr, role = $role:expr;
$($rest:tt)*
) => {
$(#[$meta])*
$vis fn $name() -> $crate::api::ic::ProtectedInternalEndpoint {
$crate::api::ic::ProtectedInternalEndpoint::new($method, [$role])
}
$crate::canic_protected_endpoint! {
$($rest)*
}
};
(
$(#[$meta:meta])*
$vis:vis fn $name:ident = $method:expr, roles = [$($role:expr),+ $(,)?];
$($rest:tt)*
) => {
$(#[$meta])*
$vis fn $name() -> $crate::api::ic::ProtectedInternalEndpoint {
$crate::api::ic::ProtectedInternalEndpoint::new($method, [$($role),+])
}
$crate::canic_protected_endpoint! {
$($rest)*
}
};
(
$(#[$meta:meta])*
$vis:vis fn $name:ident = $method:expr, roles = [] $($tail:tt)*
) => {
compile_error!(
"canic_protected_endpoint! roles = [] is invalid; protected internal endpoints must accept at least one caller role"
);
};
(
$(#[$meta:meta])*
$vis:vis fn $name:ident = $method:expr, role = $role:expr $(;)?
) => {
$(#[$meta])*
$vis fn $name() -> $crate::api::ic::ProtectedInternalEndpoint {
$crate::api::ic::ProtectedInternalEndpoint::new($method, [$role])
}
};
(
$(#[$meta:meta])*
$vis:vis fn $name:ident = $method:expr, roles = [$($role:expr),+ $(,)?] $(;)?
) => {
$(#[$meta])*
$vis fn $name() -> $crate::api::ic::ProtectedInternalEndpoint {
$crate::api::ic::ProtectedInternalEndpoint::new($method, [$($role),+])
}
};
}
#[macro_export]
macro_rules! canic_internal_client {
(
$(#[$client_meta:meta])*
$vis:vis struct $client:ident {
$(
$(#[$method_meta:meta])*
fn $method:ident = $endpoint:expr $(, role = $role:expr)?; (
$($arg:ident : $arg_ty:ty),* $(,)?
) -> $response:ty;
)*
}
) => {
$(#[$client_meta])*
$vis struct $client {
inner: $crate::api::ic::CanicInternalClient,
}
impl $client {
#[must_use]
$vis const fn new(canister_id: $crate::cdk::types::Principal) -> Self {
Self {
inner: $crate::api::ic::CanicInternalClient::new(canister_id),
}
}
#[must_use]
$vis const fn with_options(
mut self,
options: $crate::api::ic::CanicInternalCallOptions,
) -> Self {
self.inner = self.inner.with_options(options);
self
}
#[must_use]
$vis const fn with_bounded_wait(mut self) -> Self {
self.inner = self.inner.with_bounded_wait();
self
}
#[must_use]
$vis const fn with_unbounded_wait(mut self) -> Self {
self.inner = self.inner.with_unbounded_wait();
self
}
#[must_use]
$vis const fn with_cycles(mut self, cycles: u128) -> Self {
self.inner = self.inner.with_cycles(cycles);
self
}
#[must_use]
$vis const fn with_proof_ttl_secs(mut self, ttl_secs: u64) -> Self {
self.inner = self.inner.with_proof_ttl_secs(ttl_secs);
self
}
$(
$(#[$method_meta])*
$vis async fn $method(
&self,
$($arg: $arg_ty),*
) -> ::core::result::Result<$response, $crate::Error> {
let endpoint = ($endpoint)();
$crate::__canic_internal_client_execute!(
self,
endpoint,
($($arg,)*),
$response
$(, $role)?
).await
}
)*
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __canic_internal_client_execute {
($self:ident, $endpoint:ident, ($($arg:expr,)*), $response:ty) => {
$self.inner.call_update_result_with_single_role::<$response, _>(
&$endpoint,
($($arg,)*),
)
};
($self:ident, $endpoint:ident, ($($arg:expr,)*), $response:ty, $role:expr) => {
$self.inner.call_update_result::<$response, _>(
&$endpoint,
$role,
($($arg,)*),
)
};
}
#[macro_export]
macro_rules! log {
($($tt:tt)*) => {{
$crate::__internal::core::log!($($tt)*);
}};
}
#[macro_export]
macro_rules! perf {
($($label:tt)*) => {{
$crate::__internal::core::perf::PERF_LAST.with(|last| {
let now = $crate::__internal::core::perf::perf_counter();
let then = *last.borrow();
let delta = now.saturating_sub(then);
*last.borrow_mut() = now;
let label = format!($($label)*);
let delta_fmt = $crate::__internal::instructions::format_instructions(delta);
let now_fmt = $crate::__internal::instructions::format_instructions(now);
$crate::__internal::core::perf::record_checkpoint(module_path!(), &label, delta);
$crate::__internal::core::log!(
Info,
Topic::Perf,
"{}: '{}' used {}i since last (total: {}i)",
module_path!(),
label,
delta_fmt,
now_fmt
);
});
}};
}