Skip to main content

ratatui_kit/hooks/
use_future.rs

1use std::task::Poll;
2
3use futures::{FutureExt, future::LocalBoxFuture};
4
5use super::{Hook, Hooks};
6
7mod private {
8    pub trait Sealed {}
9
10    impl Sealed for crate::hooks::Hooks<'_, '_> {}
11}
12
13pub trait UseFuture: private::Sealed {
14    // 注册异步副作用任务,适合定时器、网络请求、异步轮询等场景。
15    fn use_future<F>(&mut self, f: F)
16    where
17        F: Future<Output = ()> + 'static;
18}
19
20#[doc(hidden)]
21pub struct UseFutureImpl {
22    f: Option<LocalBoxFuture<'static, ()>>,
23}
24
25impl UseFutureImpl {
26    pub fn new<F>(f: F) -> Self
27    where
28        F: Future<Output = ()> + 'static,
29    {
30        UseFutureImpl {
31            f: Some(f.boxed_local()),
32        }
33    }
34}
35
36impl Hook for UseFutureImpl {
37    fn poll_change(&mut self, cx: &mut std::task::Context) -> std::task::Poll<()> {
38        if let Some(future) = self.f.as_mut()
39            && future.as_mut().poll(cx).is_ready()
40        {
41            self.f = None; // 清除已完成的 future
42            return Poll::Ready(());
43        }
44        Poll::Pending
45    }
46}
47
48impl UseFuture for Hooks<'_, '_> {
49    fn use_future<F>(&mut self, f: F)
50    where
51        F: Future<Output = ()> + 'static,
52    {
53        self.use_hook(move || UseFutureImpl::new(f));
54    }
55}