use std::sync::Arc;
use rustauth_core::db::{auth_schema, AuthSchemaOptions, DbAdapter, DbSchema};
use rustauth_core::error::RustAuthError;
use rustauth_core::options::{RateLimitOptions, RustAuthOptions};
macro_rules! sql_stores {
($stores:ident, $builder:ident, $adapter:ty, $rate_limit:ty) => {
#[derive(Debug, Clone)]
pub struct $stores {
pub adapter: $adapter,
pub rate_limit: $rate_limit,
}
#[derive(Debug, Clone)]
pub struct $builder {
schema: DbSchema,
}
impl Default for $builder {
fn default() -> Self {
Self::new()
}
}
impl $builder {
pub fn new() -> Self {
Self {
schema: auth_schema(AuthSchemaOptions::default()),
}
}
#[must_use]
pub fn schema(mut self, schema: DbSchema) -> Self {
self.schema = schema;
self
}
pub async fn connect(self, database_url: &str) -> Result<$stores, RustAuthError> {
let adapter = <$adapter>::connect_with_schema(database_url, self.schema).await?;
let rate_limit = <$rate_limit>::from(&adapter);
Ok($stores {
adapter,
rate_limit,
})
}
}
impl $stores {
pub fn builder() -> $builder {
$builder::new()
}
pub async fn connect(database_url: &str) -> Result<Self, RustAuthError> {
Self::builder().connect(database_url).await
}
pub async fn connect_with_schema(
database_url: &str,
schema: DbSchema,
) -> Result<Self, RustAuthError> {
Self::builder().schema(schema).connect(database_url).await
}
#[must_use]
pub fn apply_to_options(&self, options: RustAuthOptions) -> RustAuthOptions {
options.rate_limit(RateLimitOptions::database(self.rate_limit.clone()))
}
pub fn adapter(&self) -> Arc<dyn DbAdapter> {
Arc::new(self.adapter.clone())
}
pub fn adapter_ref(&self) -> &$adapter {
&self.adapter
}
}
};
}
#[cfg(feature = "sqlite")]
sql_stores!(
SqliteStores,
SqliteStoresBuilder,
crate::SqliteAdapter,
crate::SqliteRateLimitStore
);
#[cfg(feature = "postgres")]
sql_stores!(
PostgresStores,
PostgresStoresBuilder,
crate::PostgresAdapter,
crate::PostgresRateLimitStore
);
#[cfg(feature = "mysql")]
sql_stores!(
MySqlStores,
MySqlStoresBuilder,
crate::MySqlAdapter,
crate::MySqlRateLimitStore
);