The only important trait for a user is the `tower::Service` trait, which is now available also at `hyper::service::Service`. The other "trait aliases" are no longer publicly exported, as people thought they had to implement them. Also removes dependency on `tower-make`, which is trivial but otherwise shouldn't affect anyone. Closes #1959
82 lines
2.5 KiB
Rust
82 lines
2.5 KiB
Rust
//! Utilities used to interact with the Tower ecosystem.
|
|
//!
|
|
//! This module provides `Connect` which hook-ins into the Tower ecosystem.
|
|
|
|
use std::marker::PhantomData;
|
|
use std::future::Future;
|
|
use std::error::Error as StdError;
|
|
|
|
use crate::{common::{Poll, task, Pin}, body::Payload, service::{MakeConnection, Service}};
|
|
use super::conn::{SendRequest, Builder};
|
|
|
|
/// Creates a connection via `SendRequest`.
|
|
///
|
|
/// This accepts a `hyper::client::conn::Builder` and provides
|
|
/// a `MakeService` implementation to create connections from some
|
|
/// target `T`.
|
|
#[derive(Debug)]
|
|
pub struct Connect<C, B, T> {
|
|
inner: C,
|
|
builder: Builder,
|
|
_pd: PhantomData<fn(T, B)>
|
|
}
|
|
|
|
impl<C, B, T> Connect<C, B, T> {
|
|
/// Create a new `Connect` with some inner connector `C` and a connection
|
|
/// builder.
|
|
pub fn new(inner: C, builder: Builder) -> Self {
|
|
Self {
|
|
inner,
|
|
builder,
|
|
_pd: PhantomData
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<C, B, T> Service<T> for Connect<C, B, T>
|
|
where
|
|
C: MakeConnection<T>,
|
|
C::Connection: Unpin + Send + 'static,
|
|
C::Future: Send + 'static,
|
|
C::Error: Into<Box<dyn StdError + Send + Sync>> + Send,
|
|
B: Payload + Unpin + 'static,
|
|
B::Data: Unpin,
|
|
{
|
|
type Response = SendRequest<B>;
|
|
type Error = crate::Error;
|
|
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
|
|
|
|
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
self.inner.poll_ready(cx).map_err(|e| crate::Error::new(crate::error::Kind::Connect).with(e.into()))
|
|
}
|
|
|
|
fn call(&mut self, req: T) -> Self::Future {
|
|
let builder = self.builder.clone();
|
|
let io = self.inner.make_connection(req);
|
|
|
|
let fut = async move {
|
|
match io.await {
|
|
Ok(io) => {
|
|
match builder.handshake(io).await {
|
|
Ok((sr, conn)) => {
|
|
builder.exec.execute(async move {
|
|
if let Err(e) = conn.await {
|
|
debug!("connection error: {:?}", e);
|
|
}
|
|
})?;
|
|
Ok(sr)
|
|
},
|
|
Err(e) => Err(e)
|
|
}
|
|
},
|
|
Err(e) => {
|
|
let err = crate::Error::new(crate::error::Kind::Connect).with(e.into());
|
|
Err(err)
|
|
}
|
|
}
|
|
};
|
|
|
|
Box::pin(fut)
|
|
}
|
|
}
|