1extern crate native_tls;
2
3use std::io::{Read, Write};
4use std::io::Error as IoError;
5use std::string::String;
6use self::native_tls::HandshakeError;
7use self::native_tls::Error as SslError;
8use yasna::ASN1Error;
9use num_enum::{TryFromPrimitive, TryFromPrimitiveError};
10
11#[derive(Debug, Copy, Clone, Eq, PartialEq)]
12pub enum RdpErrorKind {
13 InvalidData,
15 InvalidRespond,
17 NotImplemented,
19 ProtocolNegFailure,
23 InvalidAutomata,
25 InvalidProtocol,
28 InvalidCast,
34 InvalidConst,
36 InvalidChecksum,
39 InvalidOptionalField,
40 InvalidSize,
41 PossibleMITM,
44 RejectedByServer,
47 Disconnect,
49 Unknown,
51 UnexpectedType
52}
53
54#[derive(Debug)]
55pub struct RdpError {
56 kind: RdpErrorKind,
58 message: String
60}
61
62impl RdpError {
63 pub fn new (kind: RdpErrorKind, message: &str) -> Self {
70 RdpError {
71 kind,
72 message: String::from(message)
73 }
74 }
75
76 pub fn kind(&self) -> RdpErrorKind {
85 self.kind
86 }
87}
88
89#[derive(Debug)]
90pub enum Error {
91 RdpError(RdpError),
93 Io(IoError),
95 SslHandshakeError,
97 SslError(SslError),
99 ASN1Error(ASN1Error),
101 TryError(String)
103}
104
105impl From<IoError> for Error {
107 fn from(e: IoError) -> Self {
108 Error::Io(e)
109 }
110}
111
112impl<S: Read + Write> From<HandshakeError<S>> for Error {
113 fn from(_: HandshakeError<S>) -> Error {
114 Error::SslHandshakeError
115 }
116}
117
118impl From<SslError> for Error {
119 fn from(e: SslError) -> Error {
120 Error::SslError(e)
121 }
122}
123
124impl From<ASN1Error> for Error {
125 fn from(e: ASN1Error) -> Error {
126 Error::ASN1Error(e)
127 }
128}
129
130impl<T: TryFromPrimitive> From<TryFromPrimitiveError<T>> for Error {
131 fn from(_: TryFromPrimitiveError<T>) -> Self {
132 Error::RdpError(RdpError::new(RdpErrorKind::InvalidCast, "Invalid enum conversion"))
133 }
134}
135
136pub type RdpResult<T> = Result<T, Error>;
137
138#[macro_export]
140macro_rules! try_option {
141 ($val: expr, $expr: expr) => {
142 if let Some(x) = $val {
143 Ok(x)
144 } else {
145 Err(Error::RdpError(RdpError::new(RdpErrorKind::InvalidOptionalField, $expr)))
146 }
147 }
148}
149
150#[macro_export]
151macro_rules! try_let {
152 ($ident: path, $val: expr) => {
153 if let $ident(x) = $val {
154 Ok(x)
155 } else {
156 Err(Error::RdpError(RdpError::new(RdpErrorKind::InvalidCast, "Invalid Cast")))
157 }
158 }
159}
160