Skip to content

Commit 72aab81

Browse files
committed
recverror
Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
1 parent 7c72329 commit 72aab81

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

Diff for: src/sync/channel.rs

+26-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::cell::UnsafeCell;
22
use std::error::Error;
3-
use std::fmt::{Debug, Display, self};
3+
use std::fmt::{self, Debug, Display};
44
use std::future::Future;
55
use std::isize;
66
use std::marker::PhantomData;
@@ -388,22 +388,20 @@ impl<T> Receiver<T> {
388388
/// // Then we drop the sender
389389
/// });
390390
///
391-
/// assert_eq!(r.recv().await, Some(1));
392-
/// assert_eq!(r.recv().await, Some(2));
393-
///
394-
/// // recv() returns `None`
395-
/// assert_eq!(r.recv().await, None);
391+
/// assert_eq!(r.recv().await, Ok(1));
392+
/// assert_eq!(r.recv().await, Ok(2));
393+
/// assert!(r.recv().await.is_err());
396394
/// #
397395
/// # })
398396
/// ```
399-
pub async fn recv(&self) -> Option<T> {
397+
pub async fn recv(&self) -> Result<T, RecvError> {
400398
struct RecvFuture<'a, T> {
401399
channel: &'a Channel<T>,
402400
opt_key: Option<usize>,
403401
}
404402

405403
impl<T> Future for RecvFuture<'_, T> {
406-
type Output = Option<T>;
404+
type Output = Result<T, RecvError>;
407405

408406
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
409407
poll_recv(
@@ -569,12 +567,13 @@ impl<T> Stream for Receiver<T> {
569567

570568
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
571569
let this = &mut *self;
572-
poll_recv(
570+
let res = futures_core::ready!(poll_recv(
573571
&this.channel,
574572
&this.channel.stream_wakers,
575573
&mut this.opt_key,
576574
cx,
577-
)
575+
));
576+
Poll::Ready(res.ok())
578577
}
579578
}
580579

@@ -593,7 +592,7 @@ fn poll_recv<T>(
593592
wakers: &WakerSet,
594593
opt_key: &mut Option<usize>,
595594
cx: &mut Context<'_>,
596-
) -> Poll<Option<T>> {
595+
) -> Poll<Result<T, RecvError>> {
597596
loop {
598597
// If the current task is in the set, remove it.
599598
if let Some(key) = opt_key.take() {
@@ -602,8 +601,8 @@ fn poll_recv<T>(
602601

603602
// Try receiving a message.
604603
match channel.try_recv() {
605-
Ok(msg) => return Poll::Ready(Some(msg)),
606-
Err(TryRecvError::Disconnected) => return Poll::Ready(None),
604+
Ok(msg) => return Poll::Ready(Ok(msg)),
605+
Err(TryRecvError::Disconnected) => return Poll::Ready(Err(RecvError {})),
607606
Err(TryRecvError::Empty) => {
608607
// Insert this receive operation.
609608
*opt_key = Some(wakers.insert(cx));
@@ -1035,3 +1034,17 @@ impl Display for TryRecvError {
10351034
}
10361035
}
10371036
}
1037+
1038+
/// An error returned from the `recv` method.
1039+
#[cfg(feature = "unstable")]
1040+
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
1041+
#[derive(Debug)]
1042+
pub struct RecvError;
1043+
1044+
impl Error for RecvError {}
1045+
1046+
impl Display for RecvError {
1047+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1048+
Display::fmt("The channel is empty.", f)
1049+
}
1050+
}

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)