1use std::fmt;
4
5use crate::object::ObjectError;
6use crate::property::PropertyError;
7
8#[derive(Debug)]
10pub enum LatticeError {
11 ApplicationAlreadyInitialized,
13 ApplicationNotInitialized,
15 EventLoopCreation(String),
17 WindowCreation(String),
19 Timer(TimerError),
21 Scheduler(SchedulerError),
23 Object(ObjectError),
25 Property(PropertyError),
27 Signal(SignalError),
29 ThreadPool(ThreadPoolError),
31 EventLoopExited,
33}
34
35impl fmt::Display for LatticeError {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 match self {
38 Self::ApplicationAlreadyInitialized => {
39 write!(f, "Application has already been initialized")
40 }
41 Self::ApplicationNotInitialized => {
42 write!(
43 f,
44 "Application has not been initialized. Call Application::new() first"
45 )
46 }
47 Self::EventLoopCreation(msg) => {
48 write!(f, "Failed to create event loop: {msg}")
49 }
50 Self::WindowCreation(msg) => {
51 write!(f, "Failed to create window: {msg}")
52 }
53 Self::Timer(err) => write!(f, "Timer error: {err}"),
54 Self::Scheduler(err) => write!(f, "Scheduler error: {err}"),
55 Self::Object(err) => write!(f, "Object error: {err}"),
56 Self::Property(err) => write!(f, "Property error: {err}"),
57 Self::Signal(err) => write!(f, "Signal error: {err}"),
58 Self::ThreadPool(err) => write!(f, "Thread pool error: {err}"),
59 Self::EventLoopExited => {
60 write!(f, "The event loop has already exited")
61 }
62 }
63 }
64}
65
66impl std::error::Error for LatticeError {
67 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
68 match self {
69 Self::Timer(err) => Some(err),
70 Self::Scheduler(err) => Some(err),
71 Self::Object(err) => Some(err),
72 Self::Property(err) => Some(err),
73 Self::Signal(err) => Some(err),
74 Self::ThreadPool(err) => Some(err),
75 _ => None,
76 }
77 }
78}
79
80#[derive(Debug)]
82pub enum TimerError {
83 InvalidTimerId,
85 EventDispatchFailed,
87}
88
89impl fmt::Display for TimerError {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 match self {
92 Self::InvalidTimerId => write!(f, "Invalid or expired timer ID"),
93 Self::EventDispatchFailed => write!(f, "Failed to dispatch timer event"),
94 }
95 }
96}
97
98impl std::error::Error for TimerError {}
99
100impl From<TimerError> for LatticeError {
101 fn from(err: TimerError) -> Self {
102 Self::Timer(err)
103 }
104}
105
106#[derive(Debug)]
108pub enum SchedulerError {
109 InvalidTaskId,
111 EventDispatchFailed,
113}
114
115impl fmt::Display for SchedulerError {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 match self {
118 Self::InvalidTaskId => write!(f, "Invalid or expired scheduled task ID"),
119 Self::EventDispatchFailed => write!(f, "Failed to dispatch scheduler event"),
120 }
121 }
122}
123
124impl std::error::Error for SchedulerError {}
125
126impl From<SchedulerError> for LatticeError {
127 fn from(err: SchedulerError) -> Self {
128 Self::Scheduler(err)
129 }
130}
131
132impl From<ObjectError> for LatticeError {
133 fn from(err: ObjectError) -> Self {
134 Self::Object(err)
135 }
136}
137
138impl From<PropertyError> for LatticeError {
139 fn from(err: PropertyError) -> Self {
140 Self::Property(err)
141 }
142}
143
144impl From<SignalError> for LatticeError {
145 fn from(err: SignalError) -> Self {
146 Self::Signal(err)
147 }
148}
149
150#[derive(Debug, Clone, PartialEq, Eq)]
152pub enum SignalError {
153 InvalidConnection,
155 SignalDropped,
157 QueueFailed,
159}
160
161impl fmt::Display for SignalError {
162 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163 match self {
164 Self::InvalidConnection => write!(f, "Invalid or disconnected connection ID"),
165 Self::SignalDropped => write!(f, "Signal has been dropped"),
166 Self::QueueFailed => write!(f, "Failed to queue signal invocation"),
167 }
168 }
169}
170
171impl std::error::Error for SignalError {}
172
173#[derive(Debug)]
175pub enum ThreadPoolError {
176 AlreadyInitialized,
178 CreationFailed(String),
180 TaskCancelled,
182 SubmissionFailed,
184}
185
186#[derive(Debug, Clone)]
188pub enum ThreadError {
189 WrongThread {
191 operation: String,
193 expected: Option<String>,
195 actual: String,
197 },
198 AffinityViolation {
200 object: String,
202 },
203}
204
205impl fmt::Display for ThreadError {
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 match self {
208 Self::WrongThread {
209 operation,
210 expected,
211 actual,
212 } => {
213 write!(f, "'{operation}' called from wrong thread (got: {actual}")?;
214 if let Some(exp) = expected {
215 write!(f, ", expected: {exp}")?;
216 }
217 write!(f, ")")
218 }
219 Self::AffinityViolation { object } => {
220 write!(
221 f,
222 "'{object}' accessed from wrong thread (thread affinity violation)"
223 )
224 }
225 }
226 }
227}
228
229impl std::error::Error for ThreadError {}
230
231impl fmt::Display for ThreadPoolError {
232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 match self {
234 Self::AlreadyInitialized => write!(f, "Thread pool has already been initialized"),
235 Self::CreationFailed(msg) => write!(f, "Failed to create thread pool: {msg}"),
236 Self::TaskCancelled => write!(f, "Task was cancelled"),
237 Self::SubmissionFailed => write!(f, "Failed to submit task to thread pool"),
238 }
239 }
240}
241
242impl std::error::Error for ThreadPoolError {}
243
244impl From<ThreadPoolError> for LatticeError {
245 fn from(err: ThreadPoolError) -> Self {
246 Self::ThreadPool(err)
247 }
248}
249
250pub type Result<T> = std::result::Result<T, LatticeError>;