ump/
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  /// Happens when clients:
11  /// - attempt to transmit 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  /// No more client end-points remain.
21  ///
22  /// There are no more nodes to pick up in the queue and all client
23  /// end-points have been dropped (implied: no new nodes will ever be added
24  /// to the queue).
25  ClientsDisappeared,
26
27  /// The message was delivered to the server, but the reply context was
28  /// dropped before transmitting a reply.
29  NoReply,
30
31  /// Application-specific error.
32  ///
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  /// Attempt to convert [`Error`] into application-specific error.
40  pub fn into_apperr(self) -> Option<E> {
41    match self {
42      Self::App(e) => Some(e),
43      _ => None
44    }
45  }
46
47  /// Unwrap application-specific error from an [`Error`].
48  ///
49  /// # Panics
50  /// Panics if `Error` variant is not `Error::App()`.
51  pub fn unwrap_apperr(self) -> E {
52    match self {
53      Self::App(e) => e,
54      _ => panic!("Not an Error::App")
55    }
56  }
57}
58
59impl<E: std::error::Error> std::error::Error for Error<E> {}
60
61impl<E> fmt::Display for Error<E>
62where
63  E: std::error::Error
64{
65  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66    match self {
67      Self::ServerDisappeared => write!(f, "Server disappeared"),
68      Self::OriginDisappeared => write!(f, "Requestor disappeared"),
69      Self::ClientsDisappeared => write!(f, "Clients disappeared"),
70      Self::NoReply => write!(f, "Server didn't reply"),
71      Self::App(err) => write!(f, "Application error; {}", err)
72    }
73  }
74}
75
76impl<E> From<swctx::Error<RCtxState, E>> for Error<E> {
77  fn from(err: swctx::Error<RCtxState, E>) -> Self {
78    match err {
79      swctx::Error::Aborted(state) => match state {
80        RCtxState::Queued => Self::ServerDisappeared,
81        RCtxState::Active => Self::NoReply
82      },
83      swctx::Error::LostWaiter => Self::OriginDisappeared,
84      swctx::Error::App(e) => Self::App(e)
85    }
86  }
87}
88
89// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :