use std::ptr::{null, null_mut};
use libc::EINVAL;
use crate::enums::{rustls_handshake_kind, rustls_tls_version};
use crate::error::{rustls_io_result, rustls_result};
use crate::rslice::{rustls_slice_bytes, rustls_str};
pub(crate) trait PanicOrDefault {
fn value() -> Self;
}
pub(crate) trait NullParameterOrDefault {
fn value() -> Self;
}
pub(crate) trait Defaultable: Default {}
impl Defaultable for u16 {}
impl Defaultable for u32 {}
impl Defaultable for usize {}
impl Defaultable for bool {}
impl Defaultable for () {}
impl Defaultable for rustls_tls_version {}
impl Defaultable for rustls_handshake_kind {}
impl<T> Defaultable for Option<T> {}
impl Defaultable for rustls_slice_bytes<'_> {}
impl<T: Defaultable> PanicOrDefault for T {
fn value() -> Self {
Default::default()
}
}
impl<T> PanicOrDefault for *mut T {
fn value() -> Self {
null_mut()
}
}
impl<T> PanicOrDefault for *const T {
fn value() -> Self {
null()
}
}
impl PanicOrDefault for rustls_result {
fn value() -> Self {
rustls_result::Panic
}
}
impl PanicOrDefault for rustls_str<'_> {
fn value() -> Self {
rustls_str::from_str_unchecked("")
}
}
impl PanicOrDefault for rustls_io_result {
fn value() -> Self {
rustls_io_result(EINVAL)
}
}
impl<T: Defaultable> NullParameterOrDefault for T {
fn value() -> Self {
Default::default()
}
}
impl<T> NullParameterOrDefault for *mut T {
fn value() -> Self {
null_mut()
}
}
impl<T> NullParameterOrDefault for *const T {
fn value() -> Self {
null()
}
}
impl NullParameterOrDefault for rustls_result {
fn value() -> Self {
rustls_result::NullParameter
}
}
impl NullParameterOrDefault for rustls_io_result {
fn value() -> Self {
rustls_io_result(EINVAL)
}
}
impl NullParameterOrDefault for rustls_str<'_> {
fn value() -> Self {
rustls_str::from_str_unchecked("")
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! ffi_panic_boundary {
( $($tt:tt)* ) => {
match ::std::panic::catch_unwind(|| {
$($tt)*
}) {
Ok(ret) => ret,
Err(_) => return $crate::panic::PanicOrDefault::value(),
}
}
}
pub(crate) use ffi_panic_boundary;