Skip to main content

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}