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))
  }
}