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, PersistedScalar,
64        ScalarSlotValueRef, ScalarValueRef,
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
79    #[doc(hidden)]
80    #[must_use]
81    pub fn encode_generated_structural_text_payload_bytes(value: &str) -> Vec<u8> {
82        crate::db::encode_generated_structural_text_payload_bytes(value)
83    }
84
85    #[doc(hidden)]
86    #[must_use]
87    pub fn encode_generated_structural_list_payload_bytes(items: &[&[u8]]) -> Vec<u8> {
88        crate::db::encode_generated_structural_list_payload_bytes(items)
89    }
90
91    #[doc(hidden)]
92    #[must_use]
93    pub fn encode_generated_structural_map_payload_bytes(entries: &[(&[u8], &[u8])]) -> Vec<u8> {
94        crate::db::encode_generated_structural_map_payload_bytes(entries)
95    }
96
97    #[doc(hidden)]
98    #[must_use]
99    pub fn encode_generated_structural_enum_payload_bytes(
100        variant: &str,
101        path: Option<&str>,
102        payload: Option<&[u8]>,
103    ) -> Vec<u8> {
104        crate::db::encode_generated_structural_enum_payload_bytes(variant, path, payload)
105    }
106
107    #[doc(hidden)]
108    pub fn decode_generated_structural_text_payload_bytes(
109        raw_bytes: &[u8],
110    ) -> Result<String, crate::error::InternalError> {
111        crate::db::decode_generated_structural_text_payload_bytes(raw_bytes)
112    }
113
114    #[doc(hidden)]
115    pub fn decode_generated_structural_list_payload_bytes(
116        raw_bytes: &[u8],
117    ) -> Result<Vec<&[u8]>, crate::error::InternalError> {
118        crate::db::decode_generated_structural_list_payload_bytes(raw_bytes)
119    }
120
121    #[doc(hidden)]
122    pub fn decode_generated_structural_map_payload_bytes(
123        raw_bytes: &[u8],
124    ) -> Result<crate::db::GeneratedStructuralMapPayloadSlices<'_>, crate::error::InternalError>
125    {
126        crate::db::decode_generated_structural_map_payload_bytes(raw_bytes)
127    }
128
129    #[doc(hidden)]
130    pub fn decode_generated_structural_enum_payload_bytes(
131        raw_bytes: &[u8],
132    ) -> Result<crate::db::GeneratedStructuralEnumPayload<'_>, crate::error::InternalError> {
133        crate::db::decode_generated_structural_enum_payload_bytes(raw_bytes)
134    }
135
136    #[doc(hidden)]
137    pub fn generated_persisted_structured_payload_decode_failed(
138        detail: impl std::fmt::Display,
139    ) -> crate::error::InternalError {
140        crate::db::generated_persisted_structured_payload_decode_failed(detail)
141    }
142
143    #[doc(hidden)]
144    pub fn encode_persisted_structured_many_slot_payload<T>(
145        value: &[T],
146        field_name: &'static str,
147    ) -> Result<Vec<u8>, crate::error::InternalError>
148    where
149        T: crate::traits::PersistedStructuredFieldCodec,
150    {
151        crate::db::encode_persisted_structured_many_slot_payload(value, field_name)
152    }
153
154    #[doc(hidden)]
155    pub fn decode_persisted_structured_many_slot_payload<T>(
156        bytes: &[u8],
157        field_name: &'static str,
158    ) -> Result<Vec<T>, crate::error::InternalError>
159    where
160        T: crate::traits::PersistedStructuredFieldCodec,
161    {
162        crate::db::decode_persisted_structured_many_slot_payload(bytes, field_name)
163    }
164
165    #[doc(hidden)]
166    pub fn encode_persisted_structured_slot_payload<T>(
167        value: &T,
168        field_name: &'static str,
169    ) -> Result<Vec<u8>, crate::error::InternalError>
170    where
171        T: crate::traits::PersistedStructuredFieldCodec,
172    {
173        crate::db::encode_persisted_structured_slot_payload(value, field_name)
174    }
175
176    #[doc(hidden)]
177    pub fn decode_persisted_structured_slot_payload<T>(
178        bytes: &[u8],
179        field_name: &'static str,
180    ) -> Result<T, crate::error::InternalError>
181    where
182        T: crate::traits::PersistedStructuredFieldCodec,
183    {
184        crate::db::decode_persisted_structured_slot_payload(bytes, field_name)
185    }
186
187    #[doc(hidden)]
188    pub fn encode_persisted_option_scalar_slot_payload<T>(
189        value: &Option<T>,
190        field_name: &'static str,
191    ) -> Result<Vec<u8>, crate::error::InternalError>
192    where
193        T: PersistedScalar,
194    {
195        crate::db::encode_persisted_option_scalar_slot_payload(value, field_name)
196    }
197
198    #[doc(hidden)]
199    pub fn decode_persisted_option_scalar_slot_payload<T>(
200        bytes: &[u8],
201        field_name: &'static str,
202    ) -> Result<Option<T>, crate::error::InternalError>
203    where
204        T: PersistedScalar,
205    {
206        crate::db::decode_persisted_option_scalar_slot_payload(bytes, field_name)
207    }
208
209    #[doc(hidden)]
210    pub fn encode_persisted_scalar_slot_payload<T>(
211        value: &T,
212        field_name: &'static str,
213    ) -> Result<Vec<u8>, crate::error::InternalError>
214    where
215        T: PersistedScalar,
216    {
217        crate::db::encode_persisted_scalar_slot_payload(value, field_name)
218    }
219
220    #[doc(hidden)]
221    pub fn decode_persisted_scalar_slot_payload<T>(
222        bytes: &[u8],
223        field_name: &'static str,
224    ) -> Result<T, crate::error::InternalError>
225    where
226        T: PersistedScalar,
227    {
228        crate::db::decode_persisted_scalar_slot_payload(bytes, field_name)
229    }
230
231    #[doc(hidden)]
232    pub fn encode_persisted_slot_payload_by_kind<T>(
233        value: &T,
234        kind: crate::model::field::FieldKind,
235        field_name: &'static str,
236    ) -> Result<Vec<u8>, crate::error::InternalError>
237    where
238        T: crate::traits::PersistedByKindCodec,
239    {
240        crate::db::encode_persisted_slot_payload_by_kind(value, kind, field_name)
241    }
242
243    #[doc(hidden)]
244    pub fn decode_persisted_slot_payload_by_kind<T>(
245        bytes: &[u8],
246        kind: crate::model::field::FieldKind,
247        field_name: &'static str,
248    ) -> Result<T, crate::error::InternalError>
249    where
250        T: crate::traits::PersistedByKindCodec,
251    {
252        crate::db::decode_persisted_slot_payload_by_kind(bytes, kind, field_name)
253    }
254
255    #[doc(hidden)]
256    pub fn decode_persisted_option_slot_payload_by_kind<T>(
257        bytes: &[u8],
258        kind: crate::model::field::FieldKind,
259        field_name: &'static str,
260    ) -> Result<Option<T>, crate::error::InternalError>
261    where
262        T: crate::traits::PersistedByKindCodec,
263    {
264        crate::db::decode_persisted_option_slot_payload_by_kind(bytes, kind, field_name)
265    }
266
267    #[doc(hidden)]
268    pub fn encode_persisted_option_slot_payload_by_meta<T>(
269        value: &Option<T>,
270        field_name: &'static str,
271    ) -> Result<Vec<u8>, crate::error::InternalError>
272    where
273        T: crate::traits::PersistedFieldMetaCodec,
274    {
275        crate::db::encode_persisted_option_slot_payload_by_meta(value, field_name)
276    }
277
278    #[doc(hidden)]
279    pub fn decode_persisted_option_slot_payload_by_meta<T>(
280        bytes: &[u8],
281        field_name: &'static str,
282    ) -> Result<Option<T>, crate::error::InternalError>
283    where
284        T: crate::traits::PersistedFieldMetaCodec,
285    {
286        crate::db::decode_persisted_option_slot_payload_by_meta(bytes, field_name)
287    }
288
289    #[doc(hidden)]
290    pub fn encode_persisted_many_slot_payload_by_meta<T>(
291        value: &[T],
292        field_name: &'static str,
293    ) -> Result<Vec<u8>, crate::error::InternalError>
294    where
295        T: crate::traits::FieldTypeMeta + crate::traits::RuntimeValueEncode,
296    {
297        crate::db::encode_persisted_many_slot_payload_by_meta(value, field_name)
298    }
299
300    #[doc(hidden)]
301    pub fn decode_persisted_many_slot_payload_by_meta<T>(
302        bytes: &[u8],
303        field_name: &'static str,
304    ) -> Result<Vec<T>, crate::error::InternalError>
305    where
306        T: crate::traits::FieldTypeMeta + crate::traits::RuntimeValueDecode,
307    {
308        crate::db::decode_persisted_many_slot_payload_by_meta(bytes, field_name)
309    }
310
311    #[doc(hidden)]
312    pub fn encode_persisted_slot_payload_by_meta<T>(
313        value: &T,
314        field_name: &'static str,
315    ) -> Result<Vec<u8>, crate::error::InternalError>
316    where
317        T: crate::traits::PersistedFieldMetaCodec,
318    {
319        crate::db::encode_persisted_slot_payload_by_meta(value, field_name)
320    }
321
322    #[doc(hidden)]
323    pub fn decode_persisted_slot_payload_by_meta<T>(
324        bytes: &[u8],
325        field_name: &'static str,
326    ) -> Result<T, crate::error::InternalError>
327    where
328        T: crate::traits::PersistedFieldMetaCodec,
329    {
330        crate::db::decode_persisted_slot_payload_by_meta(bytes, field_name)
331    }
332
333    #[doc(hidden)]
334    pub fn encode_schema_runtime_field_slot<T>(
335        model: &'static crate::model::entity::EntityModel,
336        slot: usize,
337        value: &T,
338    ) -> Result<Vec<u8>, crate::error::InternalError>
339    where
340        T: ?Sized + crate::traits::RuntimeValueEncode,
341    {
342        let runtime_value = value.to_value();
343
344        crate::db::encode_runtime_value_into_slot(model, slot, &runtime_value)
345    }
346
347    #[doc(hidden)]
348    pub fn decode_schema_runtime_field_slot<T>(
349        model: &'static crate::model::entity::EntityModel,
350        slot: usize,
351        bytes: &[u8],
352        field_name: &'static str,
353    ) -> Result<T, crate::error::InternalError>
354    where
355        T: crate::traits::RuntimeValueDecode,
356    {
357        let runtime_value = crate::db::decode_slot_into_runtime_value(model, slot, bytes)?;
358
359        T::from_value(&runtime_value).ok_or_else(|| {
360            crate::error::InternalError::persisted_row_field_decode_failed(
361                field_name,
362                format!("payload does not match {}", std::any::type_name::<T>()),
363            )
364        })
365    }
366}