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 :