use boring::error::ErrorStack;
use quinn_proto::{crypto, ConnectError, TransportError};
use std::ffi::c_int;
use std::fmt::{Debug, Display, Formatter};
use std::io::ErrorKind;
use std::result::Result as StdResult;
use std::{fmt, io};
pub enum Error {
SslError(ErrorStack),
IoError(io::Error),
ConnectError(ConnectError),
TransportError(TransportError),
}
impl Debug for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::SslError(e) => Debug::fmt(&e, f),
Self::IoError(e) => Debug::fmt(&e, f),
Self::ConnectError(e) => Debug::fmt(&e, f),
Self::TransportError(e) => Debug::fmt(&e, f),
}
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::SslError(e) => Display::fmt(&e, f),
Self::IoError(e) => Display::fmt(&e, f),
Self::ConnectError(e) => Display::fmt(&e, f),
Self::TransportError(e) => Display::fmt(&e, f),
}
}
}
impl std::error::Error for Error {}
impl Error {
pub(crate) fn ssl() -> Self {
Error::SslError(ErrorStack::get())
}
pub(crate) fn invalid_input(msg: String) -> Self {
Error::IoError(io::Error::new(ErrorKind::InvalidInput, msg))
}
pub(crate) fn other(msg: String) -> Self {
Error::IoError(io::Error::new(ErrorKind::Other, msg))
}
}
impl From<Error> for crypto::CryptoError {
fn from(_: Error) -> Self {
crypto::CryptoError
}
}
impl From<Error> for ConnectError {
fn from(e: Error) -> Self {
match e {
Error::SslError(_) => Self::EndpointStopping,
Error::IoError(_) => Self::EndpointStopping,
Error::ConnectError(e) => e,
Error::TransportError(_) => Self::EndpointStopping,
}
}
}
impl From<ErrorStack> for Error {
fn from(e: ErrorStack) -> Self {
Error::SslError(e)
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Self {
Error::IoError(e)
}
}
impl From<ConnectError> for Error {
fn from(e: ConnectError) -> Self {
Error::ConnectError(e)
}
}
impl From<TransportError> for Error {
fn from(e: TransportError) -> Self {
Error::TransportError(e)
}
}
pub type Result<T> = StdResult<T, Error>;
pub(crate) type BoringResult = StdResult<(), ErrorStack>;
pub(crate) fn br(bssl_result: c_int) -> BoringResult {
match bssl_result {
1 => Ok(()),
_ => Err(ErrorStack::get()),
}
}
pub(crate) fn br_zero_is_success(bssl_result: c_int) -> BoringResult {
match bssl_result {
0 => Ok(()),
_ => Err(ErrorStack::get()),
}
}
pub(crate) fn map_result(bssl_result: c_int) -> Result<()> {
match bssl_result {
1 => Ok(()),
_ => Err(Error::SslError(ErrorStack::get())),
}
}
pub(crate) fn map_cb_result<T>(result: Result<T>) -> c_int {
match result {
Ok(_) => 1,
_ => 0,
}
}
pub(crate) fn map_result_zero_is_success(bssl_result: c_int) -> Result<()> {
match bssl_result {
0 => Ok(()),
_ => Err(Error::SslError(ErrorStack::get())),
}
}
pub(crate) fn map_ptr_result<T>(r: *mut T) -> Result<*mut T> {
if r.is_null() {
Err(Error::ssl())
} else {
Ok(r)
}
}