use core::mem::MaybeUninit;
use core::num::NonZeroI32;
#[repr(C)]
#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
pub enum CResult<T, E> {
Ok(T),
Err(E),
}
impl<T, E> From<Result<T, E>> for CResult<T, E> {
fn from(opt: Result<T, E>) -> Self {
match opt {
Ok(t) => Self::Ok(t),
Err(e) => Self::Err(e),
}
}
}
impl<T, E> From<CResult<T, E>> for Result<T, E> {
fn from(opt: CResult<T, E>) -> Self {
match opt {
CResult::Ok(t) => Ok(t),
CResult::Err(e) => Err(e),
}
}
}
impl<T, E> CResult<T, E> {
pub fn is_ok(&self) -> bool {
matches!(*self, CResult::Ok(_))
}
pub fn is_err(&self) -> bool {
matches!(*self, CResult::Err(_))
}
pub fn unwrap(self) -> T
where
E: core::fmt::Debug,
{
Result::from(self).unwrap()
}
pub fn ok(self) -> Option<T> {
match self {
CResult::Ok(x) => Some(x),
_ => None,
}
}
pub fn as_ref(&self) -> Result<&T, &E> {
match *self {
CResult::Ok(ref x) => Ok(x),
CResult::Err(ref e) => Err(e),
}
}
pub fn as_mut(&mut self) -> Result<&mut T, &mut E> {
match *self {
CResult::Ok(ref mut x) => Ok(x),
CResult::Err(ref mut e) => Err(e),
}
}
}
pub trait IntResult<T> {
fn into_int_result(self) -> i32;
fn into_int_out_result(self, ok_out: &mut MaybeUninit<T>) -> i32;
}
impl<T, E: IntError> IntResult<T> for Result<T, E> {
fn into_int_result(self) -> i32 {
into_int_result(self)
}
fn into_int_out_result(self, ok_out: &mut MaybeUninit<T>) -> i32 {
into_int_out_result(self, ok_out)
}
}
pub trait IntError {
fn into_int_err(self) -> NonZeroI32;
fn from_int_err(err: NonZeroI32) -> Self;
}
#[cfg(feature = "std")]
impl IntError for std::io::Error {
fn into_int_err(self) -> NonZeroI32 {
let err = self.raw_os_error().unwrap_or(0);
let err = if err == 0 {
0xffff
} else {
err
};
NonZeroI32::new(err).unwrap()
}
fn from_int_err(err: NonZeroI32) -> Self {
Self::from_raw_os_error(err.get())
}
}
impl IntError for () {
fn into_int_err(self) -> NonZeroI32 {
NonZeroI32::new(1).unwrap()
}
fn from_int_err(_err: NonZeroI32) -> Self {}
}
impl IntError for core::fmt::Error {
fn into_int_err(self) -> NonZeroI32 {
NonZeroI32::new(1).unwrap()
}
fn from_int_err(_err: NonZeroI32) -> Self {
Self
}
}
pub fn into_int_result<T, E: IntError>(res: Result<T, E>) -> i32 {
match res {
Ok(_) => 0,
Err(e) => e.into_int_err().get(),
}
}
pub fn into_int_out_result<T, E: IntError>(res: Result<T, E>, ok_out: &mut MaybeUninit<T>) -> i32 {
match res {
Ok(v) => {
unsafe { ok_out.as_mut_ptr().write(v) };
0
}
Err(e) => e.into_int_err().get(),
}
}
pub unsafe fn from_int_result<T, E: IntError>(res: i32, ok_val: MaybeUninit<T>) -> Result<T, E> {
match NonZeroI32::new(res) {
None => Ok(ok_val.assume_init()),
Some(e) => Err(E::from_int_err(e)),
}
}
pub fn from_int_result_empty<E: IntError>(res: i32) -> Result<(), E> {
match NonZeroI32::new(res) {
None => Ok(()),
Some(e) => Err(E::from_int_err(e)),
}
}