ump_ng/err.rs
1use std::fmt;
2
3use crate::rctx::RCtxState;
4
5/// Module-specific error codes.
6#[derive(Debug)]
7pub enum Error<E> {
8 /// The server object has shut down.
9 ///
10 /// This happens when clients:
11 /// - attempt to send messages to a server that has been deallocated.
12 /// - have their requests dropped from the serrver's queue because the
13 /// server itself was deallocated.
14 ServerDisappeared,
15
16 /// A message reply could not be completed because the original requestor
17 /// disappearing.
18 OriginDisappeared,
19
20 /// All the client objects have shut down.
21 ///
22 /// This happens when a server attempts to pull the latest node on off the
23 /// queue, but there are no more nodes on the queue and all the associated
24 /// client objects have been released (impled: New nodes can never be added
25 /// to the queue).
26 ClientsDisappeared,
27
28 /// The message was delivered to the server, but the reply context was
29 /// released before sending back a reply.
30 NoReply,
31
32 /// Application-specific error.
33 /// The `E` type is typically declared as the third generic parameter to
34 /// [`channel`](crate::channel()).
35 App(E)
36}
37
38impl<E> Error<E> {
39 /// Get application-specific error.
40 ///
41 /// Will return `None` is the error is not [`Error::App`].
42 pub fn into_apperr(self) -> Option<E> {
43 match self {
44 Self::App(e) => Some(e),
45 _ => None
46 }
47 }
48
49 /// Unwrap application-specific error.
50 ///
51 /// # Panics
52 /// If the error is not [`Error::App`] this function will panic.
53 pub fn unwrap_apperr(self) -> E {
54 match self {
55 Self::App(e) => e,
56 _ => panic!("Not an Error::App")
57 }
58 }
59}
60
61impl<E> std::error::Error for Error<E> where E: std::error::Error {}
62
63impl<E> fmt::Display for Error<E>
64where
65 E: std::error::Error
66{
67 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68 match self {
69 Self::ServerDisappeared => write!(f, "Server disappeared"),
70 Self::OriginDisappeared => write!(f, "Requestor disappeared"),
71 Self::ClientsDisappeared => write!(f, "Clients disappeared"),
72 Self::NoReply => write!(f, "Server didn't reply"),
73 Self::App(err) => write!(f, "Application error; {err}")
74 }
75 }
76}
77
78impl<E> From<swctx::Error<RCtxState, E>> for Error<E> {
79 fn from(err: swctx::Error<RCtxState, E>) -> Self {
80 match err {
81 swctx::Error::Aborted(state) => match state {
82 RCtxState::Queued => Self::ServerDisappeared,
83 RCtxState::Active => Self::NoReply
84 },
85 swctx::Error::LostWaiter => Self::OriginDisappeared,
86 swctx::Error::App(e) => Self::App(e)
87 }
88 }
89}
90
91// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :