Skip to content

Commit

Permalink
Transform api operations based upon middleware wrappers
Browse files Browse the repository at this point in the history
  • Loading branch information
platy committed Nov 27, 2020
1 parent 225bb7b commit 5f3964d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 13 deletions.
48 changes: 36 additions & 12 deletions plugins/actix-web/src/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ const METHODS: &[Method] = &[
/* Resource */

/// Wrapper for [`actix_web::Resource`](https://docs.rs/actix-web/*/actix_web/struct.Resource.html)
pub struct Resource<R = actix_web::Resource> {
pub struct Resource<R = actix_web::Resource, N = ()> {
path: String,
operations: BTreeMap<HttpMethod, DefaultOperationRaw>,
definitions: BTreeMap<String, DefaultSchemaRaw>,
security: BTreeMap<String, SecurityScheme>,
inner: R,
api_transformations: N,
}

impl Resource {
Expand All @@ -52,11 +53,12 @@ impl Resource {
definitions: BTreeMap::new(),
security: BTreeMap::new(),
inner: actix_web::Resource::new(path),
api_transformations: (),
}
}
}

impl<T> HttpServiceFactory for Resource<actix_web::Resource<T>>
impl<T, N> HttpServiceFactory for Resource<actix_web::Resource<T>, N>
where
T: ServiceFactory<
Config = (),
Expand Down Expand Up @@ -86,7 +88,7 @@ where
}
}

impl<T> Mountable for Resource<T> {
impl<T, N> Mountable for Resource<T, N> {
fn path(&self) -> &str {
&self.path
}
Expand All @@ -104,7 +106,7 @@ impl<T> Mountable for Resource<T> {
}
}

impl<T> Resource<actix_web::Resource<T>>
impl<T, N> Resource<actix_web::Resource<T>, N>
where
T: ServiceFactory<
Config = (),
Expand All @@ -113,6 +115,7 @@ where
Error = Error,
InitError = (),
>,
N: TransformApi,
{
/// Proxy for [`actix_web::Resource::name`](https://docs.rs/actix-web/*/actix_web/struct.Resource.html#method.name).
///
Expand All @@ -132,7 +135,7 @@ where

/// Wrapper for [`actix_web::Resource::route`](https://docs.rs/actix-web/*/actix_web/struct.Resource.html#method.route).
pub fn route(mut self, route: Route) -> Self {
let w = RouteWrapper::from(&self.path, route);
let w = self.api_transformations.transform(RouteWrapper::from(&self.path, route));
self.operations.extend(w.operations.into_iter());
self.definitions.extend(w.definitions.into_iter());
SecurityScheme::append_map(w.security, &mut self.security);
Expand Down Expand Up @@ -172,7 +175,7 @@ where

/// Proxy for [`actix_web::web::Resource::wrap`](https://docs.rs/actix-web/*/actix_web/struct.Resource.html#method.wrap).
///
/// **NOTE:** This doesn't affect spec generation.
/// The proxy adds to the signature of `wrap`'s actix-web `Transform` type that `paperclip::actix::web::TransformApi` is implemented. It can be used to transform the spec operations based on this middleware.
pub fn wrap<M>(
self,
mw: M,
Expand All @@ -186,6 +189,7 @@ where
InitError = (),
>,
>,
(N, M),
>
where
M: Transform<
Expand All @@ -194,14 +198,15 @@ where
Response = ServiceResponse,
Error = Error,
InitError = (),
>,
> + TransformApi + Clone,
{
Resource {
path: self.path,
operations: self.operations,
definitions: self.definitions,
security: self.security,
inner: self.inner.wrap(mw),
inner: self.inner.wrap(mw.clone()),
api_transformations: (self.api_transformations, mw),
}
}

Expand All @@ -221,6 +226,7 @@ where
InitError = (),
>,
>,
N,
>
where
F: FnMut(ServiceRequest, &mut T::Service) -> R + Clone,
Expand All @@ -232,6 +238,7 @@ where
definitions: self.definitions,
security: self.security,
inner: self.inner.wrap_fn(mw),
api_transformations: self.api_transformations,
}
}

Expand Down Expand Up @@ -627,11 +634,11 @@ pub fn head() -> Route {
/// us to call the `.route` method on that entity rather than creating a resource with a
/// route. This wrapper is `Mountable` and can be used by `App`, `Scope`, etc. when calling
/// the `.route()` method.
pub(crate) struct RouteWrapper<S> {
pub struct RouteWrapper<S> {
path: S,
pub(crate) operations: BTreeMap<HttpMethod, DefaultOperationRaw>,
pub(crate) definitions: BTreeMap<String, DefaultSchemaRaw>,
pub(crate) security: BTreeMap<String, SecurityScheme>,
pub operations: BTreeMap<HttpMethod, DefaultOperationRaw>,
pub definitions: BTreeMap<String, DefaultSchemaRaw>,
pub security: BTreeMap<String, SecurityScheme>,
pub(crate) inner: actix_web::Route,
}

Expand Down Expand Up @@ -684,6 +691,23 @@ where
}
}

pub trait TransformApi {
/// Perform a transformation on the api operations of the route based on the properties of this middleware
fn transform<S>(&self, route: RouteWrapper<S>) -> RouteWrapper<S> {
route
}
}

impl TransformApi for () {}

impl<N, M> TransformApi for (N, M)
where N: TransformApi,
M: TransformApi {
fn transform<S>(&self, route: RouteWrapper<S>) -> RouteWrapper<S> {
self.1.transform(self.0.transform(route))
}
}

/* Service config */

/// Wrapper for [`actix_web::web::ServiceConfig`](https://docs.rs/actix-web/*/actix_web/web/struct.ServiceConfig.html).
Expand Down
2 changes: 1 addition & 1 deletion src/build/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ mod template {
",
);
contents.push_str(&name);
contents.push_str(",");
contents.push(',');
}

contents.push_str(
Expand Down

0 comments on commit 5f3964d

Please sign in to comment.