use lambda_http::request::RequestContext;
#[doc(inline)]
pub use lambda_http::{
aws_lambda_events::apigw::{ApiGatewayProxyRequestContext, ApiGatewayV2httpRequestContext},
Context,
};
use thiserror::Error;
use super::{internal_server_error, FromParts};
use crate::{body::BoxBody, response::IntoResponse};
#[non_exhaustive]
#[derive(Debug, Error)]
#[error("`Context` is not present in the `http::Request` extensions - consider using `aws_smithy_http_server::routing::LambdaHandler`")]
pub struct MissingContext;
impl<Protocol> IntoResponse<Protocol> for MissingContext {
fn into_response(self) -> http::Response<BoxBody> {
internal_server_error()
}
}
impl<P> FromParts<P> for Context {
type Rejection = MissingContext;
fn from_parts(parts: &mut http::request::Parts) -> Result<Self, Self::Rejection> {
parts.extensions.remove().ok_or(MissingContext)
}
}
#[derive(Debug, Error)]
enum MissingGatewayContextTypeV1 {
#[error("`RequestContext` is not present in the `http::Request` extensions - consider using `aws_smithy_http_server::routing::LambdaHandler`")]
MissingRequestContext,
#[error("`RequestContext::ApiGatewayV2` is present in the `http::Request` extensions - consider using the `aws_smithy_http_server::request::lambda::ApiGatewayV2httpRequestContext` extractor")]
VersionMismatch,
}
#[derive(Debug, Error)]
#[error("{inner}")]
pub struct MissingGatewayContextV1 {
inner: MissingGatewayContextTypeV1,
}
impl<Protocol> IntoResponse<Protocol> for MissingGatewayContextV1 {
fn into_response(self) -> http::Response<BoxBody> {
internal_server_error()
}
}
impl<P> FromParts<P> for ApiGatewayProxyRequestContext {
type Rejection = MissingGatewayContextV1;
fn from_parts(parts: &mut http::request::Parts) -> Result<Self, Self::Rejection> {
let context = parts.extensions.remove().ok_or(MissingGatewayContextV1 {
inner: MissingGatewayContextTypeV1::MissingRequestContext,
})?;
if let RequestContext::ApiGatewayV1(context) = context {
Ok(context)
} else {
Err(MissingGatewayContextV1 {
inner: MissingGatewayContextTypeV1::VersionMismatch,
})
}
}
}
#[derive(Debug, Error)]
enum MissingGatewayContextTypeV2 {
#[error("`RequestContext` is not present in the `http::Request` extensions - consider using `aws_smithy_http_server::routing::LambdaHandler`")]
MissingRequestContext,
#[error("`RequestContext::ApiGatewayV1` is present in the `http::Request` extensions - consider using the `aws_smithy_http_server::request::lambda::ApiGatewayProxyRequestContext` extractor")]
VersionMismatch,
}
#[derive(Debug, Error)]
#[error("{inner}")]
pub struct MissingGatewayContextV2 {
inner: MissingGatewayContextTypeV2,
}
impl<Protocol> IntoResponse<Protocol> for MissingGatewayContextV2 {
fn into_response(self) -> http::Response<BoxBody> {
internal_server_error()
}
}
impl<P> FromParts<P> for ApiGatewayV2httpRequestContext {
type Rejection = MissingGatewayContextV2;
fn from_parts(parts: &mut http::request::Parts) -> Result<Self, Self::Rejection> {
let context = parts.extensions.remove().ok_or(MissingGatewayContextV2 {
inner: MissingGatewayContextTypeV2::MissingRequestContext,
})?;
if let RequestContext::ApiGatewayV2(context) = context {
Ok(context)
} else {
Err(MissingGatewayContextV2 {
inner: MissingGatewayContextTypeV2::VersionMismatch,
})
}
}
}