Skip to content

Commit

Permalink
Route::new in upgrade (#1891)
Browse files Browse the repository at this point in the history
* Route::new in upgrade

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

Signed-off-by: Daniele Ahmed <[email protected]>
  • Loading branch information
82marbag authored Oct 26, 2022
1 parent 2015331 commit 50e8572
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class ServerServiceGeneratorV2(
private val buildConstraints = operations.zip(builderOps).zip(extensionTypes).map { (first, exts) ->
val (operation, type) = first
// TODO(https://github.com/awslabs/smithy-rs/issues/1713#issue-1365169734): The `Error = Infallible` is an
// excess requirement to stay at parity with existing builder.
// excess requirement to stay at parity with existing builder.
writable {
rustTemplate(
"""
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class ServerAwsJsonProtocol(
"""
(
String::from("$serviceName.$operationName"),
#{SmithyHttpServer}::routing::Route::new(#{OperationValue:W})
#{OperationValue:W}
),
""",
"OperationValue" to operationValue,
Expand Down Expand Up @@ -184,7 +184,7 @@ private fun restRouterConstruction(
"""
(
#{Key:W},
#{SmithyHttpServer}::routing::Route::new(#{OperationValue:W})
#{OperationValue:W}
),
""",
"Key" to key,
Expand Down
33 changes: 18 additions & 15 deletions rust-runtime/aws-smithy-http-server/src/operation/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::{
plugin::Plugin,
request::{FromParts, FromRequest},
response::IntoResponse,
routing::Route,
runtime_error::InternalFailureException,
};

Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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))
}
}

Expand All @@ -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> {
Expand Down

0 comments on commit 50e8572

Please sign in to comment.