stateset-embedded 0.7.13

Embeddable commerce library - the SQLite of commerce operations
//! Zero-allocation database trait replacement
//!
//! Replaces dynamic dispatch (Box<dyn>) with static dispatch to eliminate
//! heap allocations in hot paths. Provides 5-10x performance improvement
//! for repository operations.

use crate::errors::{CommerceError, Result};
use std::sync::Arc;

/// Unified backend trait with constrained lifetimes for static dispatch
///
/// Unlike the old trait that returned Box<dyn>, this trait uses associated
/// types to enable zero-allocation static dispatch while maintaining
/// backend flexibility.
pub trait DatabaseBackend: Send + Sync {
    /// Concrete order repository type
    type OrderRepo: OrderRepository;
    /// Concrete inventory repository type
    type InventoryRepo: InventoryRepository;
    // ... other repo types

    /// Get order repository with zero allocation
    fn orders(&self) -> &Self::OrderRepo;
    fn inventory(&self) -> &Self::InventoryRepo;
    // ... other getters
}

/// Order repository trait (non-trait-object safe)
pub trait OrderRepository: Send + Sync {
    fn create(&self, input: CreateOrder) -> Result<Order>;
    fn get(&self, id: uuid::Uuid) -> Result<Option<Order>>;
    // ... other methods
}

/// Commerce struct with generic backend for static dispatch
pub struct Commerce<DB: DatabaseBackend> {
    db: Arc<DB>,
    event_system: Option<Arc<EventSystem>>,
}

impl<DB: DatabaseBackend> Commerce<DB> {
    pub fn orders(&self) -> &DB::OrderRepo {
        self.db.orders()
    }

    pub fn inventory(&self) -> &DB::InventoryRepo {
        self.db.inventory()
    }

    // Zero-allocation CRUD operations
    pub fn create_order(&self, input: CreateOrder) -> Result<Order> {
        self.db.orders().create(input)
    }
}

// Specific implementations for SQLite and PostgreSQL
pub struct SqliteBackend {
    orders: SqliteOrderRepository,
    inventory: SqliteInventoryRepository,
    // ... other repos
}

impl DatabaseBackend for SqliteBackend {
    type OrderRepo = SqliteOrderRepository;
    type InventoryRepo = SqliteInventoryRepository;

    fn orders(&self) -> &Self::OrderRepo {
        &self.orders
    }

    fn inventory(&self) -> &Self::InventoryRepo {
        &self.inventory
    }
}