global-registry 0.1.0

A global type registration system for Rust
Documentation
//! Factory pattern example demonstrating the FactoryRegistry

use global_registry::{FactoryRegistry, Factory};

// Service trait
trait DatabaseService: Send + Sync {
    fn connect(&self) -> String;
    fn query(&self, sql: &str) -> String;
}

// PostgreSQL implementation
#[derive(Debug)]
struct PostgreSQLService {
    connection_string: String,
}

impl PostgreSQLService {
    fn new(host: &str, database: &str) -> Self {
        Self {
            connection_string: format!("postgresql://{}:5432/{}", host, database),
        }
    }
}

impl DatabaseService for PostgreSQLService {
    fn connect(&self) -> String {
        format!("Connected to PostgreSQL: {}", self.connection_string)
    }
    
    fn query(&self, sql: &str) -> String {
        format!("PostgreSQL executing: {}", sql)
    }
}

// MySQL implementation
#[derive(Debug)]
struct MySQLService {
    connection_string: String,
}

impl MySQLService {
    fn new(host: &str, database: &str) -> Self {
        Self {
            connection_string: format!("mysql://{}:3306/{}", host, database),
        }
    }
}

impl DatabaseService for MySQLService {
    fn connect(&self) -> String {
        format!("Connected to MySQL: {}", self.connection_string)
    }
    
    fn query(&self, sql: &str) -> String {
        format!("MySQL executing: {}", sql)
    }
}

// SQLite implementation
#[derive(Debug)]
struct SQLiteService {
    file_path: String,
}

impl SQLiteService {
    fn new(file_path: &str) -> Self {
        Self {
            file_path: file_path.to_string(),
        }
    }
}

impl DatabaseService for SQLiteService {
    fn connect(&self) -> String {
        format!("Connected to SQLite: {}", self.file_path)
    }
    
    fn query(&self, sql: &str) -> String {
        format!("SQLite executing: {}", sql)
    }
}

// Configuration for database services
#[derive(Clone)]
struct DatabaseConfig {
    db_type: String,
    host: Option<String>,
    database: String,
}

impl DatabaseConfig {
    fn postgresql(host: &str, database: &str) -> Self {
        Self {
            db_type: "postgresql".to_string(),
            host: Some(host.to_string()),
            database: database.to_string(),
        }
    }
    
    fn mysql(host: &str, database: &str) -> Self {
        Self {
            db_type: "mysql".to_string(),
            host: Some(host.to_string()),
            database: database.to_string(),
        }
    }
    
    fn sqlite(file_path: &str) -> Self {
        Self {
            db_type: "sqlite".to_string(),
            host: None,
            database: file_path.to_string(),
        }
    }
}

// Service factory that creates database services based on configuration
struct ServiceFactory;

impl ServiceFactory {
    fn setup_factories() {
        let factory_registry = FactoryRegistry::global();
        
        // PostgreSQL factory
        let pg_factory: Factory<Box<dyn DatabaseService>> = Box::new(|| {
            Box::new(PostgreSQLService::new("localhost", "production"))
        });
        factory_registry.register_factory(pg_factory)
            .expect("Failed to register PostgreSQL factory");
        
        // MySQL factory  
        let mysql_factory: Factory<MySQLService> = Box::new(|| {
            MySQLService::new("mysql-server", "app_data")
        });
        factory_registry.register_factory(mysql_factory)
            .expect("Failed to register MySQL factory");
        
        // SQLite factory
        let sqlite_factory: Factory<SQLiteService> = Box::new(|| {
            SQLiteService::new("/tmp/app.db")
        });
        factory_registry.register_factory(sqlite_factory)
            .expect("Failed to register SQLite factory");
        
        // Configuration-based factory
        let config_factory: Factory<DatabaseConfig> = Box::new(|| {
            DatabaseConfig::postgresql("prod-server", "main_db")
        });
        factory_registry.register_factory(config_factory)
            .expect("Failed to register config factory");
    }
    
    fn create_database_service(db_type: &str) -> Option<Box<dyn DatabaseService>> {
        let factory_registry = FactoryRegistry::global();
        
        match db_type {
            "postgresql" => {
                factory_registry.create::<Box<dyn DatabaseService>>().ok()
            }
            "mysql" => {
                factory_registry.create::<MySQLService>()
                    .map(|service| Box::new(service) as Box<dyn DatabaseService>)
                    .ok()
            }
            "sqlite" => {
                factory_registry.create::<SQLiteService>()
                    .map(|service| Box::new(service) as Box<dyn DatabaseService>)
                    .ok()
            }
            _ => None,
        }
    }
}

// Application that uses the factories
struct Application;

impl Application {
    fn run() {
        println!("=== Factory Pattern Example ===\n");
        
        // Setup all factories
        ServiceFactory::setup_factories();
        
        // Create different database services
        let databases = vec!["postgresql", "mysql", "sqlite"];
        
        for db_type in databases {
            println!("--- Testing {} ---", db_type.to_uppercase());
            
            if let Some(service) = ServiceFactory::create_database_service(db_type) {
                println!("{}", service.connect());
                println!("{}", service.query("SELECT * FROM users"));
            } else {
                println!("Failed to create {} service", db_type);
            }
            println!();
        }
        
        // Demonstrate configuration factory
        let factory_registry = FactoryRegistry::global();
        if let Ok(config) = factory_registry.create::<DatabaseConfig>() {
            println!("Created config: {} database at {:?}", 
                   config.db_type, config.host);
        }
        
        // Show factory count
        println!("Factory registry usage complete");
    }
}

fn main() {
    Application::run();
}