use std::error::Error;
use std::future::Future;
use std::pin::Pin;
use crate::traits::ActonMessageReply;
pub struct Reply;
impl Reply {
#[inline]
#[must_use]
pub fn ready() -> Pin<Box<impl Future<Output = ()> + Sized>> {
Box::pin(async move {})
}
#[inline]
pub fn pending<F>(future: F) -> Pin<Box<F>>
where
F: Future<Output = ()> + Sized,
{
Box::pin(future)
}
#[inline]
pub fn try_pending<F, T, E>(future: F) -> Pin<Box<F>>
where
F: Future<Output = Result<T, E>> + Send + Sync + 'static,
T: ActonMessageReply + 'static,
E: Error + Send + Sync + 'static,
{
Box::pin(future)
}
#[inline]
#[must_use]
pub fn try_ok<T, E>(value: T) -> Pin<Box<impl Future<Output = Result<T, E>> + Send + Sync>>
where
T: ActonMessageReply + Send + Sync + 'static,
E: Error + Send + Sync + 'static,
{
Box::pin(async move { Ok(value) })
}
#[inline]
#[must_use]
pub fn try_err<T, E>(error: E) -> Pin<Box<impl Future<Output = Result<T, E>> + Send + Sync>>
where
T: ActonMessageReply + Send + Sync + 'static,
E: Error + Send + Sync + 'static,
{
Box::pin(async move { Err(error) })
}
#[inline]
#[must_use]
#[deprecated(since = "7.1.0", note = "Use Reply::ready() instead")]
pub fn immediate() -> Pin<Box<impl Future<Output = ()> + Sized>> {
Self::ready()
}
#[inline]
#[deprecated(since = "7.1.0", note = "Use Reply::pending() instead")]
pub fn from_async<F>(future: F) -> Pin<Box<F>>
where
F: Future<Output = ()> + Sized,
{
Self::pending(future)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug)]
struct TestSuccess {
value: i32,
}
#[derive(Debug)]
struct TestError(String);
impl std::fmt::Display for TestError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl Error for TestError {}
#[tokio::test]
async fn test_ready() {
let fut = Reply::ready();
fut.await; }
#[tokio::test]
async fn test_pending() {
let fut = Reply::pending(async {
});
fut.await;
}
#[tokio::test]
async fn test_try_ok() {
let fut: Pin<Box<dyn Future<Output = Result<TestSuccess, TestError>> + Send + Sync>> =
Reply::try_ok(TestSuccess { value: 42 });
let result = fut.await;
assert!(result.is_ok());
assert_eq!(result.unwrap().value, 42);
}
#[tokio::test]
async fn test_try_err() {
let fut: Pin<Box<dyn Future<Output = Result<TestSuccess, TestError>> + Send + Sync>> =
Reply::try_err(TestError("test error".to_string()));
let result = fut.await;
assert!(result.is_err());
assert_eq!(result.unwrap_err().0, "test error");
}
#[tokio::test]
async fn test_try_pending_ok() {
let fut =
Reply::try_pending(async { Ok::<TestSuccess, TestError>(TestSuccess { value: 100 }) });
let result = fut.await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_try_pending_err() {
let fut = Reply::try_pending(async { Err::<TestSuccess, _>(TestError("failed".into())) });
let result = fut.await;
assert!(result.is_err());
}
}