diff --git a/rust-runtime/aws-smithy-http-server/src/plugin/closure.rs b/rust-runtime/aws-smithy-http-server/src/plugin/closure.rs new file mode 100644 index 0000000000..75685c97b9 --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/plugin/closure.rs @@ -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, +} + +impl Plugin for OperationNameFn +where + F: Fn(&'static str) -> NewLayer, + Op: OperationShape, +{ + type Service = S; + type Layer = Stack; + + fn map(&self, input: Operation) -> Operation { + 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 { +/// 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(f: F) -> OperationNameFn +where + F: Fn(&'static str) -> L, +{ + OperationNameFn { f } +} diff --git a/rust-runtime/aws-smithy-http-server/src/plugin/layer.rs b/rust-runtime/aws-smithy-http-server/src/plugin/layer.rs new file mode 100644 index 0000000000..d7a055f291 --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/plugin/layer.rs @@ -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`](Operation). +pub struct HttpLayer(pub L); + +impl Plugin for HttpLayer +where + NewLayer: Clone, +{ + type Service = S; + type Layer = Stack; + + fn map(&self, input: Operation) -> Operation { + input.layer(self.0.clone()) + } +} diff --git a/rust-runtime/aws-smithy-http-server/src/plugin/mod.rs b/rust-runtime/aws-smithy-http-server/src/plugin/mod.rs index 8ee496774f..c6c13aa6c0 100644 --- a/rust-runtime/aws-smithy-http-server/src/plugin/mod.rs +++ b/rust-runtime/aws-smithy-http-server/src/plugin/mod.rs @@ -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;