Skip to main content

rustauth_tokio_postgres/
stores.rs

1//! Bundled database adapter + SQL-backed rate-limit store for `tokio-postgres`.
2
3use std::sync::Arc;
4
5use rustauth_core::db::{auth_schema, AuthSchemaOptions, DbAdapter, DbSchema};
6use rustauth_core::error::RustAuthError;
7use rustauth_core::options::{RateLimitOptions, RustAuthOptions};
8
9use crate::adapter::TokioPostgresAdapter;
10use crate::rate_limit::TokioPostgresRateLimitStore;
11
12/// Configures and connects a [`TokioPostgresStores`] bundle.
13#[derive(Debug, Clone)]
14pub struct TokioPostgresStoresBuilder {
15    schema: DbSchema,
16}
17
18impl Default for TokioPostgresStoresBuilder {
19    fn default() -> Self {
20        Self::new()
21    }
22}
23
24impl TokioPostgresStoresBuilder {
25    pub fn new() -> Self {
26        Self {
27            schema: auth_schema(AuthSchemaOptions::default()),
28        }
29    }
30
31    #[must_use]
32    pub fn schema(mut self, schema: DbSchema) -> Self {
33        self.schema = schema;
34        self
35    }
36
37    pub async fn connect(self, database_url: &str) -> Result<TokioPostgresStores, RustAuthError> {
38        let adapter = TokioPostgresAdapter::connect_with_schema(database_url, self.schema).await?;
39        let rate_limit = TokioPostgresRateLimitStore::from(&adapter);
40        Ok(TokioPostgresStores {
41            adapter,
42            rate_limit,
43        })
44    }
45}
46
47/// Database adapter and matching SQL-backed rate-limit store sharing one client.
48#[derive(Clone)]
49pub struct TokioPostgresStores {
50    pub adapter: TokioPostgresAdapter,
51    pub rate_limit: TokioPostgresRateLimitStore,
52}
53
54impl std::fmt::Debug for TokioPostgresStores {
55    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        formatter
57            .debug_struct("TokioPostgresStores")
58            .field("adapter", &self.adapter)
59            .field("rate_limit", &self.rate_limit)
60            .finish()
61    }
62}
63
64impl TokioPostgresStores {
65    pub fn builder() -> TokioPostgresStoresBuilder {
66        TokioPostgresStoresBuilder::new()
67    }
68
69    pub async fn connect(database_url: &str) -> Result<Self, RustAuthError> {
70        Self::builder().connect(database_url).await
71    }
72
73    pub async fn connect_with_schema(
74        database_url: &str,
75        schema: DbSchema,
76    ) -> Result<Self, RustAuthError> {
77        Self::builder().schema(schema).connect(database_url).await
78    }
79
80    /// Wires the SQL-backed rate-limit store into [`RustAuthOptions`].
81    #[must_use]
82    pub fn apply_to_options(&self, options: RustAuthOptions) -> RustAuthOptions {
83        options.rate_limit(RateLimitOptions::database(self.rate_limit.clone()))
84    }
85
86    pub fn adapter(&self) -> Arc<dyn DbAdapter> {
87        Arc::new(self.adapter.clone())
88    }
89
90    pub fn adapter_ref(&self) -> &TokioPostgresAdapter {
91        &self.adapter
92    }
93}