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 Rc::clone(&t.1)
19 }
20 _ => {
21 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}