ratatui_kit/hooks/
use_future.rs

1use std::task::Poll;
2
3use futures::future::BoxFuture;
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 = ()> + Send + 'static;
18}
19
20pub struct UseFutureImpl {
21    f: Option<BoxFuture<'static, ()>>,
22}
23
24impl UseFutureImpl {
25    pub fn new<F>(f: F) -> Self
26    where
27        F: Future<Output = ()> + Send + 'static,
28    {
29        UseFutureImpl {
30            f: Some(Box::pin(f)),
31        }
32    }
33}
34
35impl Hook for UseFutureImpl {
36    fn poll_change(
37        mut self: std::pin::Pin<&mut Self>,
38        cx: &mut std::task::Context,
39    ) -> std::task::Poll<()> {
40        if let Some(future) = self.f.as_mut() {
41            if future.as_mut().poll(cx).is_ready() {
42                self.f = None; // 清除已完成的 future
43            }
44        }
45        Poll::Pending
46    }
47}
48
49impl UseFuture for Hooks<'_, '_> {
50    fn use_future<F>(&mut self, f: F)
51    where
52        F: Future<Output = ()> + Send + 'static,
53    {
54        self.use_hook(move || UseFutureImpl::new(f));
55    }
56}