ump-ng 0.2.1

Micro message passing library for threads/tasks communication.
Documentation
use std::fmt;

use crate::rctx::RCtxState;

/// Module-specific error codes.
#[derive(Debug)]
pub enum Error<E> {
  /// The server object has shut down.
  ///
  /// This happens when clients:
  /// - attempt to send messages to a server that has been deallocated.
  /// - have their requests dropped from the serrver's queue because the
  ///   server itself was deallocated.
  ServerDisappeared,

  /// A message reply could not be completed because the original requestor
  /// disappearing.
  OriginDisappeared,

  /// All the client objects have shut down.
  ///
  /// This happens when a server attempts to pull the latest node on off the
  /// queue, but there are no more nodes on the queue and all the associated
  /// client objects have been released (impled:  New nodes can never be added
  /// to the queue).
  ClientsDisappeared,

  /// The message was delivered to the server, but the reply context was
  /// released before sending back a reply.
  NoReply,

  /// Application-specific error.
  /// The `E` type is typically declared as the third generic parameter to
  /// [`channel`](crate::channel()).
  App(E)
}

impl<E> Error<E> {
  /// Get application-specific error.
  ///
  /// Will return `None` is the error is not [`Error::App`].
  pub fn into_apperr(self) -> Option<E> {
    match self {
      Self::App(e) => Some(e),
      _ => None
    }
  }

  /// Unwrap application-specific error.
  ///
  /// # Panics
  /// If the error is not [`Error::App`] this function will panic.
  pub fn unwrap_apperr(self) -> E {
    match self {
      Self::App(e) => e,
      _ => panic!("Not an Error::App")
    }
  }
}

impl<E> std::error::Error for Error<E> where E: std::error::Error {}

impl<E> fmt::Display for Error<E>
where
  E: std::error::Error
{
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match self {
      Self::ServerDisappeared => write!(f, "Server disappeared"),
      Self::OriginDisappeared => write!(f, "Requestor disappeared"),
      Self::ClientsDisappeared => write!(f, "Clients disappeared"),
      Self::NoReply => write!(f, "Server didn't reply"),
      Self::App(err) => write!(f, "Application error; {err}")
    }
  }
}

impl<E> From<swctx::Error<RCtxState, E>> for Error<E> {
  fn from(err: swctx::Error<RCtxState, E>) -> Self {
    match err {
      swctx::Error::Aborted(state) => match state {
        RCtxState::Queued => Self::ServerDisappeared,
        RCtxState::Active => Self::NoReply
      },
      swctx::Error::LostWaiter => Self::OriginDisappeared,
      swctx::Error::App(e) => Self::App(e)
    }
  }
}

// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :