Skip to content

Commit

Permalink
refactor(core)!: remove EitherError in favor of either::Either (#…
Browse files Browse the repository at this point in the history
…3337)

Defining our own `EitherError` type has no value now that `Either` provides the same implementation.

Related: #3271
  • Loading branch information
thomaseizinger authored Jan 17, 2023
1 parent 29a7716 commit f4fed38
Show file tree
Hide file tree
Showing 17 changed files with 118 additions and 144 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ libp2p-gossipsub = { version = "0.44.0", path = "protocols/gossipsub", optional
[dev-dependencies]
async-std = { version = "1.6.2", features = ["attributes"] }
async-trait = "0.1"
either = "1.8.0"
env_logger = "0.10.0"
clap = { version = "4.0.13", features = ["derive"] }
tokio = { version = "1.15", features = ["io-util", "io-std", "macros", "rt", "rt-multi-thread"] }
Expand Down
3 changes: 3 additions & 0 deletions core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@

- Improve error messages in case keys cannot be decoded because of missing feature flags. See [PR 2972].

- Remove `EitherError` in favor of `either::Either`. See [PR 3337].

[PR 3031]: https://github.com/libp2p/rust-libp2p/pull/3031
[PR 3058]: https://github.com/libp2p/rust-libp2p/pull/3058
[PR 3097]: https://github.com/libp2p/rust-libp2p/pull/3097
[PR 3090]: https://github.com/libp2p/rust-libp2p/pull/3090
[PR 2972]: https://github.com/libp2p/rust-libp2p/pull/2972
[PR 3337]: https://github.com/libp2p/rust-libp2p/pull/3337

# 0.37.0

Expand Down
113 changes: 40 additions & 73 deletions core/src/either.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,44 +24,13 @@ use crate::{
transport::{ListenerId, Transport, TransportError, TransportEvent},
Multiaddr, ProtocolName,
};
use either::Either;
use futures::{
io::{IoSlice, IoSliceMut},
prelude::*,
};
use pin_project::pin_project;
use std::{fmt, io, pin::Pin, task::Context, task::Poll};

#[derive(Debug, Copy, Clone)]
pub enum EitherError<A, B> {
A(A),
B(B),
}

impl<A, B> fmt::Display for EitherError<A, B>
where
A: fmt::Display,
B: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EitherError::A(a) => a.fmt(f),
EitherError::B(b) => b.fmt(f),
}
}
}

impl<A, B> std::error::Error for EitherError<A, B>
where
A: std::error::Error,
B: std::error::Error,
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
EitherError::A(a) => a.source(),
EitherError::B(b) => b.source(),
}
}
}
use std::{io, pin::Pin, task::Context, task::Poll};

/// Implements `AsyncRead` and `AsyncWrite` and dispatches all method calls to
/// either `First` or `Second`.
Expand Down Expand Up @@ -147,15 +116,15 @@ where
A: TryStream<Ok = I>,
B: TryStream<Ok = I>,
{
type Item = Result<I, EitherError<A::Error, B::Error>>;
type Item = Result<I, Either<A::Error, B::Error>>;

fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
match self.project() {
EitherOutputProj::First(a) => {
TryStream::try_poll_next(a, cx).map(|v| v.map(|r| r.map_err(EitherError::A)))
TryStream::try_poll_next(a, cx).map(|v| v.map(|r| r.map_err(Either::Left)))
}
EitherOutputProj::Second(b) => {
TryStream::try_poll_next(b, cx).map(|v| v.map(|r| r.map_err(EitherError::B)))
TryStream::try_poll_next(b, cx).map(|v| v.map(|r| r.map_err(Either::Right)))
}
}
}
Expand All @@ -166,33 +135,33 @@ where
A: Sink<I>,
B: Sink<I>,
{
type Error = EitherError<A::Error, B::Error>;
type Error = Either<A::Error, B::Error>;

fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self.project() {
EitherOutputProj::First(a) => Sink::poll_ready(a, cx).map_err(EitherError::A),
EitherOutputProj::Second(b) => Sink::poll_ready(b, cx).map_err(EitherError::B),
EitherOutputProj::First(a) => Sink::poll_ready(a, cx).map_err(Either::Left),
EitherOutputProj::Second(b) => Sink::poll_ready(b, cx).map_err(Either::Right),
}
}

fn start_send(self: Pin<&mut Self>, item: I) -> Result<(), Self::Error> {
match self.project() {
EitherOutputProj::First(a) => Sink::start_send(a, item).map_err(EitherError::A),
EitherOutputProj::Second(b) => Sink::start_send(b, item).map_err(EitherError::B),
EitherOutputProj::First(a) => Sink::start_send(a, item).map_err(Either::Left),
EitherOutputProj::Second(b) => Sink::start_send(b, item).map_err(Either::Right),
}
}

fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self.project() {
EitherOutputProj::First(a) => Sink::poll_flush(a, cx).map_err(EitherError::A),
EitherOutputProj::Second(b) => Sink::poll_flush(b, cx).map_err(EitherError::B),
EitherOutputProj::First(a) => Sink::poll_flush(a, cx).map_err(Either::Left),
EitherOutputProj::Second(b) => Sink::poll_flush(b, cx).map_err(Either::Right),
}
}

fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self.project() {
EitherOutputProj::First(a) => Sink::poll_close(a, cx).map_err(EitherError::A),
EitherOutputProj::Second(b) => Sink::poll_close(b, cx).map_err(EitherError::B),
EitherOutputProj::First(a) => Sink::poll_close(a, cx).map_err(Either::Left),
EitherOutputProj::Second(b) => Sink::poll_close(b, cx).map_err(Either::Right),
}
}
}
Expand All @@ -203,7 +172,7 @@ where
B: StreamMuxer,
{
type Substream = EitherOutput<A::Substream, B::Substream>;
type Error = EitherError<A::Error, B::Error>;
type Error = Either<A::Error, B::Error>;

fn poll_inbound(
self: Pin<&mut Self>,
Expand All @@ -213,11 +182,11 @@ where
EitherOutputProj::First(inner) => inner
.poll_inbound(cx)
.map_ok(EitherOutput::First)
.map_err(EitherError::A),
.map_err(Either::Left),
EitherOutputProj::Second(inner) => inner
.poll_inbound(cx)
.map_ok(EitherOutput::Second)
.map_err(EitherError::B),
.map_err(Either::Right),
}
}

Expand All @@ -229,18 +198,18 @@ where
EitherOutputProj::First(inner) => inner
.poll_outbound(cx)
.map_ok(EitherOutput::First)
.map_err(EitherError::A),
.map_err(Either::Left),
EitherOutputProj::Second(inner) => inner
.poll_outbound(cx)
.map_ok(EitherOutput::Second)
.map_err(EitherError::B),
.map_err(Either::Right),
}
}

fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self.project() {
EitherOutputProj::First(inner) => inner.poll_close(cx).map_err(EitherError::A),
EitherOutputProj::Second(inner) => inner.poll_close(cx).map_err(EitherError::B),
EitherOutputProj::First(inner) => inner.poll_close(cx).map_err(Either::Left),
EitherOutputProj::Second(inner) => inner.poll_close(cx).map_err(Either::Right),
}
}

Expand All @@ -249,8 +218,8 @@ where
cx: &mut Context<'_>,
) -> Poll<Result<StreamMuxerEvent, Self::Error>> {
match self.project() {
EitherOutputProj::First(inner) => inner.poll(cx).map_err(EitherError::A),
EitherOutputProj::Second(inner) => inner.poll(cx).map_err(EitherError::B),
EitherOutputProj::First(inner) => inner.poll(cx).map_err(Either::Left),
EitherOutputProj::Second(inner) => inner.poll(cx).map_err(Either::Right),
}
}
}
Expand All @@ -269,16 +238,16 @@ where
AFuture: TryFuture<Ok = AInner>,
BFuture: TryFuture<Ok = BInner>,
{
type Output = Result<EitherOutput<AInner, BInner>, EitherError<AFuture::Error, BFuture::Error>>;
type Output = Result<EitherOutput<AInner, BInner>, Either<AFuture::Error, BFuture::Error>>;

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.project() {
EitherFutureProj::First(a) => TryFuture::try_poll(a, cx)
.map_ok(EitherOutput::First)
.map_err(EitherError::A),
.map_err(Either::Left),
EitherFutureProj::Second(a) => TryFuture::try_poll(a, cx)
.map_ok(EitherOutput::Second)
.map_err(EitherError::B),
.map_err(Either::Right),
}
}
}
Expand All @@ -296,16 +265,16 @@ where
AFut: TryFuture<Ok = AItem, Error = AError>,
BFut: TryFuture<Ok = BItem, Error = BError>,
{
type Output = Result<EitherOutput<AItem, BItem>, EitherError<AError, BError>>;
type Output = Result<EitherOutput<AItem, BItem>, Either<AError, BError>>;

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.project() {
EitherFuture2Proj::A(a) => TryFuture::try_poll(a, cx)
.map_ok(EitherOutput::First)
.map_err(EitherError::A),
.map_err(Either::Left),
EitherFuture2Proj::B(a) => TryFuture::try_poll(a, cx)
.map_ok(EitherOutput::Second)
.map_err(EitherError::B),
.map_err(Either::Right),
}
}
}
Expand Down Expand Up @@ -338,7 +307,7 @@ where
A: Transport,
{
type Output = EitherOutput<A::Output, B::Output>;
type Error = EitherError<A::Error, B::Error>;
type Error = Either<A::Error, B::Error>;
type ListenerUpgrade = EitherFuture<A::ListenerUpgrade, B::ListenerUpgrade>;
type Dial = EitherFuture<A::Dial, B::Dial>;

Expand All @@ -349,18 +318,16 @@ where
match self.project() {
EitherTransportProj::Left(a) => match a.poll(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(event) => Poll::Ready(
event
.map_upgrade(EitherFuture::First)
.map_err(EitherError::A),
),
Poll::Ready(event) => {
Poll::Ready(event.map_upgrade(EitherFuture::First).map_err(Either::Left))
}
},
EitherTransportProj::Right(b) => match b.poll(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(event) => Poll::Ready(
event
.map_upgrade(EitherFuture::Second)
.map_err(EitherError::B),
.map_err(Either::Right),
),
},
}
Expand All @@ -378,11 +345,11 @@ where
match self {
EitherTransport::Left(a) => a.listen_on(addr).map_err(|e| match e {
MultiaddrNotSupported(addr) => MultiaddrNotSupported(addr),
Other(err) => Other(EitherError::A(err)),
Other(err) => Other(Either::Left(err)),
}),
EitherTransport::Right(b) => b.listen_on(addr).map_err(|e| match e {
MultiaddrNotSupported(addr) => MultiaddrNotSupported(addr),
Other(err) => Other(EitherError::B(err)),
Other(err) => Other(Either::Right(err)),
}),
}
}
Expand All @@ -393,12 +360,12 @@ where
EitherTransport::Left(a) => match a.dial(addr) {
Ok(connec) => Ok(EitherFuture::First(connec)),
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
Err(Other(err)) => Err(Other(EitherError::A(err))),
Err(Other(err)) => Err(Other(Either::Left(err))),
},
EitherTransport::Right(b) => match b.dial(addr) {
Ok(connec) => Ok(EitherFuture::Second(connec)),
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
Err(Other(err)) => Err(Other(EitherError::B(err))),
Err(Other(err)) => Err(Other(Either::Right(err))),
},
}
}
Expand All @@ -415,12 +382,12 @@ where
EitherTransport::Left(a) => match a.dial_as_listener(addr) {
Ok(connec) => Ok(EitherFuture::First(connec)),
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
Err(Other(err)) => Err(Other(EitherError::A(err))),
Err(Other(err)) => Err(Other(Either::Left(err))),
},
EitherTransport::Right(b) => match b.dial_as_listener(addr) {
Ok(connec) => Ok(EitherFuture::Second(connec)),
Err(MultiaddrNotSupported(addr)) => Err(MultiaddrNotSupported(addr)),
Err(Other(err)) => Err(Other(EitherError::B(err))),
Err(Other(err)) => Err(Other(Either::Right(err))),
},
}
}
Expand Down
20 changes: 10 additions & 10 deletions core/src/transport/and_then.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@

use crate::{
connection::{ConnectedPoint, Endpoint},
either::EitherError,
transport::{ListenerId, Transport, TransportError, TransportEvent},
};
use futures::{future::Either, prelude::*};
use either::Either;
use futures::prelude::*;
use multiaddr::Multiaddr;
use std::{error, marker::PhantomPinned, pin::Pin, task::Context, task::Poll};

Expand All @@ -50,14 +50,14 @@ where
F::Error: error::Error,
{
type Output = O;
type Error = EitherError<T::Error, F::Error>;
type Error = Either<T::Error, F::Error>;
type ListenerUpgrade = AndThenFuture<T::ListenerUpgrade, C, F>;
type Dial = AndThenFuture<T::Dial, C, F>;

fn listen_on(&mut self, addr: Multiaddr) -> Result<ListenerId, TransportError<Self::Error>> {
self.transport
.listen_on(addr)
.map_err(|err| err.map(EitherError::A))
.map_err(|err| err.map(Either::Left))
}

fn remove_listener(&mut self, id: ListenerId) -> bool {
Expand All @@ -68,7 +68,7 @@ where
let dialed_fut = self
.transport
.dial(addr.clone())
.map_err(|err| err.map(EitherError::A))?;
.map_err(|err| err.map(Either::Left))?;
let future = AndThenFuture {
inner: Either::Left(Box::pin(dialed_fut)),
args: Some((
Expand All @@ -90,7 +90,7 @@ where
let dialed_fut = self
.transport
.dial_as_listener(addr.clone())
.map_err(|err| err.map(EitherError::A))?;
.map_err(|err| err.map(Either::Left))?;
let future = AndThenFuture {
inner: Either::Left(Box::pin(dialed_fut)),
args: Some((
Expand Down Expand Up @@ -139,7 +139,7 @@ where
Poll::Ready(other) => {
let mapped = other
.map_upgrade(|_upgrade| unreachable!("case already matched"))
.map_err(EitherError::A);
.map_err(Either::Left);
Poll::Ready(mapped)
}
Poll::Pending => Poll::Pending,
Expand All @@ -163,15 +163,15 @@ where
TMap: FnOnce(TFut::Ok, ConnectedPoint) -> TMapOut,
TMapOut: TryFuture,
{
type Output = Result<TMapOut::Ok, EitherError<TFut::Error, TMapOut::Error>>;
type Output = Result<TMapOut::Ok, Either<TFut::Error, TMapOut::Error>>;

fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
loop {
let future = match &mut self.inner {
Either::Left(future) => {
let item = match TryFuture::try_poll(future.as_mut(), cx) {
Poll::Ready(Ok(v)) => v,
Poll::Ready(Err(err)) => return Poll::Ready(Err(EitherError::A(err))),
Poll::Ready(Err(err)) => return Poll::Ready(Err(Either::Left(err))),
Poll::Pending => return Poll::Pending,
};
let (f, a) = self
Expand All @@ -183,7 +183,7 @@ where
Either::Right(future) => {
return match TryFuture::try_poll(future.as_mut(), cx) {
Poll::Ready(Ok(v)) => Poll::Ready(Ok(v)),
Poll::Ready(Err(err)) => return Poll::Ready(Err(EitherError::B(err))),
Poll::Ready(Err(err)) => return Poll::Ready(Err(Either::Right(err))),
Poll::Pending => Poll::Pending,
}
}
Expand Down
Loading

0 comments on commit f4fed38

Please sign in to comment.