bevy_ecs/error/
command_handling.rs1use core::fmt;
2
3use bevy_utils::prelude::DebugName;
4
5use crate::{
6 entity::Entity,
7 never::Never,
8 system::{entity_command::EntityCommandError, Command, EntityCommand},
9 world::{error::EntityMutableFetchError, World},
10};
11
12use super::{BevyError, ErrorContext, ErrorHandler};
13
14pub trait HandleError<Out = ()>: Send + 'static {
17 fn handle_error_with(self, error_handler: ErrorHandler) -> impl Command;
20 fn handle_error(self) -> impl Command;
23 fn ignore_error(self) -> impl Command;
25}
26
27impl<C, T, E> HandleError<Result<T, E>> for C
28where
29 C: Command<Result<T, E>>,
30 E: Into<BevyError>,
31{
32 fn handle_error_with(self, error_handler: ErrorHandler) -> impl Command {
33 move |world: &mut World| match self.apply(world) {
34 Ok(_) => {}
35 Err(err) => (error_handler)(
36 err.into(),
37 ErrorContext::Command {
38 name: DebugName::type_name::<C>(),
39 },
40 ),
41 }
42 }
43
44 fn handle_error(self) -> impl Command {
45 move |world: &mut World| match self.apply(world) {
46 Ok(_) => {}
47 Err(err) => world.default_error_handler()(
48 err.into(),
49 ErrorContext::Command {
50 name: DebugName::type_name::<C>(),
51 },
52 ),
53 }
54 }
55
56 fn ignore_error(self) -> impl Command {
57 move |world: &mut World| {
58 let _ = self.apply(world);
59 }
60 }
61}
62
63impl<C> HandleError<Never> for C
64where
65 C: Command<Never>,
66{
67 fn handle_error_with(self, _error_handler: fn(BevyError, ErrorContext)) -> impl Command {
68 move |world: &mut World| {
69 self.apply(world);
70 }
71 }
72
73 #[inline]
74 fn handle_error(self) -> impl Command {
75 move |world: &mut World| {
76 self.apply(world);
77 }
78 }
79
80 #[inline]
81 fn ignore_error(self) -> impl Command {
82 move |world: &mut World| {
83 self.apply(world);
84 }
85 }
86}
87
88impl<C> HandleError for C
89where
90 C: Command,
91{
92 #[inline]
93 fn handle_error_with(self, _error_handler: fn(BevyError, ErrorContext)) -> impl Command {
94 self
95 }
96 #[inline]
97 fn handle_error(self) -> impl Command {
98 self
99 }
100 #[inline]
101 fn ignore_error(self) -> impl Command {
102 self
103 }
104}
105
106pub trait CommandWithEntity<Out> {
114 fn with_entity(self, entity: Entity) -> impl Command<Out> + HandleError<Out>;
117}
118
119impl<C> CommandWithEntity<Result<(), EntityMutableFetchError>> for C
120where
121 C: EntityCommand,
122{
123 fn with_entity(
124 self,
125 entity: Entity,
126 ) -> impl Command<Result<(), EntityMutableFetchError>>
127 + HandleError<Result<(), EntityMutableFetchError>> {
128 move |world: &mut World| -> Result<(), EntityMutableFetchError> {
129 let entity = world.get_entity_mut(entity)?;
130 self.apply(entity);
131 Ok(())
132 }
133 }
134}
135
136impl<C, T, Err> CommandWithEntity<Result<T, EntityCommandError<Err>>> for C
137where
138 C: EntityCommand<Result<T, Err>>,
139 Err: fmt::Debug + fmt::Display + Send + Sync + 'static,
140{
141 fn with_entity(
142 self,
143 entity: Entity,
144 ) -> impl Command<Result<T, EntityCommandError<Err>>> + HandleError<Result<T, EntityCommandError<Err>>>
145 {
146 move |world: &mut World| {
147 let entity = world.get_entity_mut(entity)?;
148 self.apply(entity)
149 .map_err(EntityCommandError::CommandFailed)
150 }
151 }
152}