Skip to main content

icydb_core/
lib.rs

1//! Module: lib
2//! Responsibility: crate root for the IcyDB core runtime surface.
3//! Does not own: canister-facing facade APIs from the public `icydb` crate.
4//! Boundary: exposes the engine subsystems used by schema, query, executor, and storage layers.
5
6//! Core runtime for IcyDB: entity traits, values, executors, visitors, and
7//! the ergonomics exported via the `prelude`.
8#![warn(unreachable_pub)] // too complex to adhere to right now
9
10extern crate self as icydb;
11
12#[macro_use]
13pub(crate) mod scalar_registry;
14
15// public exports are one module level down
16pub mod db;
17pub mod error;
18pub mod metrics;
19pub mod model;
20pub mod sanitize;
21pub mod traits;
22pub mod types;
23pub mod validate;
24pub mod value;
25pub mod visitor;
26
27// testing
28#[cfg(test)]
29pub(crate) mod testing;
30
31///
32/// CONSTANTS
33///
34
35/// Maximum number of indexed fields allowed on an entity.
36///
37/// This limit keeps hashed index keys within bounded, storable sizes and
38/// simplifies sizing tests in the stores.
39pub const MAX_INDEX_FIELDS: usize = 4;
40
41///
42/// Prelude
43///
44/// Prelude contains only domain vocabulary.
45/// No errors, executors, stores, serializers, or helpers are re-exported here.
46///
47
48pub mod prelude {
49    pub use crate::{
50        model::{entity::EntityModel, index::IndexModel},
51        traits::{EntityKind, Path},
52        value::{InputValue, OutputValue},
53    };
54}
55
56// Macro/runtime wiring surface used by generated code in local core tests.
57// This mirrors the facade crate's hidden generated-code boundary so derive
58// output can target one stable path regardless of which workspace crate owns
59// the test harness.
60#[doc(hidden)]
61pub mod __macro {
62    pub use crate::db::{
63        GeneratedStructuralEnumPayload, GeneratedStructuralMapPayloadSlices, PersistedRow,
64        PersistedScalar, ScalarSlotValueRef, ScalarValueRef, SlotReader, SlotWriter,
65    };
66    pub use crate::error::InternalError;
67    pub use crate::traits::{
68        EnumValue, FieldProjection, PersistedByKindCodec, PersistedFieldMetaCodec,
69        PersistedFieldSlotCodec, PersistedStructuredFieldCodec, RuntimeValueDecode,
70        RuntimeValueEncode, RuntimeValueKind, RuntimeValueMeta, runtime_value_btree_map_from_value,
71        runtime_value_btree_set_from_value, runtime_value_collection_to_value,
72        runtime_value_from_value, runtime_value_from_vec_into,
73        runtime_value_from_vec_into_btree_map, runtime_value_from_vec_into_btree_set,
74        runtime_value_into, runtime_value_map_collection_to_value, runtime_value_to_value,
75        runtime_value_vec_from_value,
76    };
77    pub use crate::value::{InputValue, Value, ValueEnum};
78    pub use ic_memory::{
79        bootstrap_default_memory_manager, ic_memory_declaration, ic_memory_key, ic_memory_range,
80    };
81
82    #[doc(hidden)]
83    #[must_use]
84    pub fn encode_generated_structural_text_payload_bytes(value: &str) -> Vec<u8> {
85        crate::db::encode_generated_structural_text_payload_bytes(value)
86    }
87
88    #[doc(hidden)]
89    #[must_use]
90    pub fn encode_generated_structural_list_payload_bytes(items: &[&[u8]]) -> Vec<u8> {
91        crate::db::encode_generated_structural_list_payload_bytes(items)
92    }
93
94    #[doc(hidden)]
95    #[must_use]
96    pub fn encode_generated_structural_map_payload_bytes(entries: &[(&[u8], &[u8])]) -> Vec<u8> {
97        crate::db::encode_generated_structural_map_payload_bytes(entries)
98    }
99
100    #[doc(hidden)]
101    #[must_use]
102    pub fn encode_generated_structural_enum_payload_bytes(
103        variant: &str,
104        path: Option<&str>,
105        payload: Option<&[u8]>,
106    ) -> Vec<u8> {
107        crate::db::encode_generated_structural_enum_payload_bytes(variant, path, payload)
108    }
109
110    #[doc(hidden)]
111    pub fn decode_generated_structural_text_payload_bytes(
112        raw_bytes: &[u8],
113    ) -> Result<String, crate::error::InternalError> {
114        crate::db::decode_generated_structural_text_payload_bytes(raw_bytes)
115    }
116
117    #[doc(hidden)]
118    pub fn decode_generated_structural_list_payload_bytes(
119        raw_bytes: &[u8],
120    ) -> Result<Vec<&[u8]>, crate::error::InternalError> {
121        crate::db::decode_generated_structural_list_payload_bytes(raw_bytes)
122    }
123
124    #[doc(hidden)]
125    pub fn decode_generated_structural_map_payload_bytes(
126        raw_bytes: &[u8],
127    ) -> Result<crate::db::GeneratedStructuralMapPayloadSlices<'_>, crate::error::InternalError>
128    {
129        crate::db::decode_generated_structural_map_payload_bytes(raw_bytes)
130    }
131
132    #[doc(hidden)]
133    pub fn decode_generated_structural_enum_payload_bytes(
134        raw_bytes: &[u8],
135    ) -> Result<crate::db::GeneratedStructuralEnumPayload<'_>, crate::error::InternalError> {
136        crate::db::decode_generated_structural_enum_payload_bytes(raw_bytes)
137    }
138
139    #[doc(hidden)]
140    pub fn generated_persisted_structured_payload_decode_failed(
141        detail: impl std::fmt::Display,
142    ) -> crate::error::InternalError {
143        crate::db::generated_persisted_structured_payload_decode_failed(detail)
144    }
145
146    #[doc(hidden)]
147    pub fn encode_persisted_structured_many_slot_payload<T>(
148        value: &[T],
149        field_name: &'static str,
150    ) -> Result<Vec<u8>, crate::error::InternalError>
151    where
152        T: crate::traits::PersistedStructuredFieldCodec,
153    {
154        crate::db::encode_persisted_structured_many_slot_payload(value, field_name)
155    }
156
157    #[doc(hidden)]
158    pub fn decode_persisted_structured_many_slot_payload<T>(
159        bytes: &[u8],
160        field_name: &'static str,
161    ) -> Result<Vec<T>, crate::error::InternalError>
162    where
163        T: crate::traits::PersistedStructuredFieldCodec,
164    {
165        crate::db::decode_persisted_structured_many_slot_payload(bytes, field_name)
166    }
167
168    #[doc(hidden)]
169    pub fn encode_persisted_structured_slot_payload<T>(
170        value: &T,
171        field_name: &'static str,
172    ) -> Result<Vec<u8>, crate::error::InternalError>
173    where
174        T: crate::traits::PersistedStructuredFieldCodec,
175    {
176        crate::db::encode_persisted_structured_slot_payload(value, field_name)
177    }
178
179    #[doc(hidden)]
180    pub fn decode_persisted_structured_slot_payload<T>(
181        bytes: &[u8],
182        field_name: &'static str,
183    ) -> Result<T, crate::error::InternalError>
184    where
185        T: crate::traits::PersistedStructuredFieldCodec,
186    {
187        crate::db::decode_persisted_structured_slot_payload(bytes, field_name)
188    }
189
190    #[doc(hidden)]
191    pub fn encode_persisted_option_scalar_slot_payload<T>(
192        value: &Option<T>,
193        field_name: &'static str,
194    ) -> Result<Vec<u8>, crate::error::InternalError>
195    where
196        T: PersistedScalar,
197    {
198        crate::db::encode_persisted_option_scalar_slot_payload(value, field_name)
199    }
200
201    #[doc(hidden)]
202    pub fn decode_persisted_option_scalar_slot_payload<T>(
203        bytes: &[u8],
204        field_name: &'static str,
205    ) -> Result<Option<T>, crate::error::InternalError>
206    where
207        T: PersistedScalar,
208    {
209        crate::db::decode_persisted_option_scalar_slot_payload(bytes, field_name)
210    }
211
212    #[doc(hidden)]
213    pub fn encode_persisted_scalar_slot_payload<T>(
214        value: &T,
215        field_name: &'static str,
216    ) -> Result<Vec<u8>, crate::error::InternalError>
217    where
218        T: PersistedScalar,
219    {
220        crate::db::encode_persisted_scalar_slot_payload(value, field_name)
221    }
222
223    #[doc(hidden)]
224    pub fn decode_persisted_scalar_slot_payload<T>(
225        bytes: &[u8],
226        field_name: &'static str,
227    ) -> Result<T, crate::error::InternalError>
228    where
229        T: PersistedScalar,
230    {
231        crate::db::decode_persisted_scalar_slot_payload(bytes, field_name)
232    }
233
234    #[doc(hidden)]
235    pub fn encode_persisted_slot_payload_by_kind<T>(
236        value: &T,
237        kind: crate::model::field::FieldKind,
238        field_name: &'static str,
239    ) -> Result<Vec<u8>, crate::error::InternalError>
240    where
241        T: crate::traits::PersistedByKindCodec,
242    {
243        crate::db::encode_persisted_slot_payload_by_kind(value, kind, field_name)
244    }
245
246    #[doc(hidden)]
247    pub fn decode_persisted_slot_payload_by_kind<T>(
248        bytes: &[u8],
249        kind: crate::model::field::FieldKind,
250        field_name: &'static str,
251    ) -> Result<T, crate::error::InternalError>
252    where
253        T: crate::traits::PersistedByKindCodec,
254    {
255        crate::db::decode_persisted_slot_payload_by_kind(bytes, kind, field_name)
256    }
257
258    #[doc(hidden)]
259    pub fn decode_persisted_option_slot_payload_by_kind<T>(
260        bytes: &[u8],
261        kind: crate::model::field::FieldKind,
262        field_name: &'static str,
263    ) -> Result<Option<T>, crate::error::InternalError>
264    where
265        T: crate::traits::PersistedByKindCodec,
266    {
267        crate::db::decode_persisted_option_slot_payload_by_kind(bytes, kind, field_name)
268    }
269
270    #[doc(hidden)]
271    pub fn encode_persisted_option_slot_payload_by_meta<T>(
272        value: &Option<T>,
273        field_name: &'static str,
274    ) -> Result<Vec<u8>, crate::error::InternalError>
275    where
276        T: crate::traits::PersistedFieldMetaCodec,
277    {
278        crate::db::encode_persisted_option_slot_payload_by_meta(value, field_name)
279    }
280
281    #[doc(hidden)]
282    pub fn decode_persisted_option_slot_payload_by_meta<T>(
283        bytes: &[u8],
284        field_name: &'static str,
285    ) -> Result<Option<T>, crate::error::InternalError>
286    where
287        T: crate::traits::PersistedFieldMetaCodec,
288    {
289        crate::db::decode_persisted_option_slot_payload_by_meta(bytes, field_name)
290    }
291
292    #[doc(hidden)]
293    pub fn encode_persisted_many_slot_payload_by_meta<T>(
294        value: &[T],
295        field_name: &'static str,
296    ) -> Result<Vec<u8>, crate::error::InternalError>
297    where
298        T: crate::traits::FieldTypeMeta + crate::traits::RuntimeValueEncode,
299    {
300        crate::db::encode_persisted_many_slot_payload_by_meta(value, field_name)
301    }
302
303    #[doc(hidden)]
304    pub fn decode_persisted_many_slot_payload_by_meta<T>(
305        bytes: &[u8],
306        field_name: &'static str,
307    ) -> Result<Vec<T>, crate::error::InternalError>
308    where
309        T: crate::traits::FieldTypeMeta + crate::traits::RuntimeValueDecode,
310    {
311        crate::db::decode_persisted_many_slot_payload_by_meta(bytes, field_name)
312    }
313
314    #[doc(hidden)]
315    pub fn encode_persisted_slot_payload_by_meta<T>(
316        value: &T,
317        field_name: &'static str,
318    ) -> Result<Vec<u8>, crate::error::InternalError>
319    where
320        T: crate::traits::PersistedFieldMetaCodec,
321    {
322        crate::db::encode_persisted_slot_payload_by_meta(value, field_name)
323    }
324
325    #[doc(hidden)]
326    pub fn decode_persisted_slot_payload_by_meta<T>(
327        bytes: &[u8],
328        field_name: &'static str,
329    ) -> Result<T, crate::error::InternalError>
330    where
331        T: crate::traits::PersistedFieldMetaCodec,
332    {
333        crate::db::decode_persisted_slot_payload_by_meta(bytes, field_name)
334    }
335
336    #[doc(hidden)]
337    pub fn encode_schema_runtime_field_slot<T>(
338        model: &'static crate::model::entity::EntityModel,
339        slot: usize,
340        value: &T,
341    ) -> Result<Vec<u8>, crate::error::InternalError>
342    where
343        T: ?Sized + crate::traits::RuntimeValueEncode,
344    {
345        let runtime_value = value.to_value();
346
347        crate::db::encode_runtime_value_into_slot(model, slot, &runtime_value)
348    }
349
350    #[doc(hidden)]
351    pub fn decode_schema_runtime_field_slot<T>(
352        model: &'static crate::model::entity::EntityModel,
353        slot: usize,
354        bytes: &[u8],
355        field_name: &'static str,
356    ) -> Result<T, crate::error::InternalError>
357    where
358        T: crate::traits::RuntimeValueDecode,
359    {
360        let runtime_value = crate::db::decode_slot_into_runtime_value(model, slot, bytes)?;
361
362        T::from_value(&runtime_value).ok_or_else(|| {
363            crate::error::InternalError::persisted_row_field_decode_failed(
364                field_name,
365                format!("payload does not match {}", std::any::type_name::<T>()),
366            )
367        })
368    }
369}