extern crate native_tls;
use std::io::{Read, Write};
use std::io::Error as IoError;
use std::string::String;
use self::native_tls::HandshakeError;
use self::native_tls::Error as SslError;
use yasna::ASN1Error;
use num_enum::{TryFromPrimitive, TryFromPrimitiveError};
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum RdpErrorKind {
InvalidData,
InvalidRespond,
NotImplemented,
ProtocolNegFailure,
InvalidAutomata,
InvalidProtocol,
InvalidCast,
InvalidConst,
InvalidChecksum,
InvalidOptionalField,
InvalidSize,
PossibleMITM,
RejectedByServer,
Disconnect,
Unknown,
UnexpectedType
}
#[derive(Debug)]
pub struct RdpError {
kind: RdpErrorKind,
message: String
}
impl RdpError {
pub fn new (kind: RdpErrorKind, message: &str) -> Self {
RdpError {
kind,
message: String::from(message)
}
}
pub fn kind(&self) -> RdpErrorKind {
self.kind
}
}
#[derive(Debug)]
pub enum Error {
RdpError(RdpError),
Io(IoError),
SslHandshakeError,
SslError(SslError),
ASN1Error(ASN1Error),
TryError(String)
}
impl From<IoError> for Error {
fn from(e: IoError) -> Self {
Error::Io(e)
}
}
impl<S: Read + Write> From<HandshakeError<S>> for Error {
fn from(_: HandshakeError<S>) -> Error {
Error::SslHandshakeError
}
}
impl From<SslError> for Error {
fn from(e: SslError) -> Error {
Error::SslError(e)
}
}
impl From<ASN1Error> for Error {
fn from(e: ASN1Error) -> Error {
Error::ASN1Error(e)
}
}
impl<T: TryFromPrimitive> From<TryFromPrimitiveError<T>> for Error {
fn from(_: TryFromPrimitiveError<T>) -> Self {
Error::RdpError(RdpError::new(RdpErrorKind::InvalidCast, "Invalid enum conversion"))
}
}
pub type RdpResult<T> = Result<T, Error>;
#[macro_export]
macro_rules! try_option {
($val: expr, $expr: expr) => {
if let Some(x) = $val {
Ok(x)
} else {
Err(Error::RdpError(RdpError::new(RdpErrorKind::InvalidOptionalField, $expr)))
}
}
}
#[macro_export]
macro_rules! try_let {
($ident: path, $val: expr) => {
if let $ident(x) = $val {
Ok(x)
} else {
Err(Error::RdpError(RdpError::new(RdpErrorKind::InvalidCast, "Invalid Cast")))
}
}
}