Skip to content

Commit

Permalink
Improve Plugin toolkit (#2003)
Browse files Browse the repository at this point in the history
Co-authored-by: Julian Antonielli <[email protected]>
Co-authored-by: Luca Palmieri <[email protected]>
  • Loading branch information
3 people authored Nov 18, 2022
1 parent 4aca7b3 commit ed5cd6e
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
61 changes: 61 additions & 0 deletions rust-runtime/aws-smithy-http-server/src/plugin/closure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

use tower::layer::util::Stack;

use crate::operation::{Operation, OperationShape};

use super::Plugin;

/// An adapter to convert a `Fn(&'static str) -> Layer` closure into a [`Plugin`]. See [`plugin_from_operation_name_fn`] for more details.
pub struct OperationNameFn<F> {
f: F,
}

impl<P, Op, S, ExistingLayer, NewLayer, F> Plugin<P, Op, S, ExistingLayer> for OperationNameFn<F>
where
F: Fn(&'static str) -> NewLayer,
Op: OperationShape,
{
type Service = S;
type Layer = Stack<ExistingLayer, NewLayer>;

fn map(&self, input: Operation<S, ExistingLayer>) -> Operation<Self::Service, Self::Layer> {
input.layer((self.f)(Op::NAME))
}
}

/// Constructs a [`Plugin`] using a closure over the operation name `F: Fn(&'static str) -> L` where `L` is a HTTP
/// [`Layer`](tower::Layer).
///
/// # Example
///
/// ```rust
/// use aws_smithy_http_server::plugin::plugin_from_operation_name_fn;
/// use tower::layer::layer_fn;
///
/// // A `Service` which prints the operation name before calling `S`.
/// struct PrintService<S> {
/// operation_name: &'static str,
/// inner: S
/// }
///
/// // A `Layer` applying `PrintService`.
/// struct PrintLayer {
/// operation_name: &'static str
/// }
///
/// // Defines a closure taking the operation name to `PrintLayer`.
/// let f = |operation_name| PrintLayer { operation_name };
///
/// // This plugin applies the `PrintService` middleware around every operation.
/// let plugin = plugin_from_operation_name_fn(f);
/// ```
pub fn plugin_from_operation_name_fn<L, F>(f: F) -> OperationNameFn<F>
where
F: Fn(&'static str) -> L,
{
OperationNameFn { f }
}
25 changes: 25 additions & 0 deletions rust-runtime/aws-smithy-http-server/src/plugin/layer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

use tower::layer::util::Stack;

use crate::operation::Operation;

use super::Plugin;

/// A [`Plugin`] which appends a HTTP [`Layer`](tower::Layer) `L` to the existing `Layer` in [`Operation<S, Layer>`](Operation).
pub struct HttpLayer<L>(pub L);

impl<P, Op, S, ExistingLayer, NewLayer> Plugin<P, Op, S, ExistingLayer> for HttpLayer<NewLayer>
where
NewLayer: Clone,
{
type Service = S;
type Layer = Stack<ExistingLayer, NewLayer>;

fn map(&self, input: Operation<S, ExistingLayer>) -> Operation<Self::Service, Self::Layer> {
input.layer(self.0.clone())
}
}
4 changes: 4 additions & 0 deletions rust-runtime/aws-smithy-http-server/src/plugin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
* SPDX-License-Identifier: Apache-2.0
*/

mod closure;
mod filter;
mod identity;
mod layer;
mod pipeline;
mod stack;

use crate::operation::Operation;

pub use closure::{plugin_from_operation_name_fn, OperationNameFn};
pub use filter::{filter_by_operation_name, FilterByOperationName};
pub use identity::IdentityPlugin;
pub use layer::HttpLayer;
pub use pipeline::PluginPipeline;
pub use stack::PluginStack;

Expand Down

0 comments on commit ed5cd6e

Please sign in to comment.