use core::{
cmp::{Ord, Ordering, PartialOrd},
hash, mem,
ops::{Deref, DerefMut},
};
#[derive(Debug)]
#[cfg_attr(feature = "validation", derive(bytecheck::CheckBytes))]
#[repr(u8)]
pub enum ArchivedResult<T, E> {
Ok(T),
Err(E),
}
impl<T, E> ArchivedResult<T, E> {
pub fn ok(self) -> Option<T> {
match self {
ArchivedResult::Ok(value) => Some(value),
ArchivedResult::Err(_) => None,
}
}
pub fn unwrap(self) -> T {
match self {
ArchivedResult::Ok(value) => value,
ArchivedResult::Err(_) => panic!("called `ArchivedResult::unwrap()` on an `Err` value"),
}
}
pub fn unwrap_or_else<F>(self, op: F) -> T
where
F: FnOnce(E) -> T,
{
match self {
ArchivedResult::Ok(t) => t,
ArchivedResult::Err(e) => op(e),
}
}
#[inline]
pub const fn is_ok(&self) -> bool {
matches!(self, ArchivedResult::Ok(_))
}
#[inline]
pub const fn is_err(&self) -> bool {
matches!(self, ArchivedResult::Err(_))
}
#[inline]
pub fn as_ref(&self) -> Result<&T, &E> {
match self {
ArchivedResult::Ok(value) => Ok(value),
ArchivedResult::Err(err) => Err(err),
}
}
#[inline]
pub fn as_mut(&mut self) -> Result<&mut T, &mut E> {
match self {
ArchivedResult::Ok(value) => Ok(value),
ArchivedResult::Err(err) => Err(err),
}
}
#[inline]
pub fn iter(&self) -> Iter<'_, T> {
Iter {
inner: self.as_ref().ok(),
}
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
IterMut {
inner: self.as_mut().ok(),
}
}
}
impl<T: Deref, E> ArchivedResult<T, E> {
#[inline]
pub fn as_deref(&self) -> Result<&<T as Deref>::Target, &E> {
match self {
ArchivedResult::Ok(value) => Ok(value.deref()),
ArchivedResult::Err(err) => Err(err),
}
}
}
impl<T: DerefMut, E> ArchivedResult<T, E> {
#[inline]
pub fn as_deref_mut(&mut self) -> Result<&mut <T as Deref>::Target, &mut E> {
match self {
ArchivedResult::Ok(value) => Ok(value.deref_mut()),
ArchivedResult::Err(err) => Err(err),
}
}
}
pub struct Iter<'a, T> {
inner: Option<&'a T>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
let mut result = None;
mem::swap(&mut self.inner, &mut result);
result
}
}
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.next()
}
}
pub struct IterMut<'a, T> {
inner: Option<&'a mut T>,
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next(&mut self) -> Option<Self::Item> {
let mut result = None;
mem::swap(&mut self.inner, &mut result);
result
}
}
impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.next()
}
}
impl<T: Eq, E: Eq> Eq for ArchivedResult<T, E> {}
impl<T: hash::Hash, E: hash::Hash> hash::Hash for ArchivedResult<T, E> {
#[inline]
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.as_ref().hash(state)
}
}
impl<T: Ord, E: Ord> Ord for ArchivedResult<T, E> {
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
self.as_ref().cmp(&other.as_ref())
}
}
impl<T: PartialEq, E: PartialEq> PartialEq for ArchivedResult<T, E> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.as_ref().eq(&other.as_ref())
}
}
impl<T: PartialOrd, E: PartialOrd> PartialOrd for ArchivedResult<T, E> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.as_ref().partial_cmp(&other.as_ref())
}
}
impl<T, U: PartialEq<T>, E, F: PartialEq<E>> PartialEq<Result<T, E>> for ArchivedResult<U, F> {
#[inline]
fn eq(&self, other: &Result<T, E>) -> bool {
match self {
ArchivedResult::Ok(self_value) => {
if let Ok(other_value) = other {
self_value.eq(other_value)
} else {
false
}
}
ArchivedResult::Err(self_err) => {
if let Err(other_err) = other {
self_err.eq(other_err)
} else {
false
}
}
}
}
}
impl<T: PartialEq<U>, U, E: PartialEq<F>, F> PartialEq<ArchivedResult<T, E>> for Result<U, F> {
#[inline]
fn eq(&self, other: &ArchivedResult<T, E>) -> bool {
other.eq(self)
}
}