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 exposed only through `__internal`.
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` / `view` / `visitor`
24//!   Stable runtime and schema-facing building blocks used by generated code.
25//!
26//! - `model` / `obs` *(internal)*
27//!   Runtime model and metrics internals. Exposed for advanced tooling only;
28//!   not part of the supported semver surface.
29//!
30//! - `__internal::core` *(internal)*
31//!   Full engine internals for macros/tests. Not covered by semver guarantees.
32//!
33//! - `error`
34//!   Shared error types for generated code and runtime boundaries.
35//!
36//! - `macros`
37//!   Derive macros for entities, schemas, and views.
38//!
39//! - `schema`
40//!   Schema AST, builders, and validation utilities.
41//!
42//! - `db`
43//!   The public database façade: session handles, query builders,
44//!   and typed responses.
45//!
46//! ## Preludes
47//!
48//! - `prelude`
49//!   Opinionated runtime prelude for canister actor code.
50//!   Intended to be glob-imported in `lib.rs` to keep endpoints concise.
51//!
52//! - `design::prelude`
53//!   Prelude for schema and design-time code (macros, validators,
54//!   and base helpers).
55//!
56//! ## Internal boundaries
57//!
58//! The `__internal` module exposes selected engine internals strictly for
59//! generated code and macro expansion. It is not part of the supported API
60//! surface and may change without notice.
61
62// export so things just work in base/
63extern crate self as icydb;
64
65// crates
66pub use icydb_build as build;
67pub use icydb_build::build;
68pub use icydb_schema as schema;
69pub use icydb_schema_derive as macros;
70
71// core modules
72#[doc(hidden)]
73pub use icydb_core::{model, obs, traits, types, value, view, visitor};
74
75// canic modules
76pub mod base;
77pub mod db;
78pub mod error;
79pub use error::Error;
80
81/// Internal
82#[doc(hidden)]
83pub mod __internal {
84    pub use icydb_core as core;
85}
86
87/// re-exports
88///
89/// macros can use these, stops the user having to specify all the dependencies
90/// in the Cargo.toml file manually
91///
92/// these have to be in icydb_core because of the base library not being able to import icydb
93#[doc(hidden)]
94pub mod __reexports {
95    pub use canic_cdk;
96    pub use canic_memory;
97    pub use ctor;
98    pub use derive_more;
99    pub use icydb_derive;
100    pub use num_traits;
101    pub use remain;
102}
103
104///
105/// Actor Prelude
106/// using _ brings traits into scope and avoids name conflicts
107///
108
109pub mod prelude {
110    pub use crate::{
111        db,
112        db::{
113            query,
114            query::{FilterExpr, SortExpr, builder::FieldRef, predicate::Predicate},
115        },
116        traits::{
117            AsView, Collection as _, CreateView as _, EntityKind as _, EntityValue as _,
118            Inner as _, MapCollection as _, Path as _, UpdateView as _,
119        },
120        types::*,
121        value::Value,
122        view::{Create, Update, View},
123    };
124    pub use candid::CandidType;
125    pub use serde::{Deserialize, Serialize};
126}
127
128///
129/// Design Prelude
130/// For schema/design code (macros, traits, base helpers).
131///
132
133pub mod design {
134    pub mod prelude {
135        pub use ::candid::CandidType;
136        pub use ::derive_more;
137
138        pub use crate::{
139            base, db,
140            db::query::builder::FieldRef,
141            macros::*,
142            traits::{
143                AsView, Collection as _, EntityKind, EntityValue as _, FieldValue as _, Inner as _,
144                MapCollection as _, Path as _, Sanitize as _, Sanitizer, Serialize as _,
145                Validate as _, ValidateCustom, Validator, Visitable as _,
146            },
147            types::*,
148            value::Value,
149            view::{Create, Update, View},
150            visitor::VisitorContext,
151        };
152    }
153}
154
155///
156/// -------------------------- CODE -----------------------------------
157///
158use icydb_core::{error::InternalError, traits::Visitable};
159use serde::{Serialize, de::DeserializeOwned};
160
161///
162/// Consts
163///
164
165/// Workspace version re-export for downstream tooling/tests.
166pub const VERSION: &str = env!("CARGO_PKG_VERSION");
167
168///
169/// Macros
170///
171
172/// Include the generated actor module emitted by `build!` (placed in `OUT_DIR/actor.rs`).
173#[macro_export]
174macro_rules! start {
175    () => {
176        // actor.rs
177        include!(concat!(env!("OUT_DIR"), "/actor.rs"));
178    };
179}
180
181/// Access the current canister's database session; use `db!().debug()` for verbose tracing.
182#[macro_export]
183#[allow(clippy::crate_in_macro_def)]
184macro_rules! db {
185    () => {
186        crate::db()
187    };
188}
189
190///
191/// Helpers
192///
193
194/// Run sanitization over a mutable visitable tree.
195pub fn sanitize(node: &mut dyn Visitable) -> Result<(), Error> {
196    icydb_core::sanitize::sanitize(node)
197        .map_err(InternalError::from)
198        .map_err(Error::from)
199}
200
201/// Validate a visitable tree, collecting issues by path.
202pub fn validate(node: &dyn Visitable) -> Result<(), Error> {
203    icydb_core::validate::validate(node)
204        .map_err(InternalError::from)
205        .map_err(Error::from)
206}
207
208/// Serialize a visitable value into bytes.
209///
210/// The encoding format is an internal detail of icydb and is only
211/// guaranteed to round-trip via `deserialize`.
212pub fn serialize<T>(ty: &T) -> Result<Vec<u8>, Error>
213where
214    T: Serialize,
215{
216    icydb_core::serialize::serialize(ty)
217        .map_err(InternalError::from)
218        .map_err(Error::from)
219}
220
221/// Deserialize bytes into a concrete visitable value.
222///
223/// This is intended for testing, tooling, and round-trip verification.
224/// It should not be used in hot runtime paths.
225pub fn deserialize<T>(bytes: &[u8]) -> Result<T, Error>
226where
227    T: DeserializeOwned,
228{
229    icydb_core::serialize::deserialize(bytes)
230        .map_err(InternalError::from)
231        .map_err(Error::from)
232}