//! Storage abstraction: routes to the correct backend by entity kind. use crate::schema::{EntityKind, TidalError}; use crate::storage::{InMemoryBackend, StorageEngine}; /// Wraps either in-memory backends (ephemeral mode) or a fjall storage /// (persistent mode) behind a uniform interface. /// /// M3 provides three backends: items, users, creators. In ephemeral mode /// each is an independent `InMemoryBackend`; in persistent mode they share /// a single `FjallStorage` with three keyspaces. pub enum StorageBox { Memory { items: InMemoryBackend, users: InMemoryBackend, creators: InMemoryBackend, }, Fjall(crate::storage::FjallStorage), } impl StorageBox { /// Reference to the items storage engine. pub(super) fn items_engine(&self) -> &dyn StorageEngine { match self { Self::Memory { items, .. } => items, Self::Fjall(f) => f.backend(EntityKind::Item), } } /// Reference to the users storage engine. pub(super) fn users_engine(&self) -> &dyn StorageEngine { match self { Self::Memory { users, .. } => users, Self::Fjall(f) => f.backend(EntityKind::User), } } /// Reference to the creators storage engine. pub(super) fn creators_engine(&self) -> &dyn StorageEngine { match self { Self::Memory { creators, .. } => creators, Self::Fjall(f) => f.backend(EntityKind::Creator), } } /// Flush all buffered writes to durable storage. pub(super) fn flush(&self) -> crate::Result<()> { match self { Self::Memory { .. } => Ok(()), Self::Fjall(f) => f.flush_all().map_err(TidalError::from), } } }