use super::infrastructure::time::Time;
use core::{future::Future, pin::Pin, task::Poll};
pub trait Clock {
fn now(&self) -> Time;
}
pub trait Timer {
fn delay(&mut self, duration: core::time::Duration) -> impl Future<Output = ()> + Send;
}
pub trait Spawner {
fn spawn(&self, f: impl Future<Output = ()> + Send + 'static);
}
pub trait DdsRuntime: Send + 'static {
type ClockHandle: Clock + Clone + Send + Sync + 'static;
type TimerHandle: Timer + Clone + Send + Sync + 'static;
type SpawnerHandle: Spawner + Clone + Send + Sync + 'static;
fn timer(&self) -> Self::TimerHandle;
fn clock(&self) -> Self::ClockHandle;
fn spawner(&self) -> Self::SpawnerHandle;
}
pub(crate) enum Either<A, B> {
A(A),
B(B),
}
struct Select<A, B> {
a: A,
b: B,
}
pub(crate) async fn select_future<A: Future, B: Future>(
a: A,
b: B,
) -> Either<A::Output, B::Output> {
Select {
a: core::pin::pin!(a),
b: core::pin::pin!(b),
}
.await
}
impl<A, B> Future for Select<A, B>
where
A: Future + Unpin,
B: Future + Unpin,
{
type Output = Either<A::Output, B::Output>;
fn poll(
mut self: Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<Self::Output> {
if let Poll::Ready(a) = Pin::new(&mut self.a).poll(cx) {
return Poll::Ready(Either::A(a));
}
if let Poll::Ready(b) = Pin::new(&mut self.b).poll(cx) {
return Poll::Ready(Either::B(b));
}
Poll::Pending
}
}