auth-framework 0.5.0-rc19

A comprehensive, production-ready authentication and authorization framework for Rust applications
Documentation
use crate::config::StorageConfig;
use crate::errors::{AuthError, Result};
use crate::storage::{AuthStorage, MemoryStorage};
use std::sync::Arc;

pub(crate) async fn build_storage_backend(
    config: &StorageConfig,
    _pool_size: Option<u32>,
) -> Result<Arc<dyn AuthStorage>> {
    match config {
        StorageConfig::Memory => Ok(Arc::new(MemoryStorage::new())),
        #[cfg(feature = "redis-storage")]
        StorageConfig::Redis { url, key_prefix } => {
            crate::storage::RedisStorage::new(url, key_prefix)
                .map(|storage| Arc::new(storage) as Arc<dyn AuthStorage>)
                .map_err(|e| {
                    AuthError::configuration(format!("Failed to create Redis storage: {e}"))
                })
        }
        #[cfg(feature = "postgres-storage")]
        StorageConfig::Postgres {
            connection_string,
            table_prefix: _,
        } => {
            use sqlx::postgres::PgPoolOptions;

            let pool = PgPoolOptions::new()
                .max_connections(_pool_size.unwrap_or(10))
                .connect(connection_string)
                .await
                .map_err(|e| {
                    AuthError::configuration(format!("Failed to connect PostgreSQL storage: {e}"))
                })?;

            let storage = crate::storage::postgres::PostgresStorage::new(pool);
            storage.migrate().await.map_err(|e| {
                AuthError::configuration(format!("Failed to initialize PostgreSQL storage: {e}"))
            })?;

            Ok(Arc::new(storage))
        }
        #[cfg(feature = "mysql-storage")]
        StorageConfig::MySQL {
            connection_string,
            table_prefix: _,
        } => {
            use sqlx::mysql::MySqlPoolOptions;

            let pool = MySqlPoolOptions::new()
                .max_connections(_pool_size.unwrap_or(10))
                .connect(connection_string)
                .await
                .map_err(|e| {
                    AuthError::configuration(format!("Failed to connect MySQL storage: {e}"))
                })?;

            let storage = crate::storage::mysql::MySqlStorage::new(pool);
            storage.migrate().await.map_err(|e| {
                AuthError::configuration(format!("Failed to initialize MySQL storage: {e}"))
            })?;

            Ok(Arc::new(storage))
        }
        #[cfg(feature = "sqlite-storage")]
        StorageConfig::Sqlite { connection_string } => {
            use sqlx::sqlite::SqlitePoolOptions;

            let pool = SqlitePoolOptions::new()
                .max_connections(_pool_size.unwrap_or(10))
                .connect(connection_string)
                .await
                .map_err(|e| {
                    AuthError::configuration(format!("Failed to connect SQLite storage: {e}"))
                })?;

            let storage = crate::storage::sqlite::SqliteStorage::new(pool);
            storage.migrate().await.map_err(|e| {
                AuthError::configuration(format!("Failed to initialize SQLite storage: {e}"))
            })?;

            Ok(Arc::new(storage))
        }
        StorageConfig::Custom(name) => Err(AuthError::configuration(format!(
            "Custom storage backend '{name}' requires AuthFramework::new_with_storage() or replace_storage()",
        ))),
        #[allow(unreachable_patterns)]
        _ => Err(AuthError::configuration(
            "Requested storage backend is unavailable in this build. Enable the matching storage feature.",
        )),
    }
}