extern crate alloc;
use core::convert;
use core::convert::Infallible;
use core::error::Error;
use core::fmt;
use core::hint;
use core::iter::FusedIterator;
use core::ops::ControlFlow;
use core::ops::Deref;
use core::ops::DerefMut;
use core::ops::FromResidual;
use core::ops::Residual;
use core::ops::Try;
use crate::data::Metadata;
use crate::dlog;
use crate::trace::{TraceRecord, Traceable};
#[macro_export]
macro_rules! err {
($enum_error:expr) => {
Err(Ec::new($enum_error))
};
}
#[derive(PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
pub enum Result<T, E> {
Ok(T),
Err(E),
}
impl<T, E, F> FromResidual<core::result::Result<Infallible, E>> for Result<T, F>
where
E: fmt::Display + Error,
F: From<E> + Error + Traceable + Metadata,
{
#[track_caller]
fn from_residual(r: core::result::Result<Infallible, E>) -> Self {
match r {
core::result::Result::Err(err) => {
let mut e: F = err.into();
let rec = TraceRecord::new(
&e,
e.trace_ref()
.expect("Trace must be available in 'FromResidual'"),
);
dlog!(
"insert ({}) to ({})\n\tin {}",
core::any::type_name::<E>(),
rec.name,
rec.location
);
e.insert(rec);
Self::Err(e)
}
}
}
}
impl<T, E, F> FromResidual<Result<!, E>> for Result<T, F>
where
E: fmt::Display + Error + Traceable + Metadata,
F: From<E> + Error + Traceable + Metadata,
{
#[track_caller]
fn from_residual(r: Result<!, E>) -> Self {
match r {
Result::Err(err) => {
let _err_name = err.name();
let mut e: F = err.into();
let rec = TraceRecord::new(
&e,
e.trace_ref()
.expect("Trace must be available in 'FromResidual'"),
);
dlog!(
"insert ({}) to ({})\n\tin {}",
_err_name,
rec.name,
rec.location
);
e.insert(rec);
Self::Err(e)
}
}
}
}
impl<T, E, F> FromResidual<Result<!, E>> for core::result::Result<T, F>
where
E: fmt::Display + Error + Traceable + Metadata,
F: From<E>,
{
#[track_caller]
fn from_residual(r: Result<!, E>) -> Self {
match r {
Result::Err(mut e) => {
let mut rec = TraceRecord::new(
&e,
e.trace_ref()
.expect("Trace must be available in 'FromResidual'"),
);
rec.name = core::any::type_name::<F>();
dlog!(
"insert ({}) to ({})\n\tin {}",
e.name(),
rec.name,
rec.location
);
e.insert(rec);
Self::Err(e.into())
}
}
}
}
impl<T, E> Try for Result<T, E>
where
E: fmt::Display + Error + Traceable + Metadata,
{
type Output = T;
type Residual = Result<!, E>;
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self {
Self::Ok(o) => ControlFlow::Continue(o),
Self::Err(e) => ControlFlow::Break(Result::Err(e)),
}
}
fn from_output(o: Self::Output) -> Self {
Self::Ok(o)
}
}
impl<T, E> Residual<T> for Result<!, E>
where
E: fmt::Display + Error + Traceable + Metadata,
{
type TryType = Result<T, E>;
}
impl<T, E> Result<T, E> {
#[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"]
#[inline]
pub const fn is_ok(&self) -> bool {
matches!(*self, Self::Ok(_))
}
#[must_use]
#[inline]
pub fn is_ok_and(self, f: impl FnOnce(T) -> bool) -> bool {
match self {
Self::Err(_) => false,
Self::Ok(x) => f(x),
}
}
#[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"]
#[inline]
pub const fn is_err(&self) -> bool {
!self.is_ok()
}
#[must_use]
#[inline]
pub fn is_err_and(self, f: impl FnOnce(E) -> bool) -> bool {
match self {
Self::Ok(_) => false,
Self::Err(e) => f(e),
}
}
#[inline]
pub fn ok(self) -> Option<T> {
match self {
Self::Ok(x) => Some(x),
Self::Err(_) => None,
}
}
#[inline]
pub fn err(self) -> Option<E> {
match self {
Self::Ok(_) => None,
Self::Err(x) => Some(x),
}
}
#[inline]
pub const fn as_ref(&self) -> Result<&T, &E> {
match *self {
Self::Ok(ref x) => Result::<&T, &E>::Ok(x),
Self::Err(ref x) => Result::<&T, &E>::Err(x),
}
}
#[inline]
pub const fn as_mut(&mut self) -> Result<&mut T, &mut E> {
match *self {
Self::Ok(ref mut x) => Result::<&mut T, &mut E>::Ok(x),
Self::Err(ref mut x) => Result::<&mut T, &mut E>::Err(x),
}
}
#[inline]
pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> Result<U, E> {
match self {
Self::Ok(t) => Result::<U, E>::Ok(op(t)),
Self::Err(e) => Result::<U, E>::Err(e),
}
}
#[inline]
#[must_use = "if you don't need the returned value, use `if let` instead"]
pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
match self {
Self::Ok(t) => f(t),
Self::Err(_) => default,
}
}
#[inline]
pub fn map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
match self {
Self::Ok(t) => f(t),
Self::Err(e) => default(e),
}
}
#[inline]
pub fn map_err<F, O: FnOnce(E) -> F>(self, op: O) -> Result<T, F> {
match self {
Self::Ok(t) => Result::<T, F>::Ok(t),
Self::Err(e) => Result::<T, F>::Err(op(e)),
}
}
#[inline]
pub fn inspect<F: FnOnce(&T)>(self, f: F) -> Self {
if let Self::Ok(ref t) = self {
f(t);
}
self
}
#[inline]
pub fn inspect_err<F: FnOnce(&E)>(self, f: F) -> Self {
if let Self::Err(ref e) = self {
f(e);
}
self
}
#[inline]
pub fn as_deref(&self) -> Result<&T::Target, &E>
where
T: Deref,
{
self.as_ref().map(|t| t.deref())
}
#[inline]
pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E>
where
T: DerefMut,
{
self.as_mut().map(|t| t.deref_mut())
}
#[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(),
}
}
#[inline]
#[track_caller]
pub fn expect(self, msg: &str) -> T
where
E: fmt::Debug,
{
match self {
Self::Ok(t) => t,
Self::Err(e) => unwrap_failed(msg, &e),
}
}
#[inline(always)]
#[track_caller]
pub fn unwrap(self) -> T
where
E: fmt::Debug,
{
match self {
Self::Ok(t) => t,
Self::Err(e) => unwrap_failed("called `Result::unwrap()` on an `Err` value", &e),
}
}
#[inline]
pub fn unwrap_or_default(self) -> T
where
T: Default,
{
match self {
Self::Ok(x) => x,
Self::Err(_) => Default::default(),
}
}
#[inline]
#[track_caller]
pub fn expect_err(self, msg: &str) -> E
where
T: fmt::Debug,
{
match self {
Self::Ok(t) => unwrap_failed(msg, &t),
Self::Err(e) => e,
}
}
#[inline]
#[track_caller]
pub fn unwrap_err(self) -> E
where
T: fmt::Debug,
{
match self {
Self::Ok(t) => unwrap_failed("called `Result::unwrap_err()` on an `Ok` value", &t),
Self::Err(e) => e,
}
}
#[inline]
pub fn into_ok(self) -> T
where
E: Into<!>,
{
match self {
Self::Ok(x) => x,
Self::Err(e) => e.into(),
}
}
#[inline]
pub fn into_err(self) -> E
where
T: Into<!>,
{
match self {
Self::Ok(x) => x.into(),
Self::Err(e) => e,
}
}
#[inline]
pub fn and<U>(self, res: Result<U, E>) -> Result<U, E> {
match self {
Self::Ok(_) => res,
Self::Err(e) => Result::<U, E>::Err(e),
}
}
#[inline]
pub fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E> {
match self {
Self::Ok(t) => op(t),
Self::Err(e) => Result::<U, E>::Err(e),
}
}
#[inline]
pub fn or<F>(self, res: Result<T, F>) -> Result<T, F> {
match self {
Self::Ok(v) => Result::<T, F>::Ok(v),
Self::Err(_) => res,
}
}
#[inline]
pub fn or_else<F, O: FnOnce(E) -> Result<T, F>>(self, op: O) -> Result<T, F> {
match self {
Self::Ok(t) => Result::<T, F>::Ok(t),
Self::Err(e) => op(e),
}
}
#[inline]
pub fn unwrap_or(self, default: T) -> T {
match self {
Self::Ok(t) => t,
Self::Err(_) => default,
}
}
#[inline]
#[track_caller]
pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, op: F) -> T {
match self {
Self::Ok(t) => t,
Self::Err(e) => op(e),
}
}
#[inline]
#[track_caller]
pub unsafe fn unwrap_unchecked(self) -> T {
debug_assert!(self.is_ok());
match self {
Self::Ok(t) => t,
Self::Err(_) => unsafe { hint::unreachable_unchecked() },
}
}
#[inline]
#[track_caller]
pub unsafe fn unwrap_err_unchecked(self) -> E {
debug_assert!(self.is_err());
match self {
Self::Ok(_) => unsafe { hint::unreachable_unchecked() },
Self::Err(e) => e,
}
}
}
impl<T, E> Result<&T, E> {
#[inline]
pub fn copied(self) -> Result<T, E>
where
T: Copy,
{
self.map(|&t| t)
}
#[inline]
pub fn cloned(self) -> Result<T, E>
where
T: Clone,
{
self.map(|t| {
let g = t.clone();
g
})
}
}
impl<T, E> Result<&mut T, E> {
#[inline]
pub fn copied(self) -> Result<T, E>
where
T: Copy,
{
self.map(|&mut t| t)
}
#[inline]
pub fn cloned(self) -> Result<T, E>
where
T: Clone,
{
self.map(|t| t.clone())
}
}
#[inline(never)]
#[cold]
#[track_caller]
fn unwrap_failed(msg: &str, error: &dyn fmt::Debug) -> ! {
panic!("{msg}: {error:?}")
}
impl<T, E> Result<Option<T>, E> {
#[inline]
pub fn transpose(self) -> Option<Result<T, E>> {
match self {
Result::<Option<T>, E>::Ok(Some(x)) => Some(Result::<T, E>::Ok(x)),
Result::<Option<T>, E>::Ok(None) => None,
Result::<Option<T>, E>::Err(e) => Some(Result::<T, E>::Err(e)),
}
}
}
impl<T, E> Result<Result<T, E>, E> {
#[inline]
pub fn flatten(self) -> Result<T, E> {
self.and_then(convert::identity)
}
}
impl<T, E> Clone for Result<T, E>
where
T: Clone,
E: Clone,
{
#[inline]
fn clone(&self) -> Self {
match self {
Result::Ok(x) => Result::Ok(x.clone()),
Result::Err(x) => Result::Err(x.clone()),
}
}
#[inline]
fn clone_from(&mut self, source: &Self) {
match (self, source) {
(Result::Ok(to), Result::Ok(from)) => to.clone_from(from),
(Result::Err(to), Result::Err(from)) => to.clone_from(from),
(to, from) => *to = from.clone(),
}
}
}
impl<T, E> IntoIterator for Result<T, E> {
type Item = T;
type IntoIter = IntoIter<T>;
#[inline]
fn into_iter(self) -> IntoIter<T> {
IntoIter { inner: self.ok() }
}
}
impl<'a, T, E> IntoIterator for &'a Result<T, E> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
impl<'a, T, E> IntoIterator for &'a mut Result<T, E> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> IterMut<'a, T> {
self.iter_mut()
}
}
#[derive(Debug)]
pub struct Iter<'a, T: 'a> {
inner: Option<&'a T>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
#[inline]
fn next(&mut self) -> Option<&'a T> {
self.inner.take()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let n = if self.inner.is_some() { 1 } else { 0 };
(n, Some(n))
}
}
impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a T> {
self.inner.take()
}
}
impl<T> ExactSizeIterator for Iter<'_, T> {}
impl<T> FusedIterator for Iter<'_, T> {}
impl<T> Clone for Iter<'_, T> {
#[inline]
fn clone(&self) -> Self {
Iter { inner: self.inner }
}
}
#[derive(Debug)]
pub struct IterMut<'a, T: 'a> {
inner: Option<&'a mut T>,
}
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
#[inline]
fn next(&mut self) -> Option<&'a mut T> {
self.inner.take()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let n = if self.inner.is_some() { 1 } else { 0 };
(n, Some(n))
}
}
impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a mut T> {
self.inner.take()
}
}
impl<T> ExactSizeIterator for IterMut<'_, T> {}
impl<T> FusedIterator for IterMut<'_, T> {}
#[derive(Clone, Debug)]
pub struct IntoIter<T> {
inner: Option<T>,
}
impl<T> Iterator for IntoIter<T> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<T> {
self.inner.take()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let n = if self.inner.is_some() { 1 } else { 0 };
(n, Some(n))
}
}
impl<T> DoubleEndedIterator for IntoIter<T> {
#[inline]
fn next_back(&mut self) -> Option<T> {
self.inner.take()
}
}
impl<T> ExactSizeIterator for IntoIter<T> {}
impl<T> FusedIterator for IntoIter<T> {}