1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//! Error types used in this crate
use std::{error::Error as IError, fmt};

use thiserror::Error;

/// Error returned by functions in this crate
#[derive(Debug)]
pub struct Error {
    inner: Inner,
}

impl Error {
    /// Returns the kind of error
    pub fn kind(&self) -> ErrorKind {
        (&self.inner).into()
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.kind().fmt(f)
    }
}

impl IError for Error {
    fn source(&self) -> Option<&(dyn IError + 'static)> {
        self.inner.source()
    }
}

#[doc(hidden)]
impl From<Error> for std::io::Error {
    fn from(error: Error) -> Self {
        std::io::Error::new(std::io::ErrorKind::Other, error)
    }
}

#[doc(hidden)]
impl<T: Into<Inner>> From<T> for Error {
    fn from(inner: T) -> Self {
        Self {
            inner: inner.into(),
        }
    }
}

/// Different kinds of possible errors returned by functions in this crate
#[derive(Debug)]
#[non_exhaustive]
pub enum ErrorKind {
    /// Stream connecting error
    StreamConnectError,
    /// Channel receiving error
    ChannelRecvError,
    /// Channel sending error
    ChannelSendError,
    /// Other error
    Other,
}

impl fmt::Display for ErrorKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::StreamConnectError => write!(f, "Stream connecting error"),
            Self::ChannelRecvError => write!(f, "Channel receiving error"),
            Self::ChannelSendError => write!(f, "Channel sending error"),
            Self::Other => write!(f, "Other error"),
        }
    }
}

#[doc(hidden)]
#[derive(Debug, Error)]
pub enum Inner {
    #[cfg(feature = "sync")]
    #[error("Sync stream connecting error")]
    SyncConnectError,
    #[cfg(feature = "sync")]
    #[error("Sync channel receiving error: {0}")]
    SyncRecvError(#[from] std::sync::mpsc::RecvError),
    #[cfg(feature = "sync")]
    #[error("Sync channel sending error: {0}")]
    SyncSendError(#[from] std::sync::mpsc::SendError<Vec<u8>>),
    #[cfg(feature = "async-futures")]
    #[error("Async stream connecting error")]
    AsyncConnectError(#[from] async_channel::SendError<crate::futures::MockStream>),
    #[cfg(feature = "async-futures")]
    #[error("Async channel receiving error: {0}")]
    AsyncRecvError(#[from] async_channel::RecvError),
    #[cfg(feature = "async-futures")]
    #[error("Async channel sending error: {0}")]
    AsyncSendError(#[from] async_channel::SendError<Vec<u8>>),
    #[cfg(feature = "async-tokio")]
    #[error("Tokio stream connecting error")]
    TokioConnectError(#[from] tokio::sync::mpsc::error::SendError<crate::tokio::MockStream>),
    #[cfg(feature = "async-tokio")]
    #[error("Tokio channel receiving error")]
    TokioRecvError,
    #[cfg(feature = "async-tokio")]
    #[error("Tokio channel sending error: {0}")]
    TokioSendError(#[from] tokio::sync::mpsc::error::SendError<Vec<u8>>),
    #[error("Other error")]
    Other,
}

impl<'a> From<&'a Inner> for ErrorKind {
    fn from(inner: &'a Inner) -> Self {
        match inner {
            #[cfg(feature = "sync")]
            Inner::SyncConnectError => ErrorKind::StreamConnectError,
            #[cfg(feature = "sync")]
            Inner::SyncRecvError(_) => ErrorKind::ChannelRecvError,
            #[cfg(feature = "sync")]
            Inner::SyncSendError(_) => ErrorKind::ChannelSendError,
            #[cfg(feature = "async-futures")]
            Inner::AsyncConnectError(_) => ErrorKind::StreamConnectError,
            #[cfg(feature = "async-futures")]
            Inner::AsyncRecvError(_) => ErrorKind::ChannelRecvError,
            #[cfg(feature = "async-futures")]
            Inner::AsyncSendError(_) => ErrorKind::ChannelSendError,
            #[cfg(feature = "async-tokio")]
            Inner::TokioConnectError(_) => ErrorKind::StreamConnectError,
            #[cfg(feature = "async-tokio")]
            Inner::TokioRecvError => ErrorKind::ChannelRecvError,
            #[cfg(feature = "async-tokio")]
            Inner::TokioSendError(_) => ErrorKind::ChannelSendError,
            Inner::Other => ErrorKind::Other,
        }
    }
}

#[cfg(feature = "sync")]
impl From<std::sync::mpsc::SendError<crate::sync::MockStream>> for Inner {
    fn from(_: std::sync::mpsc::SendError<crate::sync::MockStream>) -> Self {
        Self::SyncConnectError
    }
}