hooks/state_with_updater/update_state/
set.rs1#[cfg(feature = "use_shared_set")]
2pub use shared::*;
3
4#[cfg(feature = "use_gen_set")]
5pub use gen::*;
6
7use super::UpdateState;
8
9#[derive(Debug)]
10pub struct Set<T> {
11 pub new_value: Option<T>,
12}
13
14impl<S> Set<S> {
15 pub fn set(&mut self, new_value: S) {
16 self.new_value = Some(new_value)
17 }
18}
19
20impl<T> Default for Set<T> {
21 fn default() -> Self {
22 Self { new_value: None }
23 }
24}
25
26impl<T> UpdateState<T> for Set<T> {
27 fn update_state(&mut self, state: &mut T) -> bool {
28 if let Some(this) = self.new_value.take() {
29 *state = this;
30 true
31 } else {
32 false
33 }
34 }
35}
36
37#[cfg(feature = "use_shared_set")]
38mod shared {
39 use super::{
40 super::{
41 use_shared_update_state, use_shared_update_state_with, SharedUpdateState,
42 UseSharedUpdateState, UseSharedUpdateStateWith,
43 },
44 Set,
45 };
46
47 pub type SharedSet<S> = SharedUpdateState<Set<S>>;
48
49 impl<S> SharedSet<S> {
50 pub fn set(&self, new_value: S) {
51 self.map_mut_update_state(|v| v.set(new_value))
52 }
53 }
54
55 pub type UseSharedSet<S> = UseSharedUpdateState<S, Set<S>>;
56 pub fn use_shared_set<S>(initial_state: S) -> UseSharedSet<S> {
57 use_shared_update_state(initial_state, Set::default())
58 }
59
60 pub type UseSharedSetWith<S, F> = UseSharedUpdateStateWith<S, Set<S>, F>;
61 pub fn use_shared_set_with<S>(
62 get_initial_state: impl FnOnce() -> S,
63 ) -> UseSharedSetWith<S, impl FnOnce() -> (S, SharedSet<S>)> {
64 use_shared_update_state_with(move || (get_initial_state(), Set::default()))
65 }
66
67 #[cfg(test)]
68 mod tests {
69 use crate::{Hook, HookPollNextUpdateExt, IntoHook};
70
71 #[test]
72 fn set() {
73 futures_lite::future::block_on(async {
74 let hook = super::use_shared_set(1).into_hook();
75 futures_lite::pin!(hook);
76
77 assert!(!std::future::poll_fn(|cx| hook.poll_next_update(cx)).await);
78
79 let (state, updater) = hook.as_mut().use_hook();
80 assert_eq!(*state, 1);
81 updater.set(2);
82 assert_eq!(*state, 1);
83
84 assert!(std::future::poll_fn(|cx| hook.poll_next_update(cx)).await);
85 let (state, _updater) = hook.as_mut().use_hook();
86 assert_eq!(*state, 2);
87
88 assert!(!std::future::poll_fn(|cx| hook.poll_next_update(cx)).await);
89 });
90 }
91
92 #[cfg(feature = "futures-core")]
93 #[cfg(feature = "use_effect")]
94 #[test]
95 fn hook_fn_state_2() {
96 use futures_lite::StreamExt;
97 use hooks_core::{hook_fn, IntoHook};
98
99 use crate::{use_shared_set, use_shared_set_with};
100
101 hook_fn!(
102 fn use_state_2() -> (i32, i32) {
103 let (state_1, updater_1) = h!(use_shared_set(1));
104 let (state_2, updater_2) = h!(use_shared_set_with(|| *state_1 + 1));
105
106 let ret = (*state_1, *state_2);
107
108 let updater_1 = updater_1.clone();
109 let updater_2 = updater_2.clone();
110 h![crate::use_effect(
111 move |(v1, v2): &_| {
112 if *v2 > 10 {
113 return;
114 }
115 updater_1.set(*v2);
116 updater_2.set(*v1 + *v2);
117 },
118 ret,
119 )];
120
121 ret
122 }
123 );
124
125 futures_lite::future::block_on(async {
126 let values = use_state_2().into_hook_values().collect::<Vec<_>>().await;
127
128 assert_eq!(values, [(1, 2), (2, 3), (3, 5), (5, 8), (8, 13)]);
129 });
130 }
131
132 #[cfg(feature = "futures-core")]
133 #[cfg(feature = "use_effect")]
134 #[cfg(feature = "proc-macro")]
135 #[test]
136 fn state_2() {
137 use futures_lite::StreamExt;
138 use hooks_core::IntoHook;
139 use hooks_macro::hook;
140
141 use super::{use_shared_set, use_shared_set_with};
142
143 #[hook(hooks_core_path = "::hooks_core")]
144 fn use_state_2() -> (i32, i32) {
145 let (state_1, updater_1) = use_shared_set(1);
146 let (state_2, updater_2) = use_shared_set_with(|| *state_1 + 1);
147
148 let ret = (*state_1, *state_2);
149
150 let updater_1 = updater_1.clone();
151 let updater_2 = updater_2.clone();
152 crate::use_effect(
153 move |(v1, v2): &_| {
154 if *v2 > 10 {
155 return;
156 }
157 updater_1.set(*v2);
158 updater_2.set(*v1 + *v2);
159 },
160 ret,
161 );
162
163 ret
164 }
165
166 futures_lite::future::block_on(async {
167 let values = use_state_2().into_hook_values().collect::<Vec<_>>().await;
168
169 assert_eq!(values, [(1, 2), (2, 3), (3, 5), (5, 8), (8, 13)]);
170 });
171 }
172 }
173}
174
175#[cfg(feature = "use_gen_set")]
176mod gen {
177 use super::{
178 super::{
179 use_gen_update_state, use_gen_update_state_with, GenUpdateStateKey,
180 GenUpdateStateOwner, UseGenUpdateState, UseGenUpdateStateWith,
181 },
182 Set,
183 };
184
185 pub type GenSetOwner<S> = GenUpdateStateOwner<Set<S>>;
186 pub type GenSetKey<S> = GenUpdateStateKey<Set<S>>;
187
188 impl<S> GenSetKey<S> {
189 pub fn set(&self, new_value: S) {
190 self.map_mut_update_state(|v| v.set(new_value))
191 }
192 }
193
194 pub type UseGenSet<S> = UseGenUpdateState<S, Set<S>>;
195 pub fn use_gen_set<S>(initial_state: S) -> UseGenSet<S> {
196 use_gen_update_state(initial_state, Set::default())
197 }
198
199 pub type UseGenSetWith<F> = UseGenUpdateStateWith<F>;
200 pub fn use_gen_set_with<S>(
201 get_initial_state: impl FnOnce() -> S,
202 ) -> UseGenSetWith<impl FnOnce() -> (S, Set<S>)> {
203 use_gen_update_state_with(move || (get_initial_state(), Set::default()))
204 }
205
206 #[cfg(test)]
207 mod tests {
208 use crate::{utils::testing::assert_always_pending, Hook, HookPollNextUpdateExt, IntoHook};
209
210 #[test]
211 fn set() {
212 futures_lite::future::block_on(async {
213 let hook = super::use_gen_set(1).into_hook();
214 futures_lite::pin!(hook);
215
216 assert_always_pending(|| std::future::poll_fn(|cx| hook.poll_next_update(cx)));
217
218 let (state, updater) = hook.as_mut().use_hook();
219 assert_eq!(*state, 1);
220 updater.set(2);
221 assert_eq!(*state, 1);
222
223 assert!(std::future::poll_fn(|cx| hook.poll_next_update(cx)).await);
224 let (state, _updater) = hook.as_mut().use_hook();
225 assert_eq!(*state, 2);
226
227 assert_always_pending(|| std::future::poll_fn(|cx| hook.poll_next_update(cx)));
228 });
229 }
230
231 #[cfg(feature = "futures-core")]
232 #[cfg(feature = "use_effect")]
233 #[test]
234 fn hook_fn_state_2() {
235 use futures_lite::StreamExt;
236 use hooks_core::{hook_fn, IntoHook};
237
238 use super::{use_gen_set, use_gen_set_with};
239
240 hook_fn!(
241 fn use_state_2() -> (i32, i32) {
242 let (state_1, updater_1) = h!(use_gen_set(1));
243 let (state_2, updater_2) = h!(use_gen_set_with(|| *state_1 + 1));
244
245 let ret = (*state_1, *state_2);
246
247 h![crate::use_effect(
248 move |(v1, v2): &_| {
249 if *v2 > 10 {
250 return;
251 }
252 updater_1.set(*v2);
253 updater_2.set(*v1 + *v2);
254 },
255 ret,
256 )];
257
258 ret
259 }
260 );
261
262 futures_lite::future::block_on(async {
263 let mut hook_values = use_state_2().into_hook_values();
264 let values = (&mut hook_values).take(5).collect::<Vec<_>>().await;
265
266 assert_eq!(values, [(1, 2), (2, 3), (3, 5), (5, 8), (8, 13)]);
267
268 assert_always_pending(|| hook_values.next())
269 });
270 }
271
272 #[cfg(feature = "futures-core")]
273 #[cfg(feature = "use_effect")]
274 #[cfg(feature = "proc-macro")]
275 #[test]
276 fn state_2() {
277 use futures_lite::StreamExt;
278 use hooks_core::IntoHook;
279 use hooks_macro::hook;
280
281 use super::{use_gen_set, use_gen_set_with};
282
283 #[hook(hooks_core_path = "::hooks_core")]
284 fn use_state_2() -> (i32, i32) {
285 let (state_1, updater_1) = use_gen_set(1);
286 let (state_2, updater_2) = use_gen_set_with(|| *state_1 + 1);
287
288 let ret = (*state_1, *state_2);
289
290 crate::use_effect(
291 move |(v1, v2): &_| {
292 if *v2 > 10 {
293 return;
294 }
295 updater_1.set(*v2);
296 updater_2.set(*v1 + *v2);
297 },
298 ret,
299 );
300
301 ret
302 }
303
304 futures_lite::future::block_on(async {
305 let mut hook_values = use_state_2().into_hook_values();
306 let values = (&mut hook_values).take(5).collect::<Vec<_>>().await;
307
308 assert_eq!(values, [(1, 2), (2, 3), (3, 5), (5, 8), (8, 13)]);
309
310 assert_always_pending(|| hook_values.next())
311 });
312 }
313 }
314}