use std::cell::Cell;
use actix_service::{IntoServiceFactory, ServiceFactory};
use actix_web::dev::{HttpServiceFactory, ServiceRequest, ServiceResponse};
use actix_web::{Error, Route};
use crate::OpenApiFactory;
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> {
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()),
)
}
pub fn app_data<U: 'static>(&mut self, ext: U) -> &mut Self {
self.0.app_data(ext);
self
}
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
}
pub fn configure<F>(&mut self, f: F) -> &mut Self
where
F: FnOnce(&mut ServiceConfig),
{
f(self);
self
}
pub fn route(&mut self, path: &str, route: Route) -> &mut Self {
self.0.route(path, route);
self
}
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
}
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
}
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
}
}