Unverified Commit ed5cd6e3 authored by Harry Barber's avatar Harry Barber Committed by GitHub
Browse files

Improve `Plugin` toolkit (#2003)

parent 4aca7b32
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
/*
 * 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 −0
Original line number Diff line number Diff line
/*
 * 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 −0
Original line number Diff line number Diff line
@@ -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;