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
use std::fmt::Display;
use thiserror::Error;
use tokio::sync::{broadcast, mpsc::error as mpsc, oneshot};
use tungstenite::error as wserror;
use crate::message;
pub type Result<T, E = Error> = core::result::Result<T, E>;
#[derive(Error, PartialEq, Debug)]
pub enum Error {
#[error("Connect: `{0}`")]
Connect(String),
#[error("ConnectionClosed")]
ConnectionClosed(String),
#[error("TimeOut")]
TimeOut,
#[error("Stream Not Found")]
StreamNotFound,
#[error("Unexpected: `{0}`")]
Unexpected(String),
#[error("Encode: `{0}`")]
Encode(String),
#[error("Decode: `{0}`")]
MalformedMessage(String),
#[error("Failed Message (ResultCode: {code:?}, detail: {detail:?})")]
FailedMessage {
code: message::ResultCode,
detail: String,
},
#[error("Invalid Value `{0}`")]
InvalidValue(String),
#[error("Max Data Point Count")]
MaxDataPointCount,
#[error("Max MaxSequence Number")]
MaxSequenceNumber,
#[error("invalid certificate")]
Certificate(#[from] webpki::Error),
#[error("invalid certificate")]
CertificateLoad(String),
}
impl From<wserror::Error> for Error {
fn from(e: wserror::Error) -> Self {
use wserror::Error as err;
match e {
err::AlreadyClosed | err::ConnectionClosed => Self::ConnectionClosed("".into()),
_ => Self::unexpected(e),
}
}
}
impl<T> From<mpsc::SendError<T>> for Error {
fn from(e: mpsc::SendError<T>) -> Self {
Error::Unexpected(e.to_string()) }
}
impl From<oneshot::error::RecvError> for Error {
fn from(e: oneshot::error::RecvError) -> Self {
Error::unexpected(e) }
}
impl From<broadcast::error::RecvError> for Error {
fn from(e: broadcast::error::RecvError) -> Self {
Error::unexpected(e)
}
}
impl From<tokio::time::error::Elapsed> for Error {
fn from(_e: tokio::time::error::Elapsed) -> Self {
Error::TimeOut
}
}
impl From<time::OutOfRangeError> for Error {
fn from(e: time::OutOfRangeError) -> Self {
Error::invalid_value(e)
}
}
impl Error {
pub fn unexpected<T: Display>(s: T) -> Self {
Error::Unexpected(s.to_string())
}
pub fn invalid_value<T: Display>(s: T) -> Self {
Error::InvalidValue(s.to_string())
}
pub fn failed_message<T: Display>(code: message::ResultCode, s: T) -> Self {
Error::FailedMessage {
code,
detail: s.to_string(),
}
}
pub fn connect<T: Display>(s: T) -> Self {
Error::Connect(s.to_string())
}
pub fn encode<T: ToString>(s: T) -> Self {
Error::Encode(s.to_string())
}
pub fn malformed_message<T: ToString>(s: T) -> Self {
Error::MalformedMessage(s.to_string())
}
}