aws_smithy_http_server/plugin/
layer.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6use std::marker::PhantomData;
7
8use tower::Layer;
9
10use super::{HttpMarker, ModelMarker, Plugin};
11
12/// A [`Plugin`] which acts as a [`Layer`] `L`.
13pub struct LayerPlugin<L>(pub L);
14
15impl<Ser, Op, S, L> Plugin<Ser, Op, S> for LayerPlugin<L>
16where
17    L: Layer<S>,
18{
19    type Output = L::Service;
20
21    fn apply(&self, svc: S) -> Self::Output {
22        self.0.layer(svc)
23    }
24}
25
26// Without more information about what the layer `L` does, we can't know whether it's appropriate
27// to run this plugin as a HTTP plugin or a model plugin, so we implement both marker traits.
28
29impl<L> HttpMarker for LayerPlugin<L> {}
30impl<L> ModelMarker for LayerPlugin<L> {}
31
32/// A [`Layer`] which acts as a [`Plugin`] `Pl` for specific protocol `P` and operation `Op`.
33pub struct PluginLayer<Ser, Op, Pl> {
34    plugin: Pl,
35    _ser: PhantomData<Ser>,
36    _op: PhantomData<Op>,
37}
38
39impl<S, Ser, Op, Pl> Layer<S> for PluginLayer<Ser, Op, Pl>
40where
41    Pl: Plugin<Ser, Op, S>,
42{
43    type Service = Pl::Output;
44
45    fn layer(&self, inner: S) -> Self::Service {
46        self.plugin.apply(inner)
47    }
48}
49
50impl<Pl> PluginLayer<(), (), Pl> {
51    pub fn new<Ser, Op>(plugin: Pl) -> PluginLayer<Ser, Op, Pl> {
52        PluginLayer {
53            plugin,
54            _ser: PhantomData,
55            _op: PhantomData,
56        }
57    }
58}