use executor_core::{LocalExecutor, Task};
use nami_core::watcher::Context;
use crate::{Container, CustomBinding, Signal};
#[derive(Debug, Clone)]
pub struct FutureSignal<T: 'static + Clone> {
container: Container<Option<T>>,
}
impl<T> FutureSignal<T>
where
T: Clone + 'static,
{
#[cfg(feature = "std")]
pub fn new<Fut>(fut: Fut) -> Self
where
Fut: core::future::Future<Output = T> + 'static,
{
Self::with_executor(executor_core::DefaultExecutor, fut)
}
pub fn with_executor<E, Fut>(executor: E, fut: Fut) -> Self
where
E: LocalExecutor,
Fut: Future<Output = T> + 'static,
{
let container = Container::default();
{
let container = container.clone();
executor
.spawn_local(async move {
let value = fut.await;
container.set(Some(value));
})
.detach();
}
Self { container }
}
}
impl<T> Signal for FutureSignal<T>
where
T: Clone + 'static,
{
type Output = Option<T>;
type Guard = <Container<Option<T>> as Signal>::Guard;
fn get(&self) -> Self::Output {
self.container.get()
}
fn watch(&self, watcher: impl Fn(Context<Self::Output>) + 'static) -> Self::Guard {
self.container.watch(watcher)
}
}