icydb-core 0.72.2

IcyDB — A type-safe, embedded ORM and schema system for the Internet Computer
Documentation
//! Module: model::entity
//! Responsibility: module-local ownership and contracts for model::entity.
//! Does not own: cross-module orchestration outside this module.
//! Boundary: exposes this module API while keeping implementation details internal.

//! Runtime-only entity schema surface generated by macros.
//!
//! This model intentionally includes only:
//! - entity metadata (path + stable external name)
//! - ordered fields
//! - primary key field
//! - index definitions
//!
//! It intentionally excludes:
//! - validators/sanitizers/defaults
//! - relations or full schema graphs
//! - JSON schema ingestion or global registries
//!
//! Stability: this is the authoritative runtime contract for planning and
//! execution. Additive changes are expected; breaking changes require a
//! coordinated version bump across the engine.
//!
//! Field names are entity-scoped. Callers that combine entities must
//! namespace by entity at the call site.

use crate::model::{field::FieldModel, index::IndexModel};

///
/// EntityModel
///
/// Macro-generated runtime schema snapshot for a single entity.
/// The planner and predicate validator consume this model directly.
///

#[derive(Debug)]
pub struct EntityModel {
    /// Fully-qualified Rust type path (for diagnostics).
    pub(crate) path: &'static str,

    /// Stable external name used in keys and routing.
    pub(crate) entity_name: &'static str,

    /// Primary key field (points at an entry in `fields`).
    pub(crate) primary_key: &'static FieldModel,

    /// Ordered field list (authoritative for runtime planning).
    pub(crate) fields: &'static [FieldModel],

    /// Index definitions (field order is significant).
    pub(crate) indexes: &'static [&'static IndexModel],
}

impl EntityModel {
    /// Build one runtime entity schema descriptor.
    #[must_use]
    pub const fn new(
        path: &'static str,
        entity_name: &'static str,
        primary_key: &'static FieldModel,
        fields: &'static [FieldModel],
        indexes: &'static [&'static IndexModel],
    ) -> Self {
        Self {
            path,
            entity_name,
            primary_key,
            fields,
            indexes,
        }
    }

    /// Return the fully-qualified Rust path for this entity.
    #[must_use]
    pub const fn path(&self) -> &'static str {
        self.path
    }

    /// Return the stable external entity name.
    #[must_use]
    pub const fn name(&self) -> &'static str {
        self.entity_name
    }

    /// Return the primary-key field descriptor.
    #[must_use]
    pub const fn primary_key(&self) -> &'static FieldModel {
        self.primary_key
    }

    /// Return the ordered runtime field descriptors.
    #[must_use]
    pub const fn fields(&self) -> &'static [FieldModel] {
        self.fields
    }

    /// Return the runtime index descriptors.
    #[must_use]
    pub const fn indexes(&self) -> &'static [&'static IndexModel] {
        self.indexes
    }
}

/// Resolve one schema field name into its stable slot index.
#[must_use]
pub(crate) fn resolve_field_slot(model: &EntityModel, field_name: &str) -> Option<usize> {
    model
        .fields
        .iter()
        .position(|field| field.name == field_name)
}

/// Resolve the primary-key field into its stable slot index.
#[must_use]
pub(crate) fn resolve_primary_key_slot(model: &EntityModel) -> Option<usize> {
    model
        .fields
        .iter()
        .position(|field| std::ptr::eq(field, model.primary_key))
}