use std::marker::PhantomData;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::task::{Context, Poll};
use http::Uri;
use tower::BoxError;
use aws_smithy_async::future::never::Never;
use aws_smithy_http::body::SdkBody;
use aws_smithy_http::result::ConnectorError;
use crate::erase::boxclone::BoxFuture;
#[non_exhaustive]
#[derive(Debug)]
pub struct NeverService<Req, Resp, Err> {
_resp: PhantomData<(Req, Resp, Err)>,
invocations: Arc<AtomicUsize>,
}
impl<Req, Resp, Err> Clone for NeverService<Req, Resp, Err> {
fn clone(&self) -> Self {
Self {
_resp: Default::default(),
invocations: self.invocations.clone(),
}
}
}
impl<Req, Resp, Err> Default for NeverService<Req, Resp, Err> {
fn default() -> Self {
Self::new()
}
}
impl<Req, Resp, Err> NeverService<Req, Resp, Err> {
pub fn new() -> Self {
NeverService {
_resp: Default::default(),
invocations: Default::default(),
}
}
pub fn num_calls(&self) -> usize {
self.invocations.load(Ordering::SeqCst)
}
}
pub type NeverConnector =
NeverService<http::Request<SdkBody>, http::Response<SdkBody>, ConnectorError>;
pub type NeverConnected = NeverService<Uri, stream::EmptyStream, BoxError>;
pub(crate) mod stream {
use std::io::Error;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
#[non_exhaustive]
#[derive(Debug, Default)]
pub struct EmptyStream;
impl EmptyStream {
pub fn new() -> Self {
Self
}
}
impl AsyncRead for EmptyStream {
fn poll_read(
self: Pin<&mut Self>,
_cx: &mut Context<'_>,
_buf: &mut ReadBuf<'_>,
) -> Poll<std::io::Result<()>> {
Poll::Pending
}
}
impl AsyncWrite for EmptyStream {
fn poll_write(
self: Pin<&mut Self>,
_cx: &mut Context<'_>,
_buf: &[u8],
) -> Poll<Result<usize, Error>> {
Poll::Pending
}
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
Poll::Pending
}
fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
Poll::Pending
}
}
}
#[derive(Clone, Debug, Default)]
pub struct NeverReplies;
impl NeverReplies {
pub fn new() -> Self {
Self
}
}
impl tower::Service<Uri> for NeverReplies {
type Response = stream::EmptyStream;
type Error = BoxError;
type Future = std::future::Ready<Result<Self::Response, Self::Error>>;
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, _req: Uri) -> Self::Future {
std::future::ready(Ok(stream::EmptyStream::new()))
}
}
impl<Req, Resp, Err> tower::Service<Req> for NeverService<Req, Resp, Err> {
type Response = Resp;
type Error = Err;
type Future = BoxFuture<Self::Response, Self::Error>;
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, _req: Req) -> Self::Future {
self.invocations.fetch_add(1, Ordering::SeqCst);
Box::pin(async move {
Never::new().await;
unreachable!()
})
}
}