Skip to content

Commit 7248e08

Browse files
committed
recverror
Signed-off-by: Yoshua Wuyts <[email protected]>
1 parent ded088f commit 7248e08

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

Diff for: src/sync/channel.rs

+25-10
Original file line numberDiff line numberDiff line change
@@ -386,20 +386,20 @@ impl<T> Receiver<T> {
386386
/// s.send(2).await;
387387
/// });
388388
///
389-
/// assert_eq!(r.recv().await, Some(1));
390-
/// assert_eq!(r.recv().await, Some(2));
391-
/// assert_eq!(r.recv().await, None);
389+
/// assert_eq!(r.recv().await, Ok(1));
390+
/// assert_eq!(r.recv().await, Ok(2));
391+
/// assert!(r.recv().await.is_err());
392392
/// #
393393
/// # })
394394
/// ```
395-
pub async fn recv(&self) -> Option<T> {
395+
pub async fn recv(&self) -> Result<T, RecvError> {
396396
struct RecvFuture<'a, T> {
397397
channel: &'a Channel<T>,
398398
opt_key: Option<usize>,
399399
}
400400

401401
impl<T> Future for RecvFuture<'_, T> {
402-
type Output = Option<T>;
402+
type Output = Result<T, RecvError>;
403403

404404
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
405405
poll_recv(
@@ -565,12 +565,13 @@ impl<T> Stream for Receiver<T> {
565565

566566
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
567567
let this = &mut *self;
568-
poll_recv(
568+
let res = futures_core::ready!(poll_recv(
569569
&this.channel,
570570
&this.channel.stream_wakers,
571571
&mut this.opt_key,
572572
cx,
573-
)
573+
));
574+
Poll::Ready(res.ok())
574575
}
575576
}
576577

@@ -589,7 +590,7 @@ fn poll_recv<T>(
589590
wakers: &WakerSet,
590591
opt_key: &mut Option<usize>,
591592
cx: &mut Context<'_>,
592-
) -> Poll<Option<T>> {
593+
) -> Poll<Result<T, RecvError>> {
593594
loop {
594595
// If the current task is in the set, remove it.
595596
if let Some(key) = opt_key.take() {
@@ -598,8 +599,8 @@ fn poll_recv<T>(
598599

599600
// Try receiving a message.
600601
match channel.try_recv() {
601-
Ok(msg) => return Poll::Ready(Some(msg)),
602-
Err(TryRecvError::Disconnected) => return Poll::Ready(None),
602+
Ok(msg) => return Poll::Ready(Ok(msg)),
603+
Err(TryRecvError::Disconnected) => return Poll::Ready(Err(RecvError {})),
603604
Err(TryRecvError::Empty) => {
604605
// Insert this receive operation.
605606
*opt_key = Some(wakers.insert(cx));
@@ -1031,3 +1032,17 @@ impl Display for TryRecvError {
10311032
}
10321033
}
10331034
}
1035+
1036+
/// An error returned from the `recv` method.
1037+
#[cfg(feature = "unstable")]
1038+
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
1039+
#[derive(Debug)]
1040+
pub struct RecvError;
1041+
1042+
impl Error for RecvError {}
1043+
1044+
impl Display for RecvError {
1045+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1046+
Display::fmt("The channel is empty.", f)
1047+
}
1048+
}

Diff for: src/sync/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ mod rwlock;
184184

185185
cfg_unstable! {
186186
pub use barrier::{Barrier, BarrierWaitResult};
187-
pub use channel::{channel, Sender, Receiver, TryRecvError, TrySendError};
187+
pub use channel::{channel, Sender, Receiver, RecvError, TryRecvError, TrySendError};
188188

189189
mod barrier;
190190
mod channel;

0 commit comments

Comments
 (0)