darkwing/server/extractors/service_provider_extractor.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
use async_trait::async_trait;
use axum::extract::FromRequestParts;
use axum::http::request::Parts;
use axum::Extension;
use crate::server::error::Error;
use crate::server::services::Services;
/// An extractor that provides access to application services in route handlers.
///
/// This extractor simplifies access to application services by extracting them
/// from request extensions. It serves as a convenient wrapper around the
/// Services type without performing any additional validation or
/// authentication.
///
/// # Fields
/// * `0` - The Services instance containing all application services
///
/// # Example
/// ```rust,no_run
/// async fn route_handler(
/// ServiceProvider(services): ServiceProvider
/// ) -> Result<impl Response, Error> {
/// // Use services directly
/// let some_data = services.some_service.do_something().await?;
/// Ok(some_data)
/// }
/// ```
pub struct ServiceProvider(pub Services);
/// Implementation of FromRequestParts to enable automatic extraction of
/// services from request extensions.
///
/// # Errors
/// Returns `Error::InternalServerErrorWithContext` if:
/// - Services are not found in request extensions
/// - Extension extraction fails
#[async_trait]
impl<S> FromRequestParts<S> for ServiceProvider
where
S: Send + Sync,
{
type Rejection = Error;
async fn from_request_parts(
parts: &mut Parts,
state: &S,
) -> Result<Self, Self::Rejection> {
let Extension(services): Extension<Services> =
Extension::from_request_parts(parts, state)
.await
.map_err(|err| {
Error::InternalServerErrorWithContext(err.to_string())
})?;
Ok(ServiceProvider(services))
}
}