ruo/
error.rs

1// Copyright (c) 2020 Xu Shaohua <shaohua@biofan.org>. All rights reserved.
2// Use of this source is governed by Apache-2.0 License that can be found
3// in the LICENSE file.
4
5use std::fmt::{self, Display};
6use std::io;
7use tokio_tungstenite::tungstenite;
8
9/// Represent the types of errors.
10#[allow(clippy::module_name_repetitions)]
11#[derive(Clone, Debug)]
12pub enum ErrorKind {
13    /// Error occurred while performing I/O.
14    IoError,
15
16    /// Packet encode error.
17    EncodeError,
18
19    /// Packet decode error.
20    DecodeError,
21
22    /// Not expected packet.
23    PacketError,
24
25    /// Send packet error.
26    SendError,
27
28    /// Socket stream error.
29    SocketError,
30
31    /// Configure error.
32    ConfigError,
33
34    /// Invalid pid.
35    PidError,
36
37    /// Invalid connect status.
38    InvalidClientStatus,
39
40    /// Auth failed while connecting to server.
41    AuthFailed,
42}
43
44#[allow(clippy::module_name_repetitions)]
45#[derive(Clone, Debug)]
46pub struct Error {
47    /// Type of current error.
48    kind: ErrorKind,
49
50    /// Detail message about this error.
51    message: String,
52}
53
54impl Error {
55    #[must_use]
56    pub fn new(kind: ErrorKind, message: &str) -> Self {
57        Self {
58            kind,
59            message: message.to_owned(),
60        }
61    }
62
63    #[must_use]
64    pub const fn from_string(kind: ErrorKind, message: String) -> Self {
65        Self { kind, message }
66    }
67}
68
69impl Display for Error {
70    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71        write!(f, "{:?}: {}", self.kind, self.message)
72    }
73}
74
75impl std::error::Error for Error {}
76
77impl From<io::Error> for Error {
78    fn from(err: io::Error) -> Self {
79        Self::from_string(ErrorKind::IoError, format!("IoError {:?}", err))
80    }
81}
82
83impl From<tungstenite::Error> for Error {
84    fn from(err: tungstenite::Error) -> Self {
85        Self::from_string(ErrorKind::IoError, format!("Websocket error: {:?}", err))
86    }
87}
88
89impl From<tokio_rustls::webpki::Error> for Error {
90    fn from(err: tokio_rustls::webpki::Error) -> Self {
91        Self::from_string(ErrorKind::ConfigError, format!("webpki error: {:?}", err))
92    }
93}
94
95impl From<quinn::ConnectError> for Error {
96    fn from(err: quinn::ConnectError) -> Self {
97        Self::from_string(
98            ErrorKind::SocketError,
99            format!("Quic connect error: {:?}", err),
100        )
101    }
102}
103
104impl From<quinn::ConnectionError> for Error {
105    fn from(err: quinn::ConnectionError) -> Self {
106        Self::from_string(
107            ErrorKind::SocketError,
108            format!("Quic connection error: {:?}", err),
109        )
110    }
111}
112
113impl From<quinn::ConfigError> for Error {
114    fn from(err: quinn::ConfigError) -> Self {
115        Self::from_string(
116            ErrorKind::ConfigError,
117            format!("Quic config error: {:?}", err),
118        )
119    }
120}
121
122impl From<quinn::WriteError> for Error {
123    fn from(err: quinn::WriteError) -> Self {
124        Self::from_string(
125            ErrorKind::SocketError,
126            format!("Quic write error: {:?}", err),
127        )
128    }
129}
130
131impl From<codec::EncodeError> for Error {
132    fn from(err: codec::EncodeError) -> Self {
133        Self::from_string(ErrorKind::EncodeError, format!("{:?}", err))
134    }
135}
136
137impl From<codec::DecodeError> for Error {
138    fn from(err: codec::DecodeError) -> Self {
139        Self::from_string(ErrorKind::DecodeError, format!("{:?}", err))
140    }
141}