Skip to main content

icydb_core/model/
entity.rs

1//! Module: model::entity
2//! Responsibility: runtime entity metadata emitted by derives and used by the engine.
3//! Does not own: full schema graphs, validators, or registry orchestration.
4//! Boundary: authoritative entity-level runtime contract for planning and execution.
5
6use crate::model::{field::FieldModel, index::IndexModel};
7
8///
9/// EntityModel
10///
11/// Macro-generated runtime schema snapshot for a single entity.
12/// The planner and predicate validator consume this model directly.
13///
14
15#[derive(Debug)]
16pub struct EntityModel {
17    /// Fully-qualified Rust type path (for diagnostics).
18    pub(crate) path: &'static str,
19
20    /// Stable external name used in keys and routing.
21    pub(crate) entity_name: &'static str,
22
23    /// Primary key field (points at an entry in `fields`).
24    pub(crate) primary_key: &'static FieldModel,
25
26    /// Stable primary-key slot within `fields`.
27    pub(crate) primary_key_slot: usize,
28
29    /// Ordered field list (authoritative for runtime planning).
30    pub(crate) fields: &'static [FieldModel],
31
32    /// Index definitions (field order is significant).
33    pub(crate) indexes: &'static [&'static IndexModel],
34}
35
36impl EntityModel {
37    /// Construct one generated runtime entity descriptor.
38    ///
39    /// This constructor exists for derive/codegen output. Runtime query and
40    /// executor code treat `EntityModel` values as already validated build-time
41    /// artifacts and do not perform defensive model-shape validation per call.
42    #[must_use]
43    #[doc(hidden)]
44    pub const fn generated(
45        path: &'static str,
46        entity_name: &'static str,
47        primary_key: &'static FieldModel,
48        primary_key_slot: usize,
49        fields: &'static [FieldModel],
50        indexes: &'static [&'static IndexModel],
51    ) -> Self {
52        Self {
53            path,
54            entity_name,
55            primary_key,
56            primary_key_slot,
57            fields,
58            indexes,
59        }
60    }
61
62    /// Return the fully-qualified Rust path for this entity.
63    #[must_use]
64    pub const fn path(&self) -> &'static str {
65        self.path
66    }
67
68    /// Return the stable external entity name.
69    #[must_use]
70    pub const fn name(&self) -> &'static str {
71        self.entity_name
72    }
73
74    /// Return the primary-key field descriptor.
75    #[must_use]
76    pub const fn primary_key(&self) -> &'static FieldModel {
77        self.primary_key
78    }
79
80    /// Return the stable primary-key slot within the ordered field table.
81    #[must_use]
82    pub const fn primary_key_slot(&self) -> usize {
83        self.primary_key_slot
84    }
85
86    /// Return the ordered runtime field descriptors.
87    #[must_use]
88    pub const fn fields(&self) -> &'static [FieldModel] {
89        self.fields
90    }
91
92    /// Return the runtime index descriptors.
93    #[must_use]
94    pub const fn indexes(&self) -> &'static [&'static IndexModel] {
95        self.indexes
96    }
97}
98
99/// Resolve one schema field name into its stable slot index.
100#[must_use]
101pub(crate) fn resolve_field_slot(model: &EntityModel, field_name: &str) -> Option<usize> {
102    model
103        .fields
104        .iter()
105        .position(|field| field.name == field_name)
106}