Skip to main content

ratatui_kit/hooks/
use_memo.rs

1use crate::{Hook, Hooks};
2
3mod private {
4    pub trait Sealed {}
5    impl Sealed for crate::Hooks<'_, '_> {}
6}
7
8pub trait UseMemo: private::Sealed {
9    // 依赖缓存,只有依赖变化时才重新计算,适合性能优化。
10    fn use_memo<F, D, T>(&mut self, f: F, deps: D) -> T
11    where
12        F: FnOnce() -> T,
13        D: PartialEq + Unpin + 'static,
14        T: Clone + Unpin + 'static;
15}
16
17pub struct UseMemoImpl<T, D> {
18    memoized_value: Option<T>,
19    deps: Option<D>,
20}
21
22impl<T, D> Default for UseMemoImpl<T, D> {
23    fn default() -> Self {
24        Self {
25            memoized_value: None,
26            deps: None,
27        }
28    }
29}
30
31impl<T: Unpin, D: Unpin> Hook for UseMemoImpl<T, D> {}
32
33impl UseMemo for Hooks<'_, '_> {
34    fn use_memo<F, D, T>(&mut self, f: F, deps: D) -> T
35    where
36        F: FnOnce() -> T,
37        D: PartialEq + Unpin + 'static,
38        T: Clone + Unpin + 'static,
39    {
40        let hook = self.use_hook(UseMemoImpl::<T, D>::default);
41        if hook.deps.as_ref() != Some(&deps) || hook.memoized_value.is_none() {
42            hook.memoized_value = Some(f());
43            hook.deps = Some(deps);
44        }
45        hook.memoized_value.clone().expect("memoized value is set")
46    }
47}