#[non_exhaustive]
#[derive(Clone, Debug)]
pub struct ReplicationConfig {
pub replica_path: String,
pub sync_url: Option<String>,
pub auth_token: Option<String>,
pub sync_interval_secs: u64,
}
impl ReplicationConfig {
pub fn new(replica_path: impl Into<String>) -> Self {
Self {
replica_path: replica_path.into(),
sync_url: None,
auth_token: None,
sync_interval_secs: 10,
}
}
pub fn with_sync_url(mut self, sync_url: impl Into<String>) -> Self {
self.sync_url = Some(sync_url.into());
self
}
pub fn with_auth_token(mut self, auth_token: impl Into<String>) -> Self {
self.auth_token = Some(auth_token.into());
self
}
pub fn with_sync_interval(mut self, secs: u64) -> Self {
self.sync_interval_secs = secs;
self
}
}
pub struct ReplicationManager;
#[derive(Debug, thiserror::Error, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum ReplicationError {
#[error("SQLite replication backend is not implemented for `{sync_url}`")]
Unsupported {
sync_url: String,
},
}
impl ReplicationManager {
#[cfg_attr(mutants, mutants::skip)]
pub fn start(config: ReplicationConfig) -> Result<(), ReplicationError> {
if let Some(sync_url) = config.sync_url {
return Err(ReplicationError::Unsupported { sync_url });
}
Ok(())
}
}
#[cfg(all(not(target_arch = "wasm32"), feature = "orm"))]
pub use rullst_orm::{Orm, RullstModel, RullstPool, async_trait, schema};
#[cfg(all(not(target_arch = "wasm32"), feature = "orm"))]
pub use sqlx;
#[cfg(all(not(target_arch = "wasm32"), feature = "orm"))]
pub use sqlx::FromRow;
#[cfg(all(not(target_arch = "wasm32"), feature = "orm"))]
#[cfg_attr(mutants, mutants::skip)]
pub fn safe_pool() -> Option<&'static rullst_orm::RullstPool> {
rullst_orm::Orm::try_pool().ok()
}
#[cfg(all(not(target_arch = "wasm32"), feature = "orm"))]
#[cfg_attr(mutants, mutants::skip)]
pub fn safe_driver() -> Option<&'static str> {
rullst_orm::Orm::try_driver().ok()
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::expect_used)]
mod tests {
use super::*;
#[tokio::test]
async fn test_db_get_pool() {
let config = ReplicationConfig::new("test.db")
.with_sync_interval(20)
.with_auth_token("secret");
assert_eq!(config.replica_path, "test.db");
assert_eq!(config.sync_interval_secs, 20);
assert_eq!(config.auth_token, Some("secret".to_string()));
}
#[test]
fn test_replication_config_with_sync_url() {
let config = ReplicationConfig::new("test.db").with_sync_url("http://sync");
assert_eq!(config.sync_url, Some("http://sync".to_string()));
}
#[test]
fn test_replication_config_with_auth_token() {
let config = ReplicationConfig::new("test.db").with_auth_token("token123");
assert_eq!(config.auth_token, Some("token123".to_string()));
}
#[test]
#[cfg(all(not(target_arch = "wasm32"), feature = "orm"))]
fn test_safe_pool_uninitialized() {
let pool = safe_pool();
assert!(pool.is_none());
}
#[test]
#[cfg(all(not(target_arch = "wasm32"), feature = "orm"))]
fn test_safe_driver_uninitialized() {
let driver = safe_driver();
assert!(driver.is_none());
}
#[test]
fn test_replication_manager_start() {
let config = ReplicationConfig::new("test.db")
.with_sync_url("https://sync.rullst.dev")
.with_sync_interval(1);
assert_eq!(
ReplicationManager::start(config),
Err(ReplicationError::Unsupported {
sync_url: "https://sync.rullst.dev".to_string(),
})
);
}
#[test]
fn test_replication_manager_start_no_url() {
let config = ReplicationConfig::new("test.db");
assert!(ReplicationManager::start(config).is_ok());
}
}