use core::task::Poll;
pub trait PollExt<T> {
fn unwrap(self) -> T;
fn expect(self, msg: &str) -> T;
fn expect_pending(&self, msg: &str);
fn ready_or<E>(self, error: E) -> Result<T, E>;
fn ready_or_else<E, F>(self, error: F) -> Result<T, E>
where
F: FnOnce() -> E;
}
impl<T> PollExt<T> for Poll<T> {
#[inline]
#[track_caller]
fn unwrap(self) -> T {
match self {
Poll::Ready(val) => val,
Poll::Pending => panic!("called `Poll::unwrap()` on a `Pending` value"),
}
}
#[inline]
#[track_caller]
fn expect(self, msg: &str) -> T {
match self {
Poll::Ready(val) => val,
Poll::Pending => panic!("{}", msg),
}
}
#[inline]
#[track_caller]
fn expect_pending(&self, msg: &str) {
if self.is_ready() {
panic!("{}", msg);
}
}
fn ready_or<E>(self, error: E) -> Result<T, E> {
self.ready_or_else(|| error)
}
fn ready_or_else<E, F>(self, error: F) -> Result<T, E>
where
F: FnOnce() -> E,
{
match self {
Poll::Ready(val) => Ok(val),
Poll::Pending => Err(error()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn poll_unwrap_ready_returns_value() {
let p = Poll::Ready("value");
assert_eq!(p.unwrap(), "value");
}
#[test]
#[should_panic]
fn poll_unwrap_pending_panics() {
let p: Poll<()> = Poll::Pending;
p.unwrap();
}
#[test]
fn poll_expect_ready_returns_value() {
let p = Poll::Ready("value");
assert_eq!(p.expect("missing value"), "value");
}
#[test]
fn poll_expect_pending() {
let p: Poll<()> = Poll::Pending;
p.expect_pending("is pending");
}
#[test]
#[should_panic]
fn poll_expect_pending_on_ready() {
let p = Poll::Ready("value");
p.expect_pending("value is not pending");
}
#[test]
#[should_panic(expected = "missing value")]
fn poll_expect_pending_panics_with_message() {
let p: Poll<()> = Poll::Pending;
p.expect("missing value");
}
#[test]
fn poll_ready_or_ready_returns_ok() {
let p = Poll::Ready("value");
assert_eq!(p.ready_or(()), Ok("value"));
}
#[test]
fn poll_ready_or_pending_returns_error() {
let p: Poll<()> = Poll::Pending;
assert_eq!(p.ready_or(()), Err(()));
}
#[test]
fn poll_ready_or_else_ready_returns_ok() {
let p = Poll::Ready("value");
assert_eq!(p.ready_or_else(|| ()), Ok("value"));
}
#[test]
fn poll_ready_or_else_pending_returns_error() {
let p: Poll<()> = Poll::Pending;
assert_eq!(p.ready_or_else(|| ()), Err(()));
}
}