How about defining Either in Tokio and implement, for example, AsyncWriteExt & AsyncReadExt for it? The code below can be greatly simplified:
#[derive(Debug)]
pub enum Connection {
Tcp(TokioTcpStream),
Tls(TlsStream<TokioTcpStream>),
}
impl AsyncWrite for Connection {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
match self.get_mut() {
Self::Tcp(stream) => Pin::new(stream).poll_write(cx, buf),
Self::Tls(stream) => Pin::new(stream).poll_write(cx, buf),
}
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
match self.get_mut() {
Self::Tcp(stream) => Pin::new(stream).poll_flush(cx),
Self::Tls(stream) => Pin::new(stream).poll_flush(cx),
}
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context) -> Poll<io::Result<()>> {
match self.get_mut() {
Self::Tcp(stream) => Pin::new(stream).poll_shutdown(cx),
Self::Tls(stream) => Pin::new(stream).poll_shutdown(cx),
}
}
}
With Either:
pub type Connection = Either<TokioTcpStream, TlsStream<TokioTcpStream>>;
If it's a good idea, I can take this issue, but I must know where to define it (for example, create either.rs inside folder X).
Thoughts @tokio-rs/maintainers?
Since tokio has own bunch of traits, it could be benefitial ofc
@carllerche i'm generally +1 on this, though i'll note that we've found Either to be a notable source of type explosion (so, Boxed types are equally important IMO).
I'm torn. In a pinch, being able to reach for an Either type is certainly convenient.
However, I feel this optimizes for writing, and I'm an advocate for "optimize for reading". Whenever I come back to code that uses Either, it takes a while to remember the details. Where as in hyper-tls, the enum MaybeHttps<T> { Http(T), Https(Tls<T>) } is immediately understandable.
So I lean slightly towards not providing Either, but more like a -0 that a -1.
I don't think we should provide an either, I think sean's point about naming it specifically to what you need is better. I also find just trait objing it works well. Which is what i do in tonic.
It should be fairly straight forward to implement your own either.
I don't think we should provide an either, I think sean's point about naming it specifically to what you need is better. I also find just trait objing it works well. Which is what i do in tonic.
It should be fairly straight forward to implement your own either.
But I think it should be next to a user to use Either or implement necessary traits by hand.
@LucioFranco @seanmonstar
I've just created a third-party crate for Either.
I think having an Either in tokio-util would be a good idea.
Most helpful comment
@carllerche i'm generally +1 on this, though i'll note that we've found Either to be a notable source of type explosion (so, Boxed types are equally important IMO).