1use derive_more::derive::{Display, Error};
2
3use crate::{entity::Entity, world::unsafe_world_cell::UnsafeWorldCell};
4
5#[derive(Clone, Copy)]
8pub enum QueryEntityError<'w> {
9 QueryDoesNotMatch(Entity, UnsafeWorldCell<'w>),
13 NoSuchEntity(Entity),
15 AliasedMutability(Entity),
19}
20
21impl<'w> core::error::Error for QueryEntityError<'w> {}
22
23impl<'w> core::fmt::Display for QueryEntityError<'w> {
24 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
25 match *self {
26 Self::QueryDoesNotMatch(entity, world) => {
27 write!(
28 f,
29 "The query does not match the entity {entity}, which has components "
30 )?;
31 format_archetype(f, world, entity)
32 }
33 Self::NoSuchEntity(entity) => write!(f, "The entity {entity} does not exist"),
34 Self::AliasedMutability(entity) => write!(
35 f,
36 "The entity {entity} was requested mutably more than once"
37 ),
38 }
39 }
40}
41
42impl<'w> core::fmt::Debug for QueryEntityError<'w> {
43 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
44 match *self {
45 Self::QueryDoesNotMatch(entity, world) => {
46 write!(f, "QueryDoesNotMatch({entity} with components ")?;
47 format_archetype(f, world, entity)?;
48 write!(f, ")")
49 }
50 Self::NoSuchEntity(entity) => write!(f, "NoSuchEntity({entity})"),
51 Self::AliasedMutability(entity) => write!(f, "AliasedMutability({entity})"),
52 }
53 }
54}
55
56fn format_archetype(
57 f: &mut core::fmt::Formatter<'_>,
58 world: UnsafeWorldCell<'_>,
59 entity: Entity,
60) -> core::fmt::Result {
61 let entity = world
63 .get_entity(entity)
64 .expect("entity does not belong to world");
65 for (i, component_id) in entity.archetype().components().enumerate() {
66 if i > 0 {
67 write!(f, ", ")?;
68 }
69 let name = world
70 .components()
71 .get_name(component_id)
72 .expect("entity does not belong to world");
73 write!(f, "{}", disqualified::ShortName(name))?;
74 }
75 Ok(())
76}
77
78impl<'w> PartialEq for QueryEntityError<'w> {
79 fn eq(&self, other: &Self) -> bool {
80 match (self, other) {
81 (Self::QueryDoesNotMatch(e1, _), Self::QueryDoesNotMatch(e2, _)) if e1 == e2 => true,
82 (Self::NoSuchEntity(e1), Self::NoSuchEntity(e2)) if e1 == e2 => true,
83 (Self::AliasedMutability(e1), Self::AliasedMutability(e2)) if e1 == e2 => true,
84 _ => false,
85 }
86 }
87}
88
89impl<'w> Eq for QueryEntityError<'w> {}
90
91#[derive(Debug, Error, Display)]
94pub enum QuerySingleError {
95 #[display("No entities fit the query {_0}")]
97 #[error(ignore)]
98 NoEntities(&'static str),
99 #[display("Multiple entities fit the query {_0}")]
101 #[error(ignore)]
102 MultipleEntities(&'static str),
103}
104
105#[cfg(test)]
106mod test {
107 use crate as bevy_ecs;
108 use crate::prelude::World;
109 use bevy_ecs_macros::Component;
110
111 #[test]
112 fn query_does_not_match() {
113 let mut world = World::new();
114
115 #[derive(Component)]
116 struct Present1;
117 #[derive(Component)]
118 struct Present2;
119 #[derive(Component, Debug)]
120 struct NotPresent;
121
122 let entity = world.spawn((Present1, Present2)).id();
123
124 let err = world
125 .query::<&NotPresent>()
126 .get(&world, entity)
127 .unwrap_err();
128
129 assert_eq!(
130 format!("{err:?}"),
131 "QueryDoesNotMatch(0v1 with components Present1, Present2)"
132 );
133 }
134}