Skip to main content

vibe_ready/api/
engine_context.rs

1use crate::api::engine_config::VibeEngineConfig;
2use crate::api::engine_error::{VibeEngineError, VibeEngineErrorCode};
3use crate::log::logger::VibeLogger;
4use crate::status::status_manager::VibeStatusManager;
5use crate::store::db::db_client::VibeDbClient;
6use std::sync::Arc;
7
8/// Low-level context shared by engine services.
9///
10/// Most applications should use [`crate::VibeEngine`] instead. This type is
11/// exposed for advanced integrations that need direct access to the database
12/// or logging clients initialized by the engine.
13pub struct VibeEngineContext {
14    status_manager: VibeStatusManager,
15    engine_config: VibeEngineConfig,
16    db_client: VibeDbClient,
17    log_db_client: Arc<VibeLogger>,
18}
19
20impl VibeEngineContext {
21    /// Creates a context from validated engine configuration.
22    ///
23    /// # Returns
24    ///
25    /// `Ok(VibeEngineContext)` when log and work stores open successfully, or
26    /// [`VibeEngineError`] when initialization fails.
27    ///
28    /// # Examples
29    ///
30    /// ```no_run
31    /// use vibe_ready::{VibeEngineConfig, VibeEngineContext, VibeResult};
32    ///
33    /// # fn demo() -> VibeResult<()> {
34    /// let context = VibeEngineContext::new(VibeEngineConfig::builder().build())?;
35    /// futures::executor::block_on(context.close())?;
36    /// # Ok(())
37    /// # }
38    /// ```
39    pub fn new(config: VibeEngineConfig) -> Result<Self, VibeEngineError> {
40        let log_config = config.log_config();
41        let store_config = config.store_config();
42        let is_encrypt: bool = store_config.encrypt;
43        // log db
44        let mut log_store_path = config.app_store_path();
45        log_store_path.push("log");
46        //
47        let db_log_ret = VibeLogger::try_new(
48            log_config.backend,
49            log_store_path,
50            is_encrypt,
51            format!("{}:{}", config.namespace(), config.app_name()),
52            log_config.level,
53            log_config.write_to_store,
54            log_config.output_stdout,
55            log_config.max_rows,
56        );
57
58        let db_log = match db_log_ret {
59            Ok(l) => l,
60            Err(_) => {
61                return Err(VibeEngineError::from_error_code(
62                    VibeEngineErrorCode::LogDatabaseOpenFailed,
63                ))
64            }
65        };
66
67        let db_client = VibeDbClient::with_backend(store_config.backend);
68        let mut work_store_path = config.app_store_path();
69        work_store_path.push("work");
70        let work_user_id = format!("{}:{}", config.namespace(), config.app_name());
71        futures::executor::block_on(db_client.try_open(work_store_path, work_user_id, is_encrypt))
72            .map_err(|error| {
73                VibeEngineError::from_error_code(VibeEngineErrorCode::WorkDatabaseOpenFailed)
74                    .with_source(error.to_string())
75            })?;
76        Ok(VibeEngineContext {
77            status_manager: VibeStatusManager::new(),
78            engine_config: config,
79            db_client,
80            log_db_client: Arc::new(db_log),
81        })
82    }
83}
84
85impl VibeEngineContext {
86    /// Returns the initialized log client.
87    ///
88    /// # Returns
89    ///
90    /// A shared reference to the internal logger used by [`crate::VibeEngine`].
91    pub fn log_db_client(&self) -> &Arc<VibeLogger> {
92        &self.log_db_client
93    }
94
95    /// Returns the initialized work-store database client.
96    ///
97    /// # Returns
98    ///
99    /// A reference to the [`crate::VibeDbClient`] used by high-level storage APIs.
100    pub fn db_client(&self) -> &VibeDbClient {
101        &self.db_client
102    }
103
104    /// Returns the validated engine configuration used to create this context.
105    ///
106    /// # Returns
107    ///
108    /// A reference to the immutable [`VibeEngineConfig`] stored by the context.
109    pub fn engine_config(&self) -> &VibeEngineConfig {
110        &self.engine_config
111    }
112
113    /// Closes listeners, work-store resources, and log-store resources.
114    ///
115    /// # Returns
116    ///
117    /// `Ok(())` when all resources close, or [`VibeEngineError`] on close failure.
118    pub async fn close(&self) -> Result<(), VibeEngineError> {
119        self.status_manager
120            .set_connection_status_listener(None)
121            .await;
122        self.db_client.close().await?;
123        self.log_db_client.close().map_err(|_| {
124            VibeEngineError::from_error_code(VibeEngineErrorCode::LogDatabaseOpenFailed)
125        })?;
126        Ok(())
127    }
128}
129
130#[cfg(test)]
131mod strict_tests {
132    use super::*;
133    include!(concat!(
134        env!("CARGO_MANIFEST_DIR"),
135        "/test/unit/api/engine_context_tests.rs"
136    ));
137}