Skip to main content

icydb/
lib.rs

1//! # icydb
2//!
3//! `icydb` is the **public facade crate** for the IcyDB runtime.
4//! It is the recommended dependency for downstream canister projects.
5//!
6//! This crate exposes:
7//! - the stable runtime surface used inside canister actor code,
8//! - schema and design-time helpers for macros and validation,
9//! - and a small set of macros and entry points that wire generated code.
10//!
11//! Low-level execution, storage, and engine internals live in
12//! `icydb-core` and are re-exposed selectively through stable facade modules.
13//!
14//! ## Crate layout
15//!
16//! - `base`
17//!   Design-time helpers, sanitizers, and validators used by schemas and macros.
18//!
19//! - `build`
20//!   Internal code generation helpers used by macros and tests
21//!   (not intended for direct use).
22//!
23//! - `traits` / `types` / `value` / `visitor`
24//!   Stable runtime and schema-facing building blocks used by generated code.
25//!
26//! - `model` / `metrics` *(internal)*
27//!   Runtime model and metrics internals. Exposed for advanced tooling only;
28//!   not part of the supported semver surface.
29//!
30//! - `error`
31//!   Shared error types for generated code and runtime boundaries.
32//!
33//! - `macros`
34//!   Derive macros for entities, canisters, and schema helpers.
35//!
36//! - `schema`
37//!   Schema AST, builders, and validation utilities.
38//!
39//! - `db`
40//!   The public database façade: session handles, query builders,
41//!   and typed responses.
42//!
43//! ## Preludes
44//!
45//! - `prelude`
46//!   Opinionated runtime prelude for canister actor code.
47//!   Intended to be glob-imported in `lib.rs` to keep endpoints concise.
48//!
49//! - `design::prelude`
50//!   Prelude for schema and design-time code (macros, validators,
51//!   and base helpers).
52//!
53//! ## Internal boundaries
54//!
55//! Generated code targets explicit facade surfaces (`traits`, `patch`,
56//! and `__macro`) instead of a broad internal-export module.
57
58// export so things just work in base/
59extern crate self as icydb;
60
61use icydb_core::{error::InternalError, traits::Visitable};
62// crates
63pub use icydb_build as build;
64pub use icydb_build::build;
65pub use icydb_schema as schema;
66pub use icydb_schema_derive as macros;
67
68// core modules
69#[doc(hidden)]
70pub use icydb_core::{types, value};
71
72#[doc(hidden)]
73pub mod model {
74    pub mod entity {
75        pub use icydb_core::model::EntityModel;
76    }
77
78    pub mod field {
79        pub use icydb_core::model::{
80            EnumVariantModel, FieldInsertGeneration, FieldKind, FieldModel, FieldStorageDecode,
81            FieldWriteManagement, RelationStrength,
82        };
83    }
84
85    pub mod index {
86        pub use icydb_core::model::{
87            IndexExpression, IndexKeyItem, IndexKeyItemsRef, IndexModel, IndexPredicateMetadata,
88        };
89    }
90
91    pub use entity::EntityModel;
92    pub use field::FieldModel;
93    pub use index::{IndexExpression, IndexModel};
94}
95
96#[doc(hidden)]
97pub mod metrics {
98    pub use icydb_core::metrics::{
99        EventCounters, EventReport, MetricsSink, metrics_report, metrics_reset_all,
100    };
101}
102
103pub mod visitor {
104    pub use icydb_core::visitor::{
105        Issue, PathSegment, SanitizeFieldDescriptor, ScopedContext, ValidateFieldDescriptor,
106        VisitableFieldDescriptor, VisitorContext, VisitorCore, VisitorError, VisitorIssues,
107        VisitorMutCore, drive_sanitize_fields, drive_validate_fields, drive_visitable_fields,
108        drive_visitable_fields_mut, perform_visit, perform_visit_mut,
109    };
110    pub use icydb_core::{
111        sanitize::{SanitizeWriteContext, SanitizeWriteMode, sanitize, sanitize_with_context},
112        validate::validate,
113    };
114}
115
116// facade modules
117pub mod base;
118pub mod db;
119pub mod error;
120pub mod traits;
121pub use error::Error;
122
123/// Generic create-input alias for one entity type.
124pub type Create<E> = <E as icydb_core::traits::EntityCreateType>::Create;
125
126// Macro/runtime wiring surface used by generated code.
127// This is intentionally narrow and not semver-stable.
128#[doc(hidden)]
129pub mod __macro {
130    pub use crate::db::execute_generated_storage_report;
131    #[cfg(feature = "sql")]
132    pub use icydb_core::db::LoweredSqlCommand;
133    pub use icydb_core::db::{
134        DataStore, DbSession as CoreDbSession, EntityRuntimeHooks, IndexStore, StoreRegistry,
135    };
136}
137
138// re-exports
139//
140// macros can use these, stops the user having to specify all the dependencies
141// in the Cargo.toml file manually
142//
143// these have to be in icydb_core because of the base library not being able to import icydb
144#[doc(hidden)]
145pub mod __reexports {
146    pub use candid;
147    pub use canic_cdk;
148    pub use canic_memory;
149    pub use ctor;
150    pub use derive_more;
151    pub use icydb_derive;
152    pub use remain;
153    pub use serde;
154}
155
156//
157// Actor Prelude
158// using _ brings traits into scope and avoids name conflicts
159//
160
161pub mod prelude {
162    pub use crate::{
163        db,
164        db::{
165            query,
166            query::{
167                FilterExpr, SortExpr,
168                builder::{
169                    FieldRef, count, count_by, exists, first, last, max, max_by, min, min_by, sum,
170                },
171                predicate::Predicate,
172            },
173        },
174        traits::{
175            Collection as _, EntityKind as _, EntityValue, Inner as _, MapCollection as _,
176            Path as _,
177        },
178        types::*,
179        value::Value,
180    };
181    pub use candid::CandidType;
182    pub use serde::{Deserialize, Serialize};
183}
184
185//
186// Design Prelude
187// For schema/design code (macros, traits, base helpers).
188//
189
190pub mod design {
191    pub mod prelude {
192        pub use ::candid::CandidType;
193        pub use ::derive_more;
194
195        pub use crate::{
196            base, db,
197            db::query::builder::{
198                FieldRef, count, count_by, exists, first, last, max, max_by, min, min_by, sum,
199            },
200            macros::*,
201            traits::{
202                Collection as _, EntityKind, EntityValue as _, FieldValue as _, Inner as _,
203                MapCollection as _, Path as _, Sanitize as _, Sanitizer, Serialize as _,
204                Validate as _, ValidateCustom, Validator, Visitable as _,
205            },
206            types::*,
207            value::Value,
208            visitor::VisitorContext,
209            visitor::{SanitizeWriteContext, SanitizeWriteMode},
210        };
211    }
212}
213
214//
215// -------------------------- CODE -----------------------------------
216//
217//
218// Consts
219//
220
221// Workspace version re-export for downstream tooling/tests.
222pub const VERSION: &str = env!("CARGO_PKG_VERSION");
223
224//
225// Macros
226//
227
228// Include the generated actor module emitted by `build!` (placed in `OUT_DIR/actor.rs`).
229#[macro_export]
230macro_rules! start {
231    () => {
232        // actor.rs
233        include!(concat!(env!("OUT_DIR"), "/actor.rs"));
234    };
235}
236
237// Access the current canister's database session; use `db!().debug()` for verbose tracing.
238#[macro_export]
239#[expect(clippy::crate_in_macro_def)]
240macro_rules! db {
241    () => {
242        crate::db()
243    };
244}
245
246//
247// Helpers
248//
249
250// Run sanitization over a mutable visitable tree.
251pub fn sanitize(node: &mut dyn Visitable) -> Result<(), Error> {
252    icydb_core::sanitize::sanitize(node)
253        .map_err(InternalError::from)
254        .map_err(Error::from)
255}
256
257// Validate a visitable tree, collecting issues by path.
258pub fn validate(node: &dyn Visitable) -> Result<(), Error> {
259    icydb_core::validate::validate(node)
260        .map_err(InternalError::from)
261        .map_err(Error::from)
262}