euv_ui/hook/use_async/struct.rs
1use super::*;
2
3/// `use_async`'s reactive handle, stored in the hook context slot and
4/// returned to the user on each render.
5///
6/// The handle exposes three fields:
7///
8/// - `state` - the current `AsyncState<T, L>` (matches what the user
9/// should `match` on in `html!`).
10/// - `refetch` - triggers the future to run again, regardless of
11/// whether the previous attempt completed or is still in flight.
12/// - `cancel` - drops the in-flight future (if any) and prevents its
13/// `Ok`/`Err` branches from mutating the state. Subsequent renders
14/// will still call the future again on the next mount.
15///
16/// Cloning a handle is cheap — `UseAsyncHandle` is `Copy` if its
17/// generic parameters are. Use it from event handlers the same way
18/// you'd use a `Signal<T>`.
19#[derive(Clone, Data)]
20pub struct UseAsyncHandle<T, L>
21where
22 T: Clone + PartialEq + 'static,
23 L: Clone + PartialEq + HasLoadingHint + 'static,
24{
25 /// Address of the heap-allocated `UseAsyncInner<T, L>` state.
26 ///
27 /// `get_inner()` is only called by `impl.rs` (slot lookup
28 /// and the opaque `Debug` rendering), so the three
29 /// generated accessors are all `pub(crate)`.
30 #[get(type(copy), pub(crate))]
31 #[get_mut(pub(crate))]
32 #[set(pub(crate))]
33 pub(crate) inner: usize,
34 /// `Copy` marker so `UseAsyncHandle` itself is `Copy`.
35 ///
36 /// No accessor of this zero-sized marker is called, so all
37 /// three are skipped rather than left as dead `pub`
38 /// surface over a `pub(crate)` field.
39 #[get(skip)]
40 #[get_mut(skip)]
41 #[set(skip)]
42 pub(crate) _marker: core::marker::PhantomData<fn() -> (T, L)>,
43}
44
45/// Blanket `Copy` for any generic instance — both fields are
46/// themselves `Copy` (`usize`, `PhantomData<fn pointer>`).
47/// The `where` clause must be repeated because a separate impl
48/// block cannot inherit bounds from the type declaration.
49impl<T, L> core::marker::Copy for UseAsyncHandle<T, L>
50where
51 T: Clone + PartialEq + 'static,
52 L: Clone + PartialEq + HasLoadingHint + 'static,
53{
54}
55
56/// Heap-allocated state backing a [`super::UseAsyncHandle`].
57///
58/// Reachable only through the raw address stored in the handle.
59/// Allocated by [`super::UseAsyncHandle::new_for_fallback`] for the
60/// "no hook context" case and by [`use_async`](crate::use_async) when
61/// the hook is registered for the first time.
62#[derive(Clone, Data)]
63pub(crate) struct UseAsyncSlot<T, L>
64where
65 T: Clone + PartialEq + 'static,
66 L: Clone + PartialEq + HasLoadingHint + 'static,
67{
68 /// Reactive state, exposed to the user as
69 /// [`UseAsyncHandle::state`].
70 pub(crate) state: Signal<AsyncState<T, L>>,
71 /// Cancellation flag — flipped on drop. The in-flight future
72 /// reads this before writing back to `state`.
73 pub(crate) cancel: Rc<Cell<bool>>,
74}