use crate::{
error::BevyError, never::Never, system::entity_command::EntityCommandError,
world::error::EntityMutableFetchError,
};
use core::fmt::{Debug, Display};
#[diagnostic::on_unimplemented(
message = "`{Self}` is not a valid `Command` output type",
label = "invalid `Command` output type",
note = "the output type of a `Command` should be `()`, `Never`, or a `Result` where the error type can be converted into `BevyError`"
)]
pub trait CommandOutput: Sized {
fn to_err(self) -> Option<BevyError>;
}
impl<T, E> CommandOutput for Result<T, E>
where
E: Into<BevyError>,
{
#[inline]
fn to_err(self) -> Option<BevyError> {
self.err().map(Into::into)
}
}
impl CommandOutput for Never {
#[inline]
fn to_err(self) -> Option<BevyError> {
None
}
}
impl CommandOutput for () {
#[inline]
fn to_err(self) -> Option<BevyError> {
None
}
}
pub trait EntityCommandOutput {
type Out;
type Error: Into<BevyError> + From<EntityMutableFetchError>;
fn into_result(self) -> Result<Self::Out, Self::Error>;
}
impl EntityCommandOutput for () {
type Out = ();
type Error = EntityMutableFetchError;
#[inline]
fn into_result(self) -> Result<Self::Out, Self::Error> {
Ok(())
}
}
impl<T, E> EntityCommandOutput for Result<T, E>
where
E: Debug + Display + Send + Sync + 'static,
{
type Out = T;
type Error = EntityCommandError<E>;
#[inline]
fn into_result(self) -> Result<Self::Out, Self::Error> {
self.map_err(EntityCommandError::CommandFailed)
}
}