tempest-engine 0.0.2

Relational database engine for TempestDB
Documentation
use std::collections::{BTreeMap, HashSet};

use derive_more::{Deref, Display};
use serde::{Deserialize, Serialize};
use tempest_core::tempest_str::TempestStr;

use crate::types::TempestType;

#[derive(Debug, Clone)]
pub(crate) struct FlatField {
    pub name: TempestStr<'static>,
    pub ty: TempestType,
    /// For Enum fields: the concrete generic args at this instantiation site.
    /// Used by the row decoder to resolve payload field types.
    pub type_args: Vec<TypeExpr>,
}

#[derive(
    Debug,
    Default,
    Display,
    Clone,
    Copy,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    Deref,
    Serialize,
    Deserialize,
)]
pub struct FieldId(pub u32);

#[derive(
    Debug,
    Default,
    Display,
    Clone,
    Copy,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    Deref,
    Serialize,
    Deserialize,
)]
pub struct TypeId(pub u32);

#[derive(
    Debug,
    Default,
    Display,
    Clone,
    Copy,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    Deref,
    Serialize,
    Deserialize,
)]
pub struct TableId(pub u32);

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TypeExpr {
    Primitive(TempestType),
    Ref(TypeId, Vec<TypeExpr>),
    GenericParam(u32),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FieldDef {
    /// Name of this column.
    pub name: TempestStr<'static>,
    /// Type of this column.
    pub ty: TypeExpr,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StructSchema {
    /// The ID of the database this struct is scoped to, or `None` for global built-in types.
    pub database_id: Option<DatabaseId>,
    /// The scope-unique name of this struct.
    pub name: TempestStr<'static>,
    /// The generic parameters this struct takes in.
    pub generic_params: Vec<TempestStr<'static>>,
    /// The fields of this struct.
    pub fields: BTreeMap<FieldId, FieldDef>,
}

#[derive(
    Debug,
    Default,
    Display,
    Clone,
    Copy,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    Deref,
    Serialize,
    Deserialize,
)]
pub struct VariantId(pub u32);

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnumVariantDef {
    pub name: TempestStr<'static>,
    /// Field types for tuple variants (empty for unit variants).
    pub fields: Vec<TypeExpr>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnumSchema {
    /// The ID of the database this enum is scoped to, or `None` for global built-in types.
    pub database_id: Option<DatabaseId>,
    pub name: TempestStr<'static>,
    pub generic_params: Vec<TempestStr<'static>>,
    pub variants: BTreeMap<VariantId, EnumVariantDef>,
}

/// A catalog type — either a struct or an enum.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TypeSchema {
    Struct(StructSchema),
    Enum(EnumSchema),
}

impl TypeSchema {
    pub fn database_id(&self) -> Option<DatabaseId> {
        match self {
            Self::Struct(s) => s.database_id,
            Self::Enum(e) => e.database_id,
        }
    }

    pub fn name(&self) -> &TempestStr<'static> {
        match self {
            Self::Struct(s) => &s.name,
            Self::Enum(e) => &e.name,
        }
    }

    pub fn as_struct(&self) -> Option<&StructSchema> {
        if let Self::Struct(s) = self { Some(s) } else { None }
    }

    pub fn as_enum(&self) -> Option<&EnumSchema> {
        if let Self::Enum(e) = self { Some(e) } else { None }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TableSchema {
    /// The unique ID of the database this table belongs to.
    pub database_id: DatabaseId,
    /// Name of this table.
    pub name: TempestStr<'static>,
    /// The ID of the [`TypeSchema`] that this table has.
    pub type_id: TypeId,
    /// The generic arguments supplied to this struct.
    pub generic_args: Vec<TypeExpr>,
    /// Paths of field IDs for each primary key column, most significant first.
    /// Each inner Vec is a root-to-leaf path through the type hierarchy.
    /// e.g. `[[FieldId(1), FieldId(0)]]` means: top-level field 1, then nested field 0 within it.
    pub primary_key: Vec<Vec<FieldId>>,
}

#[derive(
    Debug,
    Default,
    Display,
    Clone,
    Copy,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    Deref,
    Serialize,
    Deserialize,
)]
pub struct DatabaseId(pub u32);

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DatabaseSchema {
    /// Name of this dtabase.
    pub name: TempestStr<'static>,
    /// The tables this database contains.
    pub tables: HashSet<TableId>,
    /// The types this database contains.
    pub types: HashSet<TypeId>,
}

impl DatabaseSchema {
    pub(crate) fn new(name: TempestStr<'static>) -> Self {
        Self {
            name,
            tables: HashSet::new(),
            types: HashSet::new(),
        }
    }
}