Skip to main content

ratatui_kit/components/adapter/
stateful_widget.rs

1use crate::{Component, Props, State};
2use ratatui::widgets::StatefulWidget;
3
4// 与 `widget.rs` 同理:0.30 起含 `Block` 的 stateful widget(如 `List`)不再 Send + Sync。
5// 此处放宽对被适配 widget `T` 自身的 Send + Sync 要求,改为对适配器及其 props 以
6// `unsafe impl` 断言(见 `widget.rs` 顶部安全说明)。`T::State` 仍要求 Send + Sync,
7// 因 `State<T::State>` 需可存储于框架的(Send)状态体系中;0.30 起 `StatefulWidget::State`
8// 去掉了隐式 `Sized`,故显式补 `Sized`。
9
10pub struct StatefulWidgetAdapterProps<T>
11where
12    T: StatefulWidget + 'static,
13    T::State: Sized + Sync + Send + 'static,
14{
15    pub inner: T,
16    pub state: State<T::State>,
17}
18
19// Safety: 见 `widget.rs` 顶部说明。
20unsafe impl<T> Send for StatefulWidgetAdapterProps<T>
21where
22    T: StatefulWidget + 'static,
23    T::State: Sized + Sync + Send + 'static,
24{
25}
26unsafe impl<T> Sync for StatefulWidgetAdapterProps<T>
27where
28    T: StatefulWidget + 'static,
29    T::State: Sized + Sync + Send + 'static,
30{
31}
32unsafe impl<T> Props for StatefulWidgetAdapterProps<T>
33where
34    T: StatefulWidget + 'static,
35    T::State: Sized + Sync + Send + 'static,
36{
37}
38
39pub struct StatefulWidgetAdapter<T>
40where
41    T: StatefulWidget + 'static,
42    T::State: Sized + Sync + Send + 'static,
43{
44    inner: T,
45    state: State<T::State>,
46}
47
48// Safety: 见 `widget.rs` 顶部说明。
49unsafe impl<T> Send for StatefulWidgetAdapter<T>
50where
51    T: StatefulWidget + 'static,
52    T::State: Sized + Sync + Send + 'static,
53{
54}
55unsafe impl<T> Sync for StatefulWidgetAdapter<T>
56where
57    T: StatefulWidget + 'static,
58    T::State: Sized + Sync + Send + 'static,
59{
60}
61
62impl<T> Component for StatefulWidgetAdapter<T>
63where
64    T: StatefulWidget + 'static + Unpin + Clone,
65    T::State: Sized + Sync + Send + 'static + Unpin,
66{
67    type Props<'a> = StatefulWidgetAdapterProps<T>;
68
69    fn new(props: &Self::Props<'_>) -> Self {
70        Self {
71            inner: props.inner.clone(),
72            state: props.state,
73        }
74    }
75
76    fn update(
77        &mut self,
78        props: &mut Self::Props<'_>,
79        _hooks: crate::Hooks,
80        _updater: &mut crate::ComponentUpdater,
81    ) {
82        self.inner = props.inner.clone();
83        self.state = props.state;
84    }
85
86    fn draw(&mut self, drawer: &mut crate::ComponentDrawer<'_, '_>) {
87        drawer.render_stateful_widget(
88            self.inner.clone(),
89            drawer.area,
90            &mut self.state.write_no_update(),
91        );
92    }
93}