codify "platform" into resolution logic, server-fn/fullstack overhaul (#4596)
overhaul dioxus fullstack using a new implementation of server_fn This PR is a complete rewrite of dioxus fullstack designed to improve compatibility with axum and to fix a number of compilation errors based on feature flag unification plumbing through macros.
This commit is contained in:
1 parent
8421c3aef0
commit
f2b1c6d97f
424 files changed
+17284
-6624
No files matched your search
@@ -1,12 +1,18 @@
|
||||
use std::fmt::{Debug, Display};
|
||||
use std::{
|
||||
fmt::{Debug, Display},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use crate::innerlude::*;
|
||||
|
||||
/// An error that can occur while rendering a component
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum RenderError {
|
||||
/// The render function returned early
|
||||
Aborted(CapturedError),
|
||||
/// The render function returned early due to an error.
|
||||
///
|
||||
/// We captured the error, wrapped it in an Arc, and stored it here. You can no longer modify the error,
|
||||
/// but you can cheaply pass it around.
|
||||
Error(CapturedError),
|
||||
|
||||
/// The component was suspended
|
||||
Suspended(SuspendedFuture),
|
||||
@@ -26,27 +32,103 @@ impl Default for RenderError {
|
||||
}
|
||||
}
|
||||
impl std::error::Error for RenderAbortedEarly {}
|
||||
Self::Aborted(RenderAbortedEarly.into())
|
||||
Self::Error(CapturedError(Arc::new(RenderAbortedEarly.into())))
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for RenderError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Aborted(e) => write!(f, "Render aborted: {e}"),
|
||||
Self::Error(e) => write!(f, "Render aborted: {e}"),
|
||||
Self::Suspended(e) => write!(f, "Component suspended: {e:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: std::error::Error + 'static> From<E> for RenderError {
|
||||
fn from(e: E) -> Self {
|
||||
Self::Aborted(CapturedError::from(e))
|
||||
impl From<CapturedError> for RenderError {
|
||||
fn from(e: CapturedError) -> Self {
|
||||
Self::Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CapturedError> for RenderError {
|
||||
fn from(e: CapturedError) -> Self {
|
||||
RenderError::Aborted(e)
|
||||
impl<E: Into<Error>> From<E> for RenderError {
|
||||
fn from(e: E) -> Self {
|
||||
let anyhow_err = e.into();
|
||||
|
||||
if let Some(suspended) = anyhow_err.downcast_ref::<SuspendedFuture>() {
|
||||
return Self::Suspended(suspended.clone());
|
||||
}
|
||||
|
||||
if let Some(render_error) = anyhow_err.downcast_ref::<RenderError>() {
|
||||
return render_error.clone();
|
||||
}
|
||||
|
||||
Self::Error(CapturedError(Arc::new(anyhow_err)))
|
||||
}
|
||||
}
|
||||
|
||||
/// An `anyhow::Error` wrapped in an `Arc` so it can be cheaply cloned and passed around.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CapturedError(pub Arc<Error>);
|
||||
|
||||
impl CapturedError {
|
||||
/// Create a `CapturedError` from anything that implements `Display`.
|
||||
pub fn from_display(t: impl Display) -> Self {
|
||||
Self(Arc::new(anyhow::anyhow!(t.to_string())))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl serde::Serialize for CapturedError {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.0.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl<'de> serde::Deserialize<'de> for CapturedError {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
Ok(Self::from_display(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for CapturedError {
|
||||
type Target = Error;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Into<Error>> From<E> for CapturedError {
|
||||
fn from(e: E) -> Self {
|
||||
Self(Arc::new(e.into()))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for CapturedError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for CapturedError {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
Arc::ptr_eq(&self.0, &other.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assert_errs_can_downcast() {
|
||||
fn assert_is_stderr_like<T: Send + Sync + Display + Debug>() {}
|
||||
|
||||
assert_is_stderr_like::<RenderError>();
|
||||
assert_is_stderr_like::<CapturedError>();
|
||||
}
|
||||
Reference in new issue
Block a user