Unverified Commit 50e85724 authored by 82marbag's avatar 82marbag Committed by GitHub
Browse files

Route::new in upgrade (#1891)



* Route::new in upgrade

Move the creation of Routes in Upgradable to have a cleaner sequence of
constraints in ServiceBuilder::build

Signed-off-by: default avatarDaniele Ahmed <ahmeddan@amazon.de>
parent 2015331e
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -162,11 +162,7 @@ class ServerServiceGeneratorV2(
                    $exts,
                    B,
                    Pl,
                >,
                $type::Service: Clone + Send + 'static,
                <$type::Service as #{Tower}::Service<#{Http}::Request<B>>>::Future: Send + 'static,

                $type::Service: #{Tower}::Service<#{Http}::Request<B>, Error = std::convert::Infallible>
                >
                """,
                "Marker" to protocol.markerStruct(),
                *codegenScope,
+2 −2
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ class ServerAwsJsonProtocol(
                    """
                    (
                        String::from("$serviceName.$operationName"),
                        #{SmithyHttpServer}::routing::Route::new(#{OperationValue:W})
                        #{OperationValue:W}
                    ),
                    """,
                    "OperationValue" to operationValue,
@@ -184,7 +184,7 @@ private fun restRouterConstruction(
                """
                (
                    #{Key:W},
                    #{SmithyHttpServer}::routing::Route::new(#{OperationValue:W})
                    #{OperationValue:W}
                ),
                """,
                "Key" to key,
+18 −15
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ use crate::{
    plugin::Plugin,
    request::{FromParts, FromRequest},
    response::IntoResponse,
    routing::Route,
    runtime_error::InternalFailureException,
};

@@ -70,9 +71,6 @@ impl<S, P, Op, E, B> Layer<S> for UpgradeLayer<P, Op, E, B> {
    }
}

/// An alias allowing for quick access to [`UpgradeLayer`]s target [`Service`].
pub type UpgradedService<P, Op, E, B, S> = <UpgradeLayer<P, Op, E, B> as Layer<S>>::Service;

/// A [`Service`] responsible for wrapping an operation [`Service`] accepting and returning Smithy
/// types, and converting it into a [`Service`] accepting and returning [`http`] types.
pub struct Upgrade<Protocol, Operation, Exts, B, S> {
@@ -222,12 +220,14 @@ where
/// Provides an interface to convert a representation of an operation to a HTTP [`Service`](tower::Service) with
/// canonical associated types.
pub trait Upgradable<Protocol, Operation, Exts, B, Plugin> {
    type Service: Service<http::Request<B>, Response = http::Response<BoxBody>>;

    /// Performs an upgrade from a representation of an operation to a HTTP [`Service`](tower::Service).
    fn upgrade(self, plugin: &Plugin) -> Self::Service;
    fn upgrade(self, plugin: &Plugin) -> Route<B>;
}

type UpgradedService<Pl, P, Op, Exts, B, S, L> = <<Pl as Plugin<P, Op, S, L>>::Layer as Layer<
    Upgrade<P, Op, Exts, B, <Pl as Plugin<P, Op, S, L>>::Service>,
>>::Service;

impl<P, Op, Exts, B, Pl, S, L, PollError> Upgradable<P, Op, Exts, B, Pl> for Operation<S, L>
where
    // `Op` is used to specify the operation shape
@@ -255,17 +255,20 @@ where
    // The signature of the output is correct
    <Pl::Layer as Layer<Upgrade<P, Op, Exts, B, Pl::Service>>>::Service:
        Service<http::Request<B>, Response = http::Response<BoxBody>>,
{
    type Service = <Pl::Layer as Layer<Upgrade<P, Op, Exts, B, Pl::Service>>>::Service;

    // For `Route::new` for the resulting service
    <Pl::Layer as Layer<Upgrade<P, Op, Exts, B, Pl::Service>>>::Service: Service<http::Request<B>, Error = Infallible>,
    UpgradedService<Pl, P, Op, Exts, B, S, L>: Clone + Send + 'static,
    <UpgradedService<Pl, P, Op, Exts, B, S, L> as Service<http::Request<B>>>::Future: Send + 'static,
{
    /// Takes the [`Operation<S, L>`](Operation), applies [`Plugin`], then applies [`UpgradeLayer`] to
    /// the modified `S`, then finally applies the modified `L`.
    ///
    /// The composition is made explicit in the method constraints and return type.
    fn upgrade(self, plugin: &Pl) -> Self::Service {
    fn upgrade(self, plugin: &Pl) -> Route<B> {
        let mapped = plugin.map(self);
        let layer = Stack::new(UpgradeLayer::new(), mapped.layer);
        layer.layer(mapped.inner)
        Route::new(layer.layer(mapped.inner))
    }
}

@@ -282,17 +285,17 @@ pub struct FailOnMissingOperation;
impl<P, Op, Exts, B, Pl> Upgradable<P, Op, Exts, B, Pl> for FailOnMissingOperation
where
    InternalFailureException: IntoResponse<P>,
    P: 'static,
{
    type Service = MissingFailure<P>;

    fn upgrade(self, _plugin: &Pl) -> Self::Service {
        MissingFailure { _protocol: PhantomData }
    fn upgrade(self, _plugin: &Pl) -> Route<B> {
        Route::new(MissingFailure { _protocol: PhantomData })
    }
}

/// A [`Service`] which always returns an internal failure message and logs an error.
#[derive(Copy)]
pub struct MissingFailure<P> {
    _protocol: PhantomData<P>,
    _protocol: PhantomData<fn(P)>,
}

impl<P> Clone for MissingFailure<P> {