bevy_ecs/error/
command_handling.rs1use core::{any::type_name, fmt};
2
3use crate::{
4 entity::Entity,
5 never::Never,
6 system::{entity_command::EntityCommandError, Command, EntityCommand},
7 world::{error::EntityMutableFetchError, World},
8};
9
10use super::{default_error_handler, BevyError, ErrorContext};
11
12pub trait HandleError<Out = ()> {
15 fn handle_error_with(self, error_handler: fn(BevyError, ErrorContext)) -> impl Command;
18 fn handle_error(self) -> impl Command
21 where
22 Self: Sized,
23 {
24 self.handle_error_with(default_error_handler())
25 }
26}
27
28impl<C, T, E> HandleError<Result<T, E>> for C
29where
30 C: Command<Result<T, E>>,
31 E: Into<BevyError>,
32{
33 fn handle_error_with(self, error_handler: fn(BevyError, ErrorContext)) -> impl Command {
34 move |world: &mut World| match self.apply(world) {
35 Ok(_) => {}
36 Err(err) => (error_handler)(
37 err.into(),
38 ErrorContext::Command {
39 name: type_name::<C>().into(),
40 },
41 ),
42 }
43 }
44}
45
46impl<C> HandleError<Never> for C
47where
48 C: Command<Never>,
49{
50 fn handle_error_with(self, _error_handler: fn(BevyError, ErrorContext)) -> impl Command {
51 move |world: &mut World| {
52 self.apply(world);
53 }
54 }
55}
56
57impl<C> HandleError for C
58where
59 C: Command,
60{
61 #[inline]
62 fn handle_error_with(self, _error_handler: fn(BevyError, ErrorContext)) -> impl Command {
63 self
64 }
65 #[inline]
66 fn handle_error(self) -> impl Command
67 where
68 Self: Sized,
69 {
70 self
71 }
72}
73
74pub trait CommandWithEntity<Out> {
82 fn with_entity(self, entity: Entity) -> impl Command<Out> + HandleError<Out>;
85}
86
87impl<C> CommandWithEntity<Result<(), EntityMutableFetchError>> for C
88where
89 C: EntityCommand,
90{
91 fn with_entity(
92 self,
93 entity: Entity,
94 ) -> impl Command<Result<(), EntityMutableFetchError>>
95 + HandleError<Result<(), EntityMutableFetchError>> {
96 move |world: &mut World| -> Result<(), EntityMutableFetchError> {
97 let entity = world.get_entity_mut(entity)?;
98 self.apply(entity);
99 Ok(())
100 }
101 }
102}
103
104impl<C, T, Err> CommandWithEntity<Result<T, EntityCommandError<Err>>> for C
105where
106 C: EntityCommand<Result<T, Err>>,
107 Err: fmt::Debug + fmt::Display + Send + Sync + 'static,
108{
109 fn with_entity(
110 self,
111 entity: Entity,
112 ) -> impl Command<Result<T, EntityCommandError<Err>>> + HandleError<Result<T, EntityCommandError<Err>>>
113 {
114 move |world: &mut World| {
115 let entity = world.get_entity_mut(entity)?;
116 self.apply(entity)
117 .map_err(EntityCommandError::CommandFailed)
118 }
119 }
120}