Skip to main content

icydb_core/traits/
mod.rs

1//! Module: traits
2//!
3//! Responsibility: foundational kind, field metadata, projection, and wrapper
4//! contracts awaiting narrower domain ownership.
5//! Does not own: entity composition, key taxonomy, runtime value conversion,
6//! visitor traversal, executor policy, or public facade DTO behavior.
7//! Boundary: remaining reusable contracts consumed throughout `icydb-core`.
8
9use crate::{
10    model::field::{FieldKind, FieldModel, FieldStorageDecode},
11    value::{InputValue, Value},
12    visitor::Visitable,
13};
14use serde::de::DeserializeOwned;
15use std::collections::{BTreeMap, BTreeSet};
16
17// ============================================================================
18// FOUNDATIONAL KINDS
19// ============================================================================
20//
21// These traits define *where* something lives in the system,
22// not what data it contains.
23//
24
25///
26/// Path
27/// Fully-qualified schema path.
28///
29
30pub trait Path {
31    const PATH: &'static str;
32}
33
34///
35/// Kind
36/// Marker for all schema/runtime nodes.
37///
38
39pub trait Kind: Path + 'static {}
40impl<T> Kind for T where T: Path + 'static {}
41
42///
43/// CanisterKind
44/// Marker for canister namespaces
45///
46
47pub trait CanisterKind: Kind {
48    /// Stable memory slot used for commit marker storage.
49    const COMMIT_MEMORY_ID: u8;
50
51    /// Durable stable-memory allocation key for commit marker storage.
52    const COMMIT_STABLE_KEY: &'static str;
53}
54
55///
56/// StoreKind
57/// Marker for data stores bound to a canister
58///
59
60pub trait StoreKind: Kind {
61    type Canister: CanisterKind;
62}
63
64// ============================================================================
65// TYPE SYSTEM CONTRACTS
66// ============================================================================
67//
68// These traits define behavioral expectations for schema-defined types.
69//
70
71///
72/// TypeKind
73///
74/// Any schema-defined data type.
75///
76/// This is a *strong* contract and should only be required
77/// where full lifecycle semantics are needed.
78///
79
80pub trait TypeKind: Kind + Clone + DeserializeOwned + Visitable + PartialEq {}
81
82impl<T> TypeKind for T where T: Kind + Clone + DeserializeOwned + PartialEq + Visitable {}
83
84///
85/// FieldTypeMeta
86///
87/// Static runtime field metadata for one schema-facing value type.
88/// This is the single authority for generated field kind and storage-decode
89/// metadata, so callers do not need per-type inherent constants.
90///
91
92pub trait FieldTypeMeta {
93    /// Semantic field kind used for runtime planning and validation.
94    const KIND: FieldKind;
95
96    /// Persisted decode contract used by row and payload decoding.
97    const STORAGE_DECODE: FieldStorageDecode;
98
99    /// Known nested fields for generated structured records.
100    const NESTED_FIELDS: &'static [FieldModel] = &[];
101}
102
103impl<T> FieldTypeMeta for Option<T>
104where
105    T: FieldTypeMeta,
106{
107    const KIND: FieldKind = T::KIND;
108    const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
109    const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
110}
111
112impl<T> FieldTypeMeta for Box<T>
113where
114    T: FieldTypeMeta,
115{
116    const KIND: FieldKind = T::KIND;
117    const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
118    const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
119}
120
121// Standard containers mirror the generated collection-wrapper contract: their
122// semantic kind remains structural, but persisted decode routes through the
123// shared structural `Value` storage seam instead of leaf-by-leaf scalar decode.
124impl<T> FieldTypeMeta for Vec<T>
125where
126    T: FieldTypeMeta,
127{
128    const KIND: FieldKind = FieldKind::List(&T::KIND);
129    const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
130}
131
132impl<T> FieldTypeMeta for BTreeSet<T>
133where
134    T: FieldTypeMeta,
135{
136    const KIND: FieldKind = FieldKind::Set(&T::KIND);
137    const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
138}
139
140impl<K, V> FieldTypeMeta for BTreeMap<K, V>
141where
142    K: FieldTypeMeta,
143    V: FieldTypeMeta,
144{
145    const KIND: FieldKind = FieldKind::Map {
146        key: &K::KIND,
147        value: &V::KIND,
148    };
149    const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
150}
151
152/// ============================================================================
153/// QUERY VALUE BOUNDARIES
154/// ============================================================================
155
156/// Name-based field input projection used before accepted-catalog admission.
157pub trait AuthoredFieldProjection {
158    /// Resolve one authored field value by stable field slot index.
159    fn get_input_value_by_index(&self, index: usize) -> Option<InputValue>;
160}
161
162pub trait FieldProjection {
163    /// Resolve one field value by stable field slot index.
164    fn get_value_by_index(&self, index: usize) -> Option<Value>;
165}
166
167/// ============================================================================
168/// MISC HELPERS
169/// ============================================================================
170
171///
172/// Inner
173///
174/// For newtypes to expose their innermost value.
175///
176
177pub trait Inner<T> {
178    fn inner(&self) -> &T;
179    fn into_inner(self) -> T;
180}
181
182///
183/// Repr
184///
185/// Internal representation boundary for scalar wrapper types.
186///
187
188pub trait Repr {
189    type Inner;
190
191    fn repr(&self) -> Self::Inner;
192    fn from_repr(inner: Self::Inner) -> Self;
193}