react/
use_memo.rs

1use std::rc::Rc;
2
3pub fn use_memo_no_dep<T: 'static + ?Sized>(func: fn() -> Rc<T>) -> Rc<T> {
4    let v = crate::use_ref_readonly_with(move || func());
5    v.0
6}
7
8pub fn use_memo_one<D: 'static + PartialEq, T: 'static>(
9    func: fn(&Rc<D>) -> Rc<T>,
10    dep: Rc<D>,
11) -> Rc<T> {
12    let dep_and_value = crate::use_ref_cell::<Option<(Rc<D>, Rc<T>)>>(None);
13    let mut dep_and_value = dep_and_value.0.borrow_mut();
14
15    match &*dep_and_value {
16        Some(t) if &t.0 == &dep => {
17            // dep not changed
18            Rc::clone(&t.1)
19        }
20        _ => {
21            // dep changed
22            let new_v: Rc<T> = func(&dep);
23
24            *dep_and_value = Some((dep, Rc::clone(&new_v)));
25
26            new_v
27        }
28    }
29}
30
31#[macro_export]
32macro_rules! use_memo {
33    (() => $e:expr) => {
34        $crate::use_memo_no_dep(|| $crate::auto_wrap_rc!($e))
35    };
36    (($( $dep:ident $(= $dep_expr:expr)? ),+ $(,)?) => $e:expr ) => {
37        $crate::use_memo_one(
38            |__dep_tuple| {
39                $crate::__impl_let_dep_list_memo!( { *__dep_tuple } $($dep)+ );
40                $e
41            },
42            $crate::auto_wrap_rc!((
43                $($crate::__impl_pass_dep!( $dep $(= $dep_expr)? )),+
44            )),
45        )
46    };
47}