Skip to main content

storage_kit/state_stores/config/
mod.rs

1//! Built-in state-store configuration.
2
3mod lance;
4mod postgres;
5mod redb;
6#[cfg(feature = "sqlite")]
7mod sqlite;
8
9use serde::{Deserialize, Serialize};
10
11use crate::StateStoreError;
12
13pub use lance::{LanceStateStoreConfig, LanceStateStoreLocation};
14pub use postgres::{PostgresStateStoreConfig, PostgresStateStoreTlsMode};
15pub use redb::{RedbStateStoreConfig, RedbStateStoreLocation};
16#[cfg(feature = "sqlite")]
17pub use sqlite::{SqliteStateStoreConfig, SqliteStateStoreLocation};
18
19/// Selects and configures one built-in state-store implementation.
20///
21/// Lance is always compiled. Redb, PostgreSQL, and SQLite/Turso require
22/// `redb`, `postgres`, and `sqlite`. These values contain configuration only; pass
23/// one to [`crate::StateStore::connect`] to obtain a shared store.
24///
25/// # Examples
26///
27/// ```
28/// use storage_kit::state::config::{StateStoreConfig, LanceStateStoreConfig};
29/// let config = StateStoreConfig::lance(LanceStateStoreConfig::memory());
30/// config.validate()?;
31/// # Ok::<(), storage_kit::StateStoreError>(())
32/// ```
33#[derive(Clone, Debug, Serialize, Deserialize)]
34pub enum StateStoreConfig {
35    /// Opens the embedded Lance state store.
36    Lance(LanceStateStoreConfig),
37    /// Opens the embedded Redb state store.
38    Redb(RedbStateStoreConfig),
39    /// Opens the PostgreSQL state store.
40    Postgres(PostgresStateStoreConfig),
41    /// Opens the embedded SQLite/Turso state store.
42    #[cfg(feature = "sqlite")]
43    Sqlite(SqliteStateStoreConfig),
44}
45
46impl StateStoreConfig {
47    /// Selects the embedded Lance StateStore.
48    ///
49    /// # Examples
50    ///
51    /// ```
52    /// use storage_kit::state::config::{LanceStateStoreConfig, StateStoreConfig};
53    /// let config = StateStoreConfig::lance(LanceStateStoreConfig::memory());
54    /// config.validate()?;
55    /// # Ok::<(), storage_kit::StateStoreError>(())
56    /// ```
57    #[must_use]
58    pub fn lance(config: LanceStateStoreConfig) -> Self {
59        Self::Lance(config)
60    }
61
62    /// Selects Redb.
63    ///
64    /// # Examples
65    ///
66    /// ```
67    /// use storage_kit::state::config::{StateStoreConfig, RedbStateStoreConfig};
68    /// let config = StateStoreConfig::redb(RedbStateStoreConfig::memory());
69    /// assert!(matches!(config, StateStoreConfig::Redb(_)));
70    /// config.validate()?;
71    /// # Ok::<(), storage_kit::StateStoreError>(())
72    /// ```
73    #[must_use]
74    pub fn redb(config: RedbStateStoreConfig) -> Self {
75        Self::Redb(config)
76    }
77
78    /// Selects PostgreSQL.
79    ///
80    /// This constructs configuration without connecting to PostgreSQL.
81    ///
82    /// # Examples
83    ///
84    /// ```
85    /// use storage_kit::state::config::{StateStoreConfig, PostgresStateStoreConfig};
86    /// let config = StateStoreConfig::postgres(PostgresStateStoreConfig::localhost("app", "user"));
87    /// config.validate()?;
88    /// # Ok::<(), storage_kit::StateStoreError>(())
89    /// ```
90    #[must_use]
91    pub fn postgres(config: PostgresStateStoreConfig) -> Self {
92        Self::Postgres(config)
93    }
94
95    /// Selects SQLite/Turso.
96    ///
97    /// # Examples
98    ///
99    /// ```
100    /// use storage_kit::state::config::{StateStoreConfig, SqliteStateStoreConfig};
101    /// let config = StateStoreConfig::sqlite(SqliteStateStoreConfig::memory());
102    /// config.validate()?;
103    /// # Ok::<(), storage_kit::StateStoreError>(())
104    /// ```
105    #[cfg(feature = "sqlite")]
106    #[must_use]
107    pub fn sqlite(config: SqliteStateStoreConfig) -> Self {
108        Self::Sqlite(config)
109    }
110
111    /// Validates the selected backend configuration.
112    ///
113    /// This performs local checks only and does not establish connectivity.
114    ///
115    /// # Errors
116    ///
117    /// Returns [`StateStoreError::InvalidConfig`] when the selected configuration
118    /// has an invalid location, connection setting, timeout, or cache bound. The
119    /// selected backend configuration's `validate` method describes its bounds.
120    ///
121    /// # Examples
122    ///
123    /// ```
124    /// use storage_kit::state::config::{StateStoreConfig, RedbStateStoreConfig};
125    /// let config = StateStoreConfig::redb(RedbStateStoreConfig::memory());
126    /// config.validate()?;
127    /// # Ok::<(), storage_kit::StateStoreError>(())
128    /// ```
129    pub fn validate(&self) -> Result<(), StateStoreError> {
130        match self {
131            Self::Lance(config) => config.validate(),
132            Self::Redb(config) => config.validate(),
133            Self::Postgres(config) => config.validate(),
134            #[cfg(feature = "sqlite")]
135            Self::Sqlite(config) => config.validate(),
136        }
137    }
138}
139
140impl From<LanceStateStoreConfig> for StateStoreConfig {
141    fn from(config: LanceStateStoreConfig) -> Self {
142        Self::Lance(config)
143    }
144}
145
146impl From<RedbStateStoreConfig> for StateStoreConfig {
147    fn from(config: RedbStateStoreConfig) -> Self {
148        Self::Redb(config)
149    }
150}
151
152impl From<PostgresStateStoreConfig> for StateStoreConfig {
153    fn from(config: PostgresStateStoreConfig) -> Self {
154        Self::Postgres(config)
155    }
156}
157
158#[cfg(feature = "sqlite")]
159impl From<SqliteStateStoreConfig> for StateStoreConfig {
160    fn from(config: SqliteStateStoreConfig) -> Self {
161        Self::Sqlite(config)
162    }
163}