Skip to content

Commit ed5cd6e

Browse files
hlbarberjjantLukeMathWalker
authored
Improve Plugin toolkit (#2003)
Co-authored-by: Julian Antonielli <julianantonielli@gmail.com> Co-authored-by: Luca Palmieri <20745048+LukeMathWalker@users.noreply.github.com>
1 parent 4aca7b3 commit ed5cd6e

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
use tower::layer::util::Stack;
7+
8+
use crate::operation::{Operation, OperationShape};
9+
10+
use super::Plugin;
11+
12+
/// An adapter to convert a `Fn(&'static str) -> Layer` closure into a [`Plugin`]. See [`plugin_from_operation_name_fn`] for more details.
13+
pub struct OperationNameFn<F> {
14+
f: F,
15+
}
16+
17+
impl<P, Op, S, ExistingLayer, NewLayer, F> Plugin<P, Op, S, ExistingLayer> for OperationNameFn<F>
18+
where
19+
F: Fn(&'static str) -> NewLayer,
20+
Op: OperationShape,
21+
{
22+
type Service = S;
23+
type Layer = Stack<ExistingLayer, NewLayer>;
24+
25+
fn map(&self, input: Operation<S, ExistingLayer>) -> Operation<Self::Service, Self::Layer> {
26+
input.layer((self.f)(Op::NAME))
27+
}
28+
}
29+
30+
/// Constructs a [`Plugin`] using a closure over the operation name `F: Fn(&'static str) -> L` where `L` is a HTTP
31+
/// [`Layer`](tower::Layer).
32+
///
33+
/// # Example
34+
///
35+
/// ```rust
36+
/// use aws_smithy_http_server::plugin::plugin_from_operation_name_fn;
37+
/// use tower::layer::layer_fn;
38+
///
39+
/// // A `Service` which prints the operation name before calling `S`.
40+
/// struct PrintService<S> {
41+
/// operation_name: &'static str,
42+
/// inner: S
43+
/// }
44+
///
45+
/// // A `Layer` applying `PrintService`.
46+
/// struct PrintLayer {
47+
/// operation_name: &'static str
48+
/// }
49+
///
50+
/// // Defines a closure taking the operation name to `PrintLayer`.
51+
/// let f = |operation_name| PrintLayer { operation_name };
52+
///
53+
/// // This plugin applies the `PrintService` middleware around every operation.
54+
/// let plugin = plugin_from_operation_name_fn(f);
55+
/// ```
56+
pub fn plugin_from_operation_name_fn<L, F>(f: F) -> OperationNameFn<F>
57+
where
58+
F: Fn(&'static str) -> L,
59+
{
60+
OperationNameFn { f }
61+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
use tower::layer::util::Stack;
7+
8+
use crate::operation::Operation;
9+
10+
use super::Plugin;
11+
12+
/// A [`Plugin`] which appends a HTTP [`Layer`](tower::Layer) `L` to the existing `Layer` in [`Operation<S, Layer>`](Operation).
13+
pub struct HttpLayer<L>(pub L);
14+
15+
impl<P, Op, S, ExistingLayer, NewLayer> Plugin<P, Op, S, ExistingLayer> for HttpLayer<NewLayer>
16+
where
17+
NewLayer: Clone,
18+
{
19+
type Service = S;
20+
type Layer = Stack<ExistingLayer, NewLayer>;
21+
22+
fn map(&self, input: Operation<S, ExistingLayer>) -> Operation<Self::Service, Self::Layer> {
23+
input.layer(self.0.clone())
24+
}
25+
}

rust-runtime/aws-smithy-http-server/src/plugin/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6+
mod closure;
67
mod filter;
78
mod identity;
9+
mod layer;
810
mod pipeline;
911
mod stack;
1012

1113
use crate::operation::Operation;
1214

15+
pub use closure::{plugin_from_operation_name_fn, OperationNameFn};
1316
pub use filter::{filter_by_operation_name, FilterByOperationName};
1417
pub use identity::IdentityPlugin;
18+
pub use layer::HttpLayer;
1519
pub use pipeline::PluginPipeline;
1620
pub use stack::PluginStack;
1721

0 commit comments

Comments
 (0)