flams_web_utils/components/
await.rs1use std::future::Future;
2
3use crate::components::{display_error, Spinner};
4use flams_utils::parking_lot;
5use leptos::{
6 either::{Either, EitherOf3},
7 prelude::*,
8};
9
10pub fn wait_local<
11 Out: 'static + Send + Sync + Clone,
12 Fut: Future<Output = Option<Out>> + 'static + Send,
13 F: Fn() -> Fut + 'static,
14>(
15 future: F,
16 children: impl Fn(Out) -> AnyView + 'static + Send,
17 err: String,
18) -> AnyView {
19 let res = LocalResource::new(future);
20 view! {
21 <Suspense fallback = || view!(<Spinner/>)>{move || {
22 res.get().and_then(|mut r| r.take()).map_or_else(
23 || view!(<div>{err.clone()}</div>).into_any(),
24 |res| children(res)
25 )
26 }}</Suspense>
27 }
28 .into_any()
29}
30
31pub fn wait_and_then<E, Fut, F, T>(f: F, r: impl FnOnce(T) -> AnyView + Send + 'static) -> AnyView
32where
33 Fut: Future<Output = Result<T, ServerFnError<E>>> + Send + 'static,
34 F: Fn() -> Fut + Send + Sync + 'static,
35 T: Send + Sync + Clone + 'static + serde::Serialize + for<'de> serde::Deserialize<'de>,
36 E: std::fmt::Display
37 + Clone
38 + serde::Serialize
39 + for<'de> serde::Deserialize<'de>
40 + Send
41 + Sync
42 + 'static,
43{
44 let r = std::sync::Arc::new(parking_lot::Mutex::new(Some(r)));
45 let res = Resource::new(|| (), move |()| f());
46 view! {
47 <Suspense fallback = || view!(<Spinner/>)>{move ||
48 match res.get() {
49 Some(Ok(t)) =>
50 r.lock().take().map(|r| r(t)).into_any(),
51 Some(Err(e)) => display_error(e.to_string().into()),
52 None => view!(<Spinner/>).into_any(),
53 }
54 }</Suspense>
55 }
56 .into_any()
57}
58
59pub fn wait_and_then_fn<E, Fut, F, T>(f: F, r: impl Fn(T) -> AnyView + Send + 'static) -> AnyView
60where
61 Fut: Future<Output = Result<T, E>> + Send + 'static,
62 F: Fn() -> Fut + 'static + Send + Sync,
63 T: Send + Sync + Clone + 'static + serde::Serialize + for<'de> serde::Deserialize<'de>,
64 E: std::fmt::Display
65 + Clone
66 + serde::Serialize
67 + for<'de> serde::Deserialize<'de>
68 + Send
69 + Sync
70 + FromServerFnError
71 + 'static,
72{
73 let res = Resource::new(|| (), move |()| f());
74 view! {
75 <Suspense fallback = || view!(<Spinner/>)>{move ||
76 match res.get() {
77 Some(Ok(t)) =>
78 r(t),
79 Some(Err(e)) => display_error(e.to_string().into()),
80 None => view!(<Spinner/>).into_any(),
81 }
82 }</Suspense>
83 }
84 .into_any()
85}