Skip to main content

canic_core/
lib.rs

1//! Core Canic library used inside canisters.
2//!
3//! Canister roles should depend on the `canic` facade crate, which exposes the
4//! supported API/DTO/ID surfaces and the common entrypoint macros:
5//! - `canic::build!` (in `build.rs`) to validate/embed `canic.toml`
6//! - `canic::start!` (in `lib.rs`) to wire lifecycle hooks and export endpoints
7//!
8//! ## Layering
9//!
10//! Canic is organized to keep endpoint code thin and coordination centralized:
11//! - `access/` contains access expressions, predicates, and metrics for boundary enforcement.
12//! - `workflow/` implements orchestration and lifecycle workflows.
13//! - `domain/policy/pure/` contains pure policy decisions invoked by workflow.
14//! - `ops/` provides deterministic state access, conversion, and approved single-step effects.
15//! - `model/` owns authoritative runtime state and storage invariants.
16//! - `storage/` contains passive persisted schemas and stable-memory representations.
17//! - `view/` exposes internal read-only projections over stored/runtime state.
18//! - macro entrypoints live in the `canic` facade crate.
19//!
20//! Endpoints call workflow, which may call policy and ops independently.
21//! Ops may call model; policy never calls ops.
22
23#[doc(hidden)]
24pub mod access;
25pub mod api;
26#[doc(hidden)]
27pub mod bootstrap;
28#[doc(hidden)]
29pub mod cdk;
30#[doc(hidden)]
31pub mod control_plane_support;
32
33#[doc(hidden)]
34pub mod dispatch;
35
36#[doc(hidden)]
37mod error;
38mod format;
39pub mod ids;
40#[doc(hidden)]
41pub mod ingress;
42pub mod log;
43pub mod memory;
44mod memory_macros;
45pub mod perf;
46
47pub mod replay_policy;
48#[doc(hidden)]
49pub mod role_contract;
50#[doc(hidden)]
51pub mod shared_support;
52#[doc(hidden)]
53pub mod state_contract;
54#[cfg(test)]
55pub mod test;
56
57pub(crate) mod config;
58pub(crate) mod domain;
59pub(crate) mod infra;
60pub(crate) mod lifecycle;
61pub(crate) mod model;
62pub(crate) mod ops;
63pub(crate) mod storage;
64pub(crate) mod view;
65pub(crate) mod workflow;
66
67use canic_contracts::{diagnostics, dto, protocol};
68
69pub(crate) use error::InternalError;
70
71/// Internal re-exports required for macro expansion.
72/// Not part of the public API.
73#[doc(hidden)]
74pub mod __reexports {
75    pub use ::ic_memory;
76    pub use ::ic_memory::__reexports::ctor;
77}
78
79///
80/// Consts
81///
82
83pub const VERSION: &str = env!("CARGO_PKG_VERSION");
84// Canonical hardcoded 1 MiB chunk size for Canic wasm staging/install flows.
85// The management canister wasm chunk store rejects larger payloads.
86pub const CANIC_WASM_CHUNK_BYTES: usize = 1_048_576;
87/// Existing byte-lane envelope, including bounded publication metadata.
88pub const CANIC_WASM_CHUNK_REQUEST_MAX_BYTES: usize = CANIC_WASM_CHUNK_BYTES + 64 * 1024;
89
90#[cfg(test)]
91const _: () = {
92    fn __canic_memory_test_bootstrap() {
93        crate::api::runtime::MemoryRuntimeApi::bootstrap_registry()
94            .expect("test stable-memory bootstrap");
95    }
96
97    #[crate::__reexports::ctor::ctor(
98        unsafe,
99        anonymous,
100        crate_path = crate::__reexports::ctor
101    )]
102    fn __canic_install_memory_test_bootstrap_hook() {
103        crate::memory::runtime::install_test_bootstrap_hook(__canic_memory_test_bootstrap);
104    }
105};
106
107#[macro_export]
108macro_rules! perf {
109    ($($label:tt)*) => {{
110        let label = format!($($label)*);
111        let _ = $crate::perf::checkpoint(module_path!(), &label);
112    }};
113}
114
115#[cfg(test)]
116#[macro_export]
117macro_rules! assert_err_variant {
118    ($err:expr, $pat:pat $(if $guard:expr)? $(,)?) => {{
119        match $err {
120            $pat $(if $guard)? => {}
121            other => panic!("unexpected error variant: {other:?}"),
122        }
123    }};
124}
125
126#[cfg(test)]
127mod memory_bootstrap_tests {
128    #[test]
129    fn installs_host_test_bootstrap_hook() {
130        assert!(crate::memory::runtime::has_test_bootstrap_hook());
131    }
132}