flow-di 0.1.0

A dependency injection framework for Rust inspired by C# AutoFac and Microsoft.Extensions.DependencyInjection
Documentation
use thiserror::Error;

/// Error types for the dependency injection framework
#[derive(Error, Debug)]
pub enum DiError {
    /// Service not registered
    #[error("Service not registered: {type_name}")]
    ServiceNotRegistered { type_name: String },

    /// Keyed service not registered
    #[error("Keyed service not registered: {type_name} with key '{key}'")]
    KeyedServiceNotRegistered { type_name: String, key: String },

    /// Circular dependency detected
    #[error("Circular dependency detected for service: {type_name}")]
    CircularDependency { type_name: String },

    /// Scope has been disposed
    #[error("Scope has been disposed")]
    ScopeDisposed,

    /// Service creation failed
    #[error("Failed to create service: {type_name} - {reason}")]
    ServiceCreationFailed { type_name: String, reason: String },

    /// Service already registered
    #[error("Service already registered: {type_name}")]
    ServiceAlreadyRegistered { type_name: String },

    /// Type casting failed
    #[error("Type casting failed for service: {type_name}")]
    TypeCastingFailed { type_name: String },

    /// Scoped service resolved from root container
    #[error("Scoped service '{type_name}' cannot be resolved from root container")]
    ScopedServiceInRootContainer { type_name: String },

    /// Generic error
    #[error("Generic error: {message}")]
    Generic { message: String },
}

impl DiError {
    /// Create service not registered error from TypeId
    pub fn service_not_registered<T: 'static>() -> Self {
        Self::ServiceNotRegistered {
            type_name: std::any::type_name::<T>().to_string(),
        }
    }

    /// Create keyed service not registered error from TypeId
    pub fn keyed_service_not_registered<T: 'static>(key: &str) -> Self {
        Self::KeyedServiceNotRegistered {
            type_name: std::any::type_name::<T>().to_string(),
            key: key.to_string(),
        }
    }

    /// Create circular dependency error from TypeId
    pub fn circular_dependency<T: 'static>() -> Self {
        Self::CircularDependency {
            type_name: std::any::type_name::<T>().to_string(),
        }
    }

    /// Create service creation failed error from TypeId
    pub fn service_creation_failed<T: 'static>(reason: &str) -> Self {
        Self::ServiceCreationFailed {
            type_name: std::any::type_name::<T>().to_string(),
            reason: reason.to_string(),
        }
    }

    /// Create service already registered error from TypeId
    pub fn service_already_registered<T: 'static>() -> Self {
        Self::ServiceAlreadyRegistered {
            type_name: std::any::type_name::<T>().to_string(),
        }
    }

    /// Create type casting failed error from TypeId
    pub fn type_casting_failed<T: 'static>() -> Self {
        Self::TypeCastingFailed {
            type_name: std::any::type_name::<T>().to_string(),
        }
    }

    /// Create scoped service in root container error from TypeId
    pub fn scoped_service_in_root_container<T: 'static>() -> Self {
        Self::ScopedServiceInRootContainer {
            type_name: std::any::type_name::<T>().to_string(),
        }
    }

    /// Create generic error
    pub fn generic(message: &str) -> Self {
        Self::Generic {
            message: message.to_string(),
        }
    }
}

/// Dependency injection result type
pub type DiResult<T> = Result<T, DiError>;