Skip to content

Commit

Permalink
Change NoCustomError to be an empty enum
Browse files Browse the repository at this point in the history
Contrary to an empty struct, which has exactly 1 possible value, an
empty enum has 0 possible values: it can't even be constructed.

Fixes #3154
  • Loading branch information
nicolas-guichard committed Nov 17, 2024
1 parent 7f2237b commit 3d4b681
Showing 1 changed file with 35 additions and 16 deletions.
51 changes: 35 additions & 16 deletions server_fn/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,50 @@ impl From<ServerFnError> for Error {
Clone,
Copy,
)]
#[cfg_attr(
feature = "rkyv",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
pub struct NoCustomError;
pub enum NoCustomError {}

#[cfg(feature = "rkyv")]
impl rkyv::Archive for NoCustomError {
const COPY_OPTIMIZATION: rkyv::traits::CopyOptimization<Self> =
rkyv::traits::CopyOptimization::disable();
type Archived = ();
type Resolver = ();
fn resolve(&self, _: Self::Resolver, _: rkyv::Place<Self::Archived>) {
match *self {}
}
}

#[cfg(feature = "rkyv")]
impl<T, D: rkyv::rancor::Fallible + ?Sized> rkyv::Deserialize<T, D>
for NoCustomError
{
fn deserialize(&self, _: &mut D) -> Result<T, D::Error> {
match *self {}
}
}

#[cfg(feature = "rkyv")]
impl<S: rkyv::rancor::Fallible + ?Sized> rkyv::Serialize<S> for NoCustomError {
fn serialize(
&self,
_: &mut S,
) -> Result<Self::Resolver, <S as rkyv::rancor::Fallible>::Error> {
match *self {}
}
}

// Implement `Display` for `NoCustomError`
impl fmt::Display for NoCustomError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Unit Type Displayed")
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
match *self {}
}
}

impl FromStr for NoCustomError {
type Err = ();

fn from_str(_s: &str) -> Result<Self, Self::Err> {
Ok(NoCustomError)
fn from_str(_: &str) -> Result<Self, Self::Err> {
Err(())
}
}

Expand Down Expand Up @@ -94,13 +120,6 @@ pub(crate) trait ServerFnErrorKind {}

impl ServerFnErrorKind for ServerFnError {}

// This impl should catch passing () or nothing to server_fn_error
impl ViaError<NoCustomError> for &&&WrapError<()> {
fn to_server_error(&self) -> ServerFnError {
ServerFnError::WrappedServerError(NoCustomError)
}
}

// This impl will catch any type that implements any type that impls
// Error and Clone, so that it can be wrapped into ServerFnError
impl<E: std::error::Error + Clone> ViaError<E> for &&WrapError<E> {
Expand Down

0 comments on commit 3d4b681

Please sign in to comment.