more fullstack cleanups: loaders serialize, ServeConfig only (#4785)
* some opinionated cleanups in dioxus-server * add serialize to loader * add `result` to Resource * clippy * fix * writable memos, resources, `onmount`, `.pending`, and `.value()` on actions * fix compile issues * fix typo
This commit is contained in:
1 parent
a3e40a5ea2
commit
7102bc3b6a
33 files changed
+2085
-672
No files matched your search
@@ -3,7 +3,7 @@ use dioxus_core::{use_hook, Callback, CapturedError, Result, Task};
|
||||
use dioxus_signals::{ReadSignal, ReadableBoxExt, ReadableExt, Signal, WritableExt};
|
||||
use futures_channel::oneshot::Receiver;
|
||||
use futures_util::{future::Shared, FutureExt};
|
||||
use std::{marker::PhantomData, prelude::rust_2024::Future};
|
||||
use std::{marker::PhantomData, pin::Pin, prelude::rust_2024::Future, task::Poll};
|
||||
|
||||
pub fn use_action<E, C, M>(mut user_fn: C) -> Action<C::Input, C::Output>
|
||||
where
|
||||
@@ -82,15 +82,7 @@ pub struct Action<I, T: 'static> {
|
||||
}
|
||||
|
||||
impl<I: 'static, O: 'static> Action<I, O> {
|
||||
pub fn value(&self) -> Option<ReadSignal<O>> {
|
||||
if self.value.read().is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(self.reader)
|
||||
}
|
||||
|
||||
pub fn result(&self) -> Option<Result<ReadSignal<O>, CapturedError>> {
|
||||
pub fn value(&self) -> Option<Result<ReadSignal<O>, CapturedError>> {
|
||||
if !matches!(
|
||||
*self.state.read(),
|
||||
ActionState::Ready | ActionState::Errored
|
||||
@@ -109,7 +101,7 @@ impl<I: 'static, O: 'static> Action<I, O> {
|
||||
Some(Ok(self.reader))
|
||||
}
|
||||
|
||||
pub fn is_pending(&self) -> bool {
|
||||
pub fn pending(&self) -> bool {
|
||||
*self.state.read() == ActionState::Pending
|
||||
}
|
||||
|
||||
@@ -162,13 +154,10 @@ impl<T> Dispatching<T> {
|
||||
impl<T> std::future::Future for Dispatching<T> {
|
||||
type Output = ();
|
||||
|
||||
fn poll(
|
||||
mut self: std::pin::Pin<&mut Self>,
|
||||
_cx: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<Self::Output> {
|
||||
fn poll(mut self: Pin<&mut Self>, _cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
|
||||
match self.receiver.poll_unpin(_cx) {
|
||||
std::task::Poll::Ready(_) => std::task::Poll::Ready(()),
|
||||
std::task::Poll::Pending => std::task::Poll::Pending,
|
||||
Poll::Ready(_) => Poll::Ready(()),
|
||||
Poll::Pending => Poll::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -281,6 +270,7 @@ impl<A: 'static, B: 'static, O> Action<(A, B), O> {
|
||||
Dispatching::new((self.callback).call((_a, _b)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: 'static, B: 'static, C: 'static, O> Action<(A, B, C), O> {
|
||||
pub fn call(&mut self, _a: A, _b: B, _c: C) -> Dispatching<()> {
|
||||
Dispatching::new((self.callback).call((_a, _b, _c)))
|
||||
|
||||
@@ -11,8 +11,8 @@ use futures_util::{
|
||||
future::{self},
|
||||
pin_mut, FutureExt, StreamExt,
|
||||
};
|
||||
use std::ops::Deref;
|
||||
use std::{cell::Cell, future::Future, rc::Rc};
|
||||
use std::{fmt::Debug, ops::Deref};
|
||||
|
||||
#[doc = include_str!("../docs/use_resource.md")]
|
||||
#[doc = include_str!("../docs/rules_of_hooks.md")]
|
||||
@@ -324,6 +324,11 @@ impl<T> Resource<T> {
|
||||
self.task.cloned()
|
||||
}
|
||||
|
||||
/// Is the resource's future currently running?
|
||||
pub fn pending(&self) -> bool {
|
||||
matches!(*self.state.peek(), UseResourceState::Pending)
|
||||
}
|
||||
|
||||
/// Is the resource's future currently finished running?
|
||||
///
|
||||
/// Reading this does not subscribe to the future's state
|
||||
@@ -439,6 +444,35 @@ impl<T> Resource<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> Resource<Result<T, E>> {
|
||||
/// Convert the `Resource<Result<T, E>>` into an `Option<Result<MappedSignal<T>, MappedSignal<E>>>`
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn result(
|
||||
&self,
|
||||
) -> Option<
|
||||
Result<
|
||||
MappedSignal<T, Signal<Option<Result<T, E>>>>,
|
||||
MappedSignal<E, Signal<Option<Result<T, E>>>>,
|
||||
>,
|
||||
> {
|
||||
let value: MappedSignal<T, Signal<Option<Result<T, E>>>> = self.value.map(|v| match v {
|
||||
Some(Ok(ref res)) => res,
|
||||
_ => panic!("Resource is not ready"),
|
||||
});
|
||||
|
||||
let error: MappedSignal<E, Signal<Option<Result<T, E>>>> = self.value.map(|v| match v {
|
||||
Some(Err(ref err)) => err,
|
||||
_ => panic!("Resource is not ready"),
|
||||
});
|
||||
|
||||
match &*self.value.peek() {
|
||||
Some(Ok(_)) => Some(Ok(value)),
|
||||
Some(Err(_)) => Some(Err(error)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Resource<T>> for ReadSignal<Option<T>> {
|
||||
fn from(val: Resource<T>) -> Self {
|
||||
val.value.into()
|
||||
@@ -468,6 +502,19 @@ impl<T> Readable for Resource<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Writable for Resource<T> {
|
||||
type WriteMetadata = <Signal<Option<T>> as Writable>::WriteMetadata;
|
||||
|
||||
fn try_write_unchecked(
|
||||
&self,
|
||||
) -> Result<WritableRef<'static, Self>, generational_box::BorrowMutError>
|
||||
where
|
||||
Self::Target: 'static,
|
||||
{
|
||||
self.value.try_write_unchecked()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoAttributeValue for Resource<T>
|
||||
where
|
||||
T: Clone + IntoAttributeValue,
|
||||
|
||||
Reference in new issue
Block a user