1use std::{
2 any::Any,
3 hash::{
4 Hash,
5 Hasher,
6 },
7 rc::Rc,
8};
9
10use rustc_hash::FxHasher;
11
12use crate::{
13 diff_key::DiffKey,
14 element::Element,
15};
16
17#[cfg(feature = "test")]
18pub fn from_fn_captured<T: Fn() -> Element + 'static>(comp: T) -> Element {
19 use std::rc::Rc;
20
21 use crate::diff_key::DiffKey;
22
23 Element::Component {
24 key: DiffKey::None,
25 #[cfg(feature = "hotreload")]
26 comp: Rc::new(move |_| crate::hotreload::subsecond::HotFn::current(&comp).call(())),
27 #[cfg(not(feature = "hotreload"))]
28 comp: Rc::new(move |_| comp()),
29 props: Rc::new(()),
30 }
31}
32
33#[cfg(feature = "test")]
34pub fn from_fn_standalone(comp: fn() -> Element) -> Element {
35 Element::Component {
36 key: comp.into(),
37 #[cfg(feature = "hotreload")]
38 comp: Rc::new(move |_| crate::hotreload::subsecond::HotFn::current(comp).call(())),
39 #[cfg(not(feature = "hotreload"))]
40 comp: Rc::new(move |_| comp()),
41 props: Rc::new(()),
42 }
43}
44
45#[cfg(feature = "test")]
46pub fn from_fn_standalone_borrowed<P: 'static + PartialEq>(
47 props: P,
48 comp: fn(&P) -> Element,
49) -> Element {
50 Element::Component {
51 key: comp.into(),
52 #[cfg(feature = "hotreload")]
53 comp: Rc::new(move |props| {
54 let props = (&*props as &dyn Any).downcast_ref::<P>().unwrap();
55 crate::hotreload::subsecond::HotFn::current(comp).call((props,))
56 }),
57 #[cfg(not(feature = "hotreload"))]
58 comp: Rc::new(move |props| {
59 let props = (&*props as &dyn Any).downcast_ref::<P>().unwrap();
60 comp(props)
61 }),
62 props: Rc::new(props),
63 }
64}
65
66pub fn from_fn<P: PartialEq + 'static>(
68 key: impl Hash,
69 props: P,
70 comp: impl Fn(&P) -> Element + Clone + 'static,
71) -> Element {
72 let mut hasher = FxHasher::default();
73 key.hash(&mut hasher);
74 Element::Component {
75 key: DiffKey::U64(hasher.finish()),
76 #[cfg(feature = "hotreload")]
77 comp: Rc::new(move |props| {
78 let props = (&*props as &dyn Any).downcast_ref::<P>().unwrap();
79 crate::hotreload::subsecond::HotFn::current(comp.clone()).call((props,))
80 }),
81 #[cfg(not(feature = "hotreload"))]
82 comp: Rc::new(move |props| {
83 let props = (&*props as &dyn Any).downcast_ref::<P>().unwrap();
84 comp(props)
85 }),
86 props: Rc::new(props),
87 }
88}
89
90pub fn from_fn_owned<P: PartialEq + Clone + 'static>(
92 key: impl Hash,
93 props: P,
94 comp: impl Fn(P) -> Element + Clone + 'static,
95) -> Element {
96 let mut hasher = FxHasher::default();
97 key.hash(&mut hasher);
98 Element::Component {
99 key: DiffKey::U64(hasher.finish()),
100 #[cfg(feature = "hotreload")]
101 comp: Rc::new(move |props| {
102 let props = (&*props as &dyn Any).downcast_ref::<P>().cloned().unwrap();
103 crate::hotreload::subsecond::HotFn::current(comp.clone()).call((props,))
104 }),
105 #[cfg(not(feature = "hotreload"))]
106 comp: Rc::new(move |props| {
107 let props = (&*props as &dyn Any).downcast_ref::<P>().cloned().unwrap();
108 comp(props)
109 }),
110 props: Rc::new(props),
111 }
112}
113
114pub fn from_fn_standalone_borrowed_keyed<K: Hash, P: 'static + PartialEq>(
115 key: K,
116 props: P,
117 comp: fn(&P) -> Element,
118) -> Element {
119 let mut hasher = FxHasher::default();
120 key.hash(&mut hasher);
121 Element::Component {
122 key: DiffKey::U64(hasher.finish()),
123 #[cfg(feature = "hotreload")]
124 comp: Rc::new(move |props| {
125 let props = (&*props as &dyn Any).downcast_ref::<P>().unwrap();
126 crate::hotreload::subsecond::HotFn::current(comp).call((props,))
127 }),
128 #[cfg(not(feature = "hotreload"))]
129 comp: Rc::new(move |props| {
130 let props = (&*props as &dyn Any).downcast_ref::<P>().unwrap();
131 comp(props)
132 }),
133 props: Rc::new(props),
134 }
135}