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
17#[doc(hidden)]
18pub struct UseMemoImpl<T, D> {
19    memoized_value: Option<T>,
20    deps: Option<D>,
21}
22
23impl<T, D> Default for UseMemoImpl<T, D> {
24    fn default() -> Self {
25        Self {
26            memoized_value: None,
27            deps: None,
28        }
29    }
30}
31
32impl<T: Unpin, D: Unpin> Hook for UseMemoImpl<T, D> {}
33
34impl UseMemo for Hooks<'_, '_> {
35    fn use_memo<F, D, T>(&mut self, f: F, deps: D) -> T
36    where
37        F: FnOnce() -> T,
38        D: PartialEq + Unpin + 'static,
39        T: Clone + Unpin + 'static,
40    {
41        let hook = self.use_hook(UseMemoImpl::<T, D>::default);
42        if hook.deps.as_ref() != Some(&deps) || hook.memoized_value.is_none() {
43            hook.memoized_value = Some(f());
44            hook.deps = Some(deps);
45        }
46        hook.memoized_value.clone().expect("memoized value is set")
47    }
48}