use std::time::Duration;
use tokio::sync::oneshot;
use crate::error::{Error, Result};
pub struct EventWaiter<T> {
receiver: oneshot::Receiver<T>,
timeout_ms: Option<f64>,
}
impl<T: Send + 'static> EventWaiter<T> {
pub(crate) fn new(receiver: oneshot::Receiver<T>, timeout_ms: Option<f64>) -> Self {
Self {
receiver,
timeout_ms,
}
}
pub async fn wait(self) -> Result<T> {
let timeout_ms = self.timeout_ms.unwrap_or(30_000.0);
let timeout_duration = Duration::from_millis(timeout_ms as u64);
match tokio::time::timeout(timeout_duration, self.receiver).await {
Ok(Ok(value)) => Ok(value),
Ok(Err(_)) => Err(Error::ProtocolError(
"Event source closed before event fired".to_string(),
)),
Err(_) => Err(Error::Timeout(format!(
"Timed out waiting for event after {timeout_ms}ms"
))),
}
}
}
impl<T> std::fmt::Debug for EventWaiter<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EventWaiter")
.field("timeout_ms", &self.timeout_ms)
.finish()
}
}