utoipa_actix_web/
service_config.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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//! Implement `utoipa` extended [`ServiceConfig`] for [`actix_web::web::ServiceConfig`].

use std::cell::Cell;

use actix_service::{IntoServiceFactory, ServiceFactory};
use actix_web::dev::{HttpServiceFactory, ServiceRequest, ServiceResponse};
use actix_web::{Error, Route};

use crate::OpenApiFactory;

/// Wrapper type for [`actix_web::web::ServiceConfig`], [`utoipa::openapi::path::Paths`] and
/// vec of [`utoipa::openapi::schema::Schema`] references.
pub struct ServiceConfig<'s>(
    pub(super) &'s mut actix_web::web::ServiceConfig,
    pub(super) Cell<utoipa::openapi::path::Paths>,
    pub(super)  Cell<
        Vec<(
            String,
            utoipa::openapi::RefOr<utoipa::openapi::schema::Schema>,
        )>,
    >,
);

impl<'s> ServiceConfig<'s> {
    /// Construct a new [`ServiceConfig`] from given [`actix_web::web::ServiceConfig`].
    pub fn new(conf: &'s mut actix_web::web::ServiceConfig) -> ServiceConfig<'s> {
        ServiceConfig(
            conf,
            Cell::new(utoipa::openapi::path::Paths::new()),
            Cell::new(Vec::new()),
        )
    }

    /// Passthrough implementation for [`actix_web::web::ServiceConfig::app_data`].
    pub fn app_data<U: 'static>(&mut self, ext: U) -> &mut Self {
        self.0.app_data(ext);
        self
    }

    /// Passthrough implementation for [`actix_web::web::ServiceConfig::default_service`].
    pub fn default_service<F, U>(&mut self, f: F) -> &mut Self
    where
        F: IntoServiceFactory<U, ServiceRequest>,
        U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>
            + 'static,
        U::InitError: std::fmt::Debug,
    {
        self.0.default_service(f);
        self
    }

    /// Passthrough implementation for [`actix_web::web::ServiceConfig::configure`].
    pub fn configure<F>(&mut self, f: F) -> &mut Self
    where
        F: FnOnce(&mut ServiceConfig),
    {
        f(self);
        self
    }

    /// Passthrough implementation for [`actix_web::web::ServiceConfig::route`].
    pub fn route(&mut self, path: &str, route: Route) -> &mut Self {
        self.0.route(path, route);
        self
    }

    /// Counterpart for [`UtoipaApp::service`][utoipa_app_service].
    ///
    /// [utoipa_app_service]: ../struct.UtoipaApp.html#method.service
    pub fn service<F>(&mut self, factory: F) -> &mut Self
    where
        F: HttpServiceFactory + OpenApiFactory + 'static,
    {
        let mut paths = self.1.take();
        let other_paths = factory.paths();
        paths.merge(other_paths);

        let mut schemas = self.2.take();
        factory.schemas(&mut schemas);
        self.2.set(schemas);

        self.0.service(factory);
        self.1.set(paths);

        self
    }

    /// Passthrough implementation for [`actix_web::web::ServiceConfig::external_resource`].
    pub fn external_resource<N, U>(&mut self, name: N, url: U) -> &mut Self
    where
        N: AsRef<str>,
        U: AsRef<str>,
    {
        self.0.external_resource(name, url);
        self
    }

    /// Synonymous for [`UtoipaApp::map`][utoipa_app_map]
    ///
    /// [utoipa_app_map]: ../struct.UtoipaApp.html#method.map
    pub fn map<
        F: FnOnce(&mut actix_web::web::ServiceConfig) -> &mut actix_web::web::ServiceConfig,
    >(
        &mut self,
        op: F,
    ) -> &mut Self {
        op(self.0);

        self
    }
}