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