1pub(crate) mod cache;
4pub(crate) mod cmd;
5pub(crate) mod ent;
6pub(crate) mod entry;
7pub(crate) mod lock;
8pub(crate) mod post;
9pub(crate) mod resource;
10pub(crate) mod sched;
11pub(crate) mod sys;
12pub(crate) mod wait;
13pub(crate) mod web;
14pub(crate) mod worker;
15
16pub mod prelude {
17 pub use super::{
18 cmd::prelude::*,
19 ent::prelude::*,
20 entry::prelude::*,
21 post::prelude::*,
22 resource::prelude::*,
23 sched::prelude::*,
24 sys::prelude::*,
25 worker::prelude::*,
26 {DynResult, EcsError},
27 };
28}
29
30use std::{error::Error, fmt};
31use thiserror::Error;
32
33pub type DynResult<T> = Result<T, Box<dyn Error + Send + Sync + 'static>>;
36
37#[derive(Error)]
39#[repr(C)]
40pub enum EcsError<Data = ()> {
41 #[error("unknown system `{0}`")]
42 UnknownSystem(String, Data),
43
44 #[error("unknown entity `{0}`")]
45 UnknownEntity(String, Data),
46 #[error("invalid entity `{0}`")]
47 InvalidEntity(String, Data),
48
49 #[error("unknown resource `{0}`")]
50 UnknownResource(String, Data),
51 #[error("duplicated resource `{0}`")]
52 DupResource(String, Data),
53
54 #[error("invalid request `{0}`")]
55 InvalidRequest(String, Data),
56
57 #[error("unknown error `{0}`")]
58 Unknown(String, Data),
59}
60
61impl<Data> fmt::Debug for EcsError<Data> {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 match self {
64 Self::UnknownSystem(reason, ..) => {
65 write!(f, "EcsError::UnknownSystem({reason}, ..)")
66 }
67 Self::UnknownEntity(reason, ..) => {
68 write!(f, "EcsError::UnknownEntity({reason}, ..)")
69 }
70 Self::InvalidEntity(reason, ..) => {
71 write!(f, "EcsError::InvalidEntity({reason}, ..)")
72 }
73 Self::UnknownResource(reason, ..) => {
74 write!(f, "EcsError::UnknownResource({reason}, ..)")
75 }
76 Self::DupResource(reason, ..) => {
77 write!(f, "EcsError::DupResource({reason}, ..)")
78 }
79 Self::InvalidRequest(reason, ..) => {
80 write!(f, "EcsError::InvalidRequest({reason}, ..)")
81 }
82 Self::Unknown(reason, ..) => {
83 write!(f, "EcsError::Unknown({reason}, ..)")
84 }
85 }
86 }
87}
88
89impl<Data> EcsError<Data> {
90 pub fn reason(&self) -> &str {
91 match self {
92 Self::UnknownSystem(reason, ..) => reason,
93 Self::UnknownEntity(reason, ..) => reason,
94 Self::InvalidEntity(reason, ..) => reason,
95 Self::UnknownResource(reason, ..) => reason,
96 Self::DupResource(reason, ..) => reason,
97 Self::InvalidRequest(reason, ..) => reason,
98 Self::Unknown(reason, ..) => reason,
99 }
100 }
101
102 pub fn take_data(self) -> Data {
103 match self {
104 Self::UnknownSystem(_, data) => data,
105 Self::UnknownEntity(_, data) => data,
106 Self::InvalidEntity(_, data) => data,
107 Self::UnknownResource(_, data) => data,
108 Self::DupResource(_, data) => data,
109 Self::InvalidRequest(_, data) => data,
110 Self::Unknown(_, data) => data,
111 }
112 }
113
114 pub fn without_data(self) -> EcsError<()> {
115 self.with_data(())
116 }
117
118 pub fn with_data<OutData>(self, data: OutData) -> EcsError<OutData> {
119 self.map_data(|_| data)
120 }
121
122 pub fn map_data<F, OutData>(self, f: F) -> EcsError<OutData>
123 where
124 F: FnOnce(Data) -> OutData,
125 {
126 match self {
127 Self::UnknownSystem(reason, old) => EcsError::UnknownSystem(reason, f(old)),
128 Self::UnknownEntity(reason, old) => EcsError::UnknownEntity(reason, f(old)),
129 Self::InvalidEntity(reason, old) => EcsError::InvalidEntity(reason, f(old)),
130 Self::UnknownResource(reason, old) => EcsError::UnknownResource(reason, f(old)),
131 Self::DupResource(reason, old) => EcsError::DupResource(reason, f(old)),
132 Self::InvalidRequest(reason, old) => EcsError::InvalidRequest(reason, f(old)),
133 Self::Unknown(reason, old) => EcsError::Unknown(reason, f(old)),
134 }
135 }
136}
137
138pub mod stat {
139 macro_rules! decl_counter {
140 ($name:ident, $id:ident) => {
141 paste::paste! {
142 #[cfg(feature = "stat")]
143 pub(crate) static $id: std::sync::LazyLock<std::sync::atomic::AtomicI64> =
144 std::sync::LazyLock::new(|| std::sync::atomic::AtomicI64::new(0));
145
146 pub fn [<current _$name>]() -> i64 {
147 #[cfg(feature = "stat")]
148 { $id.load(std::sync::atomic::Ordering::Relaxed) }
149
150 #[cfg(not(feature = "stat"))]
151 { -1 }
152 }
153
154 pub fn [<reset _$name>]() {
155 #[cfg(feature = "stat")]
156 $id.store(0, std::sync::atomic::Ordering::Relaxed);
157 }
158
159 pub(crate) fn [<increase _$name>]() {
160 #[cfg(feature = "stat")]
161 $id.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
162 }
163
164 pub fn [<assert_eq _$name>](_value: i64) {
165 #[cfg(feature = "stat")]
166 assert_eq!([<current _$name>](), _value);
167 }
168
169 pub fn [<assert_ne _$name>](_value: i64) {
170 #[cfg(feature = "stat")]
171 assert_ne!([<current _$name>](), _value);
172 }
173 }
174 };
175 }
176
177 decl_counter!(system_task_count, SYS_CNT);
178 decl_counter!(future_task_count, FUT_CNT);
179 decl_counter!(parallel_task_count, PAR_CNT);
180}