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
138
139
140
141
142
use super::MethodCall;
use std::{
    error::Error,
    fmt::{self, Display, Formatter},
};
use tokio::time::Elapsed;

/// Represents possible errors that an HTTPS webhook server may return.
#[derive(Debug)]
pub enum HttpsWebhook {
    /// An error during setting the webhook.
    SetWebhook(MethodCall),
    /// Calling the `setWebhook` method timed out.
    SetWebhookTimeout(Elapsed),
    /// An error during initializing TLS.
    Tls(native_tls::Error),
    /// An error during port binding.
    Bind(std::io::Error),
    /// An error while running the server.
    Server(hyper::Error),
}

impl HttpsWebhook {
    /// Checks if `self` is `SetWebhook`.
    #[must_use]
    pub fn is_set_webhook(&self) -> bool {
        match self {
            Self::SetWebhook(..) => true,
            _ => false,
        }
    }

    /// Checks if `self` is `SetWebhookTimeout`.
    #[must_use]
    pub fn is_set_webhook_timeout(&self) -> bool {
        match self {
            Self::SetWebhookTimeout(..) => true,
            _ => false,
        }
    }

    /// Checks if `self` is `Tls`.
    #[must_use]
    pub fn is_tls(&self) -> bool {
        match self {
            Self::Tls(..) => true,
            _ => false,
        }
    }

    /// Checks if `self` is `Bind`.
    #[must_use]
    pub fn is_bind(&self) -> bool {
        match self {
            Self::Bind(..) => true,
            _ => false,
        }
    }

    /// Checks if `self` is `Server`.
    #[must_use]
    pub fn is_server(&self) -> bool {
        match self {
            Self::Server(..) => true,
            _ => false,
        }
    }
}

impl Display for HttpsWebhook {
    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
        match self {
            Self::SetWebhook(error) => write!(
                formatter,
                "The webhook event loop failed because a call to `setWebhook` \
                 failed with an error: {}",
                error,
            ),
            Self::SetWebhookTimeout(timeout) => write!(
                formatter,
                "The webhook event loop failed because a call to `setWebhook` \
                 timed out: {}",
                timeout,
            ),
            Self::Tls(timeout) => write!(
                formatter,
                "The webhook event loop failed because TLS initialization \
                 failed with an error: {}",
                timeout,
            ),
            Self::Bind(timeout) => write!(
                formatter,
                "The webhook event loop failed because failed to bind to a \
                 port: {}",
                timeout,
            ),
            Self::Server(error) => write!(
                formatter,
                "The webhook event loop failed because the server returned \
                 with an error: {}",
                error,
            ),
        }
    }
}

impl Error for HttpsWebhook {}

impl From<MethodCall> for HttpsWebhook {
    #[must_use]
    fn from(error: MethodCall) -> Self {
        Self::SetWebhook(error)
    }
}

impl From<Elapsed> for HttpsWebhook {
    #[must_use]
    fn from(error: Elapsed) -> Self {
        Self::SetWebhookTimeout(error)
    }
}

impl From<native_tls::Error> for HttpsWebhook {
    #[must_use]
    fn from(error: native_tls::Error) -> Self {
        Self::Tls(error)
    }
}

impl From<std::io::Error> for HttpsWebhook {
    #[must_use]
    fn from(error: std::io::Error) -> Self {
        Self::Bind(error)
    }
}

impl From<hyper::Error> for HttpsWebhook {
    #[must_use]
    fn from(error: hyper::Error) -> Self {
        Self::Server(error)
    }
}