use crate::container::binding::ServiceBinder;
use crate::container::conventions::{
ServiceConventions, ServiceMetadata, ServiceRegistry as ConventionServiceRegistry,
};
use crate::container::debug::ContainerInspector;
use crate::container::ioc_container::IocContainer;
use crate::container::module::{ModuleRegistry, ServiceModule};
use crate::container::scope::ServiceScope;
use crate::container::visualization::{
DependencyVisualizer, VisualizationFormat, VisualizationStyle,
};
use crate::errors::CoreError;
use std::sync::Arc;
#[derive(Default)]
pub struct UserService;
impl UserService {
pub fn get_user(&self, _id: u32) -> String {
"Demo User".to_string()
}
}
#[derive(Default)]
pub struct UserRepository;
impl UserRepository {
pub fn find_user(&self, _id: u32) -> Option<String> {
Some("Repository User".to_string())
}
}
#[derive(Default)]
pub struct AppLogger;
impl AppLogger {
pub fn log(&self, message: &str) {
println!("[LOG] {}", message);
}
}
pub struct UserModule;
impl ServiceModule for UserModule {
fn name(&self) -> &str {
"User Management Module"
}
fn description(&self) -> Option<&str> {
Some("Handles user-related services and operations")
}
fn version(&self) -> Option<&str> {
Some("1.0.0")
}
fn configure(&self, services: &mut crate::container::binding::ServiceBindings) {
services.bind::<UserService, UserService>();
services.bind::<UserRepository, UserRepository>();
}
fn depends_on(&self) -> Vec<crate::container::module::ModuleId> {
vec![]
}
}
pub struct CoreModule;
impl ServiceModule for CoreModule {
fn name(&self) -> &str {
"Core Module"
}
fn description(&self) -> Option<&str> {
Some("Core application services")
}
fn configure(&self, services: &mut crate::container::binding::ServiceBindings) {
services.bind::<AppLogger, AppLogger>();
}
}
pub fn demo_phase6_features() -> Result<(), CoreError> {
println!("=== Phase 6 Demo: Developer Experience & Tooling ===");
println!();
println!("1. Auto-wiring Conventions:");
println!("---------------------------");
let mut conventions = ServiceConventions::new();
conventions.add_naming_convention("*Service", ServiceScope::Singleton);
conventions.add_naming_convention("*Repository", ServiceScope::Scoped);
conventions.add_naming_convention("*Logger", ServiceScope::Singleton);
println!(
"✓ UserService lifetime: {:?}",
conventions.get_lifetime_for_type("UserService")
);
println!(
"✓ UserRepository lifetime: {:?}",
conventions.get_lifetime_for_type("UserRepository")
);
println!(
"✓ AppLogger lifetime: {:?}",
conventions.get_lifetime_for_type("AppLogger")
);
let mut service_registry = ConventionServiceRegistry::new();
let user_service_metadata =
ServiceMetadata::new("UserService".to_string()).with_lifetime(ServiceScope::Singleton);
service_registry.register_service(user_service_metadata);
let user_repo_metadata =
ServiceMetadata::new("UserRepository".to_string()).with_lifetime(ServiceScope::Scoped);
service_registry.register_service(user_repo_metadata);
println!(
"✓ Registered {} services with conventions",
service_registry.all_services().len()
);
println!();
println!("2. Module System:");
println!("-----------------");
let mut module_registry = ModuleRegistry::new();
module_registry.register_module(CoreModule, None)?;
module_registry.register_module(UserModule, None)?;
let load_order = module_registry.calculate_load_order()?;
println!(
"✓ Module load order calculated: {} modules",
load_order.len()
);
for (i, module_id) in load_order.iter().enumerate() {
if let Some(loaded_module) = module_registry.get_loaded_module(module_id) {
println!(
" {}. {} ({})",
i + 1,
loaded_module.metadata.name,
loaded_module
.metadata
.version
.as_deref()
.unwrap_or("no version")
);
}
}
println!();
println!("3. Debug & Inspection Tools:");
println!("-----------------------------");
let container = IocContainer::new();
let inspector = ContainerInspector::new(Arc::new(container));
let container_info = inspector.get_container_info();
println!(
"✓ Container Status: {}",
if container_info.is_built {
"Built"
} else {
"Not Built"
}
);
println!("✓ Registered Services: {}", container_info.service_count);
println!("✓ Cached Instances: {}", container_info.cached_instances);
println!();
println!("4. Dependency Visualization:");
println!("----------------------------");
let descriptors = vec![]; let visualizer = DependencyVisualizer::new(descriptors);
let style = VisualizationStyle::default();
match visualizer.visualize(VisualizationFormat::Ascii, style.clone()) {
Ok(ascii_viz) => {
println!("✓ ASCII Visualization Generated:");
println!(
"{}",
ascii_viz.lines().take(10).collect::<Vec<_>>().join("\n")
);
if ascii_viz.lines().count() > 10 {
println!(" ... (truncated)");
}
}
Err(e) => println!("⚠️ ASCII visualization failed: {}", e),
}
println!();
match visualizer.visualize(VisualizationFormat::Json, style) {
Ok(json_viz) => {
println!("✓ JSON Visualization Generated ({} bytes)", json_viz.len());
let preview: String = json_viz.chars().take(200).collect();
println!(" Preview: {}...", preview);
}
Err(e) => println!("⚠️ JSON visualization failed: {}", e),
}
println!();
println!("5. Container Health Monitoring:");
println!("-------------------------------");
println!("✓ Health Check System Available");
println!("✓ Performance Profiler Available");
println!("✓ Resolution Tracer Available");
println!();
println!("🎉 Phase 6 Demo Complete!");
println!(" All developer experience and tooling features are operational.");
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_phase6_demo() {
let result = demo_phase6_features();
assert!(result.is_ok(), "Phase 6 demo should run successfully");
}
#[test]
fn test_service_conventions() {
let conventions = ServiceConventions::new();
assert_eq!(
conventions.get_lifetime_for_type("UserService"),
ServiceScope::Singleton
);
assert_eq!(
conventions.get_lifetime_for_type("UserRepository"),
ServiceScope::Scoped
);
assert_eq!(
conventions.get_lifetime_for_type("PaymentFactory"),
ServiceScope::Transient
);
assert_eq!(
conventions.get_lifetime_for_type("AppLogger"),
ServiceScope::Singleton
);
}
#[test]
fn test_module_registry() {
let mut registry = ModuleRegistry::new();
assert!(registry.register_module(CoreModule, None).is_ok());
assert!(registry.register_module(UserModule, None).is_ok());
let load_order = registry.calculate_load_order();
assert!(load_order.is_ok());
assert_eq!(load_order.unwrap().len(), 2);
}
#[test]
fn test_container_inspector() {
let container = IocContainer::new();
let inspector = ContainerInspector::new(Arc::new(container));
let info = inspector.get_container_info();
assert!(!info.is_built); assert_eq!(info.service_count, 0); }
#[test]
fn test_service_metadata() {
let metadata = ServiceMetadata::new("TestService".to_string())
.with_lifetime(ServiceScope::Singleton)
.with_name("test".to_string())
.as_default()
.with_tag("core".to_string());
assert_eq!(metadata.type_name, "TestService");
assert_eq!(metadata.lifetime, Some(ServiceScope::Singleton));
assert_eq!(metadata.name, Some("test".to_string()));
assert!(metadata.is_default);
assert_eq!(metadata.tags, vec!["core"]);
}
}