#![doc(issue_tracker_base_url = "https://github.com/alilleybrinker/woah/issues/")]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "nightly", feature(try_trait_v2))]
#![cfg_attr(feature = "nightly", feature(try_blocks))]
#![cfg_attr(feature = "nightly", feature(control_flow_enum))]
#![cfg_attr(feature = "nightly", feature(trusted_len))]
#![cfg_attr(feature = "nightly", feature(never_type))]
#![cfg_attr(feature = "nightly", doc(test(attr(feature(try_trait_v2)))))]
#![cfg_attr(feature = "nightly", doc(test(attr(feature(try_blocks)))))]
#![cfg_attr(feature = "nightly", doc(test(attr(feature(control_flow_enum)))))]
#![cfg_attr(feature = "nightly", doc(test(attr(feature(trusted_len)))))]
#![cfg_attr(feature = "nightly", doc(test(attr(feature(never_type)))))]
#![deny(clippy::all)]
#![deny(clippy::cargo)]
#![warn(missing_debug_implementations)]
#![warn(missing_copy_implementations)]
use crate::Result::{FatalErr, LocalErr, Success};
#[cfg(feature = "nightly")]
use core::convert::Infallible;
use core::convert::{From, Into};
use core::fmt::Debug;
#[cfg(feature = "nightly")]
use core::iter::FromIterator;
#[cfg(feature = "nightly")]
use core::iter::Product;
#[cfg(feature = "nightly")]
use core::iter::Sum;
#[cfg(feature = "nightly")]
use core::iter::TrustedLen;
use core::iter::{DoubleEndedIterator, FusedIterator, Iterator};
#[cfg(feature = "nightly")]
use core::ops::ControlFlow;
use core::ops::{Deref, DerefMut};
#[cfg(feature = "nightly")]
use core::ops::{FromResidual, Try};
use core::result::{Result as StdResult, Result::Err, Result::Ok};
#[cfg(feature = "either")]
use either::Either::{self, Left, Right};
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "std")]
use std::process::{ExitCode, Termination};
pub mod prelude {
pub use crate::{Result, Result::FatalErr, Result::LocalErr, Result::Success};
pub use core::result::Result as StdResult;
#[cfg(feature = "nightly")]
pub use core::ops::{FromResidual, Try};
#[cfg(feature = "nightly")]
pub use core::ops::ControlFlow;
#[cfg(feature = "std")]
pub use std::process::Termination;
#[cfg(feature = "nightly")]
pub use core::iter::FromIterator;
#[cfg(feature = "nightly")]
pub use core::iter::Product;
#[cfg(feature = "nightly")]
pub use core::iter::Sum;
#[cfg(feature = "nightly")]
pub use core::iter::TrustedLen;
}
pub mod docs {
}
#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
#[must_use = "this `Result` may be a `LocalErr`, which should be handled, or a `FatalErr`, which should be propagated"]
pub enum Result<T, L, F> {
Success(T),
LocalErr(L),
FatalErr(F),
}
#[cfg(feature = "nightly")]
impl<T, L, F> FromResidual for Result<T, L, F> {
#[inline]
fn from_residual(residual: StdResult<Infallible, F>) -> Self {
Result::FatalErr(residual.unwrap_err())
}
}
#[cfg(feature = "nightly")]
impl<T, L, F> Try for Result<T, L, F> {
type Output = StdResult<T, L>;
type Residual = StdResult<Infallible, F>;
#[inline]
fn from_output(output: StdResult<T, L>) -> Self {
From::from(output)
}
#[inline]
fn branch(self) -> ControlFlow<StdResult<Infallible, F>, StdResult<T, L>> {
match self {
Result::Success(t) => ControlFlow::Continue(Ok(t)),
Result::LocalErr(l) => ControlFlow::Continue(Err(l)),
Result::FatalErr(f) => ControlFlow::Break(Err(f)),
}
}
}
impl<T, L, F> Result<T, L, F> {
#[inline]
pub fn into_result(self) -> StdResult<StdResult<T, L>, F> {
self.into()
}
#[inline]
pub fn from_result(ok: StdResult<T, L>) -> Self {
match ok {
Ok(t) => Success(t),
Err(err) => LocalErr(err),
}
}
#[inline]
pub fn from_success(val: T) -> Self {
Success(val)
}
#[inline]
pub fn from_local_err(err: L) -> Self {
LocalErr(err)
}
#[inline]
pub fn from_fatal_error(err: F) -> Self {
FatalErr(err)
}
#[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"]
#[inline]
pub fn is_success(&self) -> bool {
matches!(self, Success(_))
}
#[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"]
#[inline]
pub fn is_err(&self) -> bool {
!self.is_success()
}
#[must_use = "if you intended to assert that this is local_err, consider `.unwrap_local_err()` instead"]
#[inline]
pub fn is_local_err(&self) -> bool {
matches!(self, LocalErr(_))
}
#[must_use = "if you intended to assert that this is fatal_err, consider `.unwrap_fatal_err()` instead"]
#[inline]
pub fn is_fatal_err(&self) -> bool {
matches!(self, FatalErr(_))
}
#[must_use]
#[inline]
pub fn contains<U>(&self, x: &U) -> bool
where
U: PartialEq<T>,
{
matches!(self, Success(t) if *x == *t)
}
#[cfg(feature = "either")]
#[must_use]
#[inline]
pub fn contains_err<U, Y>(&self, e: Either<&U, &Y>) -> bool
where
U: PartialEq<L>,
Y: PartialEq<F>,
{
matches!((self, e), (LocalErr(err), Left(e)) if *e == *err)
|| matches!((self, e), (FatalErr(err), Right(e)) if *e == *err)
}
#[must_use]
#[inline]
pub fn contains_local_err<E>(&self, e: &E) -> bool
where
E: PartialEq<L>,
{
matches!(self, LocalErr(err) if *e == *err)
}
#[must_use]
#[inline]
pub fn contains_fatal_err<E>(&self, e: &E) -> bool
where
E: PartialEq<F>,
{
matches!(self, FatalErr(err) if *e == *err)
}
#[inline]
pub fn success(self) -> Option<T> {
match self {
Success(t) => Some(t),
_ => None,
}
}
#[cfg(feature = "either")]
#[inline]
pub fn err(self) -> Option<Either<L, F>> {
match self {
LocalErr(err) => Some(Left(err)),
FatalErr(err) => Some(Right(err)),
_ => None,
}
}
#[inline]
pub fn local_err(self) -> Option<L> {
match self {
LocalErr(err) => Some(err),
_ => None,
}
}
#[inline]
pub fn fatal_err(self) -> Option<F> {
match self {
FatalErr(err) => Some(err),
_ => None,
}
}
#[inline]
pub fn as_ref(&self) -> Result<&T, &L, &F> {
match self {
Success(t) => Success(t),
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err),
}
}
#[inline]
pub fn as_mut(&mut self) -> Result<&mut T, &mut L, &mut F> {
match self {
Success(t) => Success(t),
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err),
}
}
#[inline]
pub fn map<U, S>(self, f: U) -> Result<S, L, F>
where
U: FnOnce(T) -> S,
{
match self {
Success(t) => Success(f(t)),
LocalErr(e) => LocalErr(e),
FatalErr(e) => FatalErr(e),
}
}
#[inline]
pub fn map_or<U, G>(self, default: U, f: G) -> U
where
G: FnOnce(T) -> U,
{
match self {
Success(t) => f(t),
_ => default,
}
}
#[inline]
pub fn map_or_else<U, LD, FD, G>(self, default_local: LD, default_fatal: FD, f: G) -> U
where
LD: FnOnce(L) -> U,
FD: FnOnce(F) -> U,
G: FnOnce(T) -> U,
{
match self {
Success(t) => f(t),
LocalErr(err) => default_local(err),
FatalErr(err) => default_fatal(err),
}
}
#[cfg(feature = "either")]
#[inline]
pub fn map_err<U, M, G>(self, f: U) -> Result<T, M, G>
where
U: FnOnce(Either<L, F>) -> Either<M, G>,
{
match self {
Success(t) => Success(t),
LocalErr(err) => match f(Left(err)) {
Left(err) => LocalErr(err),
Right(err) => FatalErr(err),
},
FatalErr(err) => match f(Right(err)) {
Left(err) => LocalErr(err),
Right(err) => FatalErr(err),
},
}
}
#[inline]
pub fn map_local_err<U, S>(self, f: U) -> Result<T, S, F>
where
U: FnOnce(L) -> S,
{
match self {
Success(t) => Success(t),
LocalErr(e) => LocalErr(f(e)),
FatalErr(e) => FatalErr(e),
}
}
#[inline]
pub fn map_fatal_err<U, S>(self, f: U) -> Result<T, L, S>
where
U: FnOnce(F) -> S,
{
match self {
Success(t) => Success(t),
LocalErr(e) => LocalErr(e),
FatalErr(e) => FatalErr(f(e)),
}
}
#[inline]
pub fn iter(&self) -> Iter<T> {
let inner = match self {
Success(t) => Some(t),
_ => None,
};
Iter { inner }
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<T> {
let inner = match self {
Success(t) => Some(t),
_ => None,
};
IterMut { inner }
}
#[inline]
pub fn and<U>(self, res: Result<U, L, F>) -> Result<U, L, F> {
match self {
Success(_) => res,
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err),
}
}
#[inline]
pub fn and_then<U, G>(self, op: G) -> Result<U, L, F>
where
G: FnOnce(T) -> Result<U, L, F>,
{
match self {
Success(t) => op(t),
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err),
}
}
#[inline]
pub fn or<M, G>(
self,
res_local: Result<T, M, G>,
res_fatal: Result<T, M, G>,
) -> Result<T, M, G> {
match self {
Success(t) => Success(t),
LocalErr(_) => res_local,
FatalErr(_) => res_fatal,
}
}
#[inline]
pub fn or_local<M>(self, res: Result<T, M, F>) -> Result<T, M, F> {
match self {
Success(t) => Success(t),
LocalErr(_) => res,
FatalErr(err) => FatalErr(err),
}
}
#[inline]
pub fn or_fatal<G>(self, res: Result<T, L, G>) -> Result<T, L, G> {
match self {
Success(t) => Success(t),
LocalErr(err) => LocalErr(err),
FatalErr(_) => res,
}
}
#[inline]
pub fn or_else<O, P, M, G>(self, op_local: O, op_fatal: P) -> Result<T, M, G>
where
O: FnOnce(L) -> Result<T, M, G>,
P: FnOnce(F) -> Result<T, M, G>,
{
match self {
Success(t) => Success(t),
LocalErr(err) => op_local(err),
FatalErr(err) => op_fatal(err),
}
}
#[inline]
pub fn or_else_local<O, M>(self, op: O) -> Result<T, M, F>
where
O: FnOnce(L) -> Result<T, M, F>,
{
match self {
Success(t) => Success(t),
LocalErr(err) => op(err),
FatalErr(err) => FatalErr(err),
}
}
#[inline]
pub fn or_else_fatal<O, G>(self, op: O) -> Result<T, L, G>
where
O: FnOnce(F) -> Result<T, L, G>,
{
match self {
Success(t) => Success(t),
LocalErr(err) => LocalErr(err),
FatalErr(err) => op(err),
}
}
#[inline]
pub fn unwrap_or(self, alt: T) -> T {
match self {
Success(t) => t,
_ => alt,
}
}
#[inline]
pub fn unwrap_or_else<M, G>(self, local_op: M, fatal_op: G) -> T
where
M: FnOnce(L) -> T,
G: FnOnce(F) -> T,
{
match self {
Success(t) => t,
LocalErr(err) => local_op(err),
FatalErr(err) => fatal_op(err),
}
}
}
impl<'a, T, L, F> Result<&'a T, L, F>
where
T: Copy,
{
#[inline]
pub fn copied(self) -> Result<T, L, F> {
match self {
Success(t) => Success(*t),
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err),
}
}
}
impl<'a, T, L, F> Result<&'a mut T, L, F>
where
T: Copy,
{
#[inline]
pub fn copied(self) -> Result<T, L, F> {
match self {
Success(t) => Success(*t),
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err),
}
}
}
impl<'a, T, L, F> Result<&'a T, L, F>
where
T: Clone,
{
#[inline]
pub fn cloned(self) -> Result<T, L, F> {
match self {
Success(t) => Success(t.clone()),
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err),
}
}
}
impl<'a, T, L, F> Result<&'a mut T, L, F>
where
T: Clone,
{
#[inline]
pub fn cloned(self) -> Result<T, L, F> {
match self {
Success(t) => Success(t.clone()),
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err),
}
}
}
impl<T, L, F> Result<T, L, F>
where
L: Debug,
F: Debug,
{
#[inline]
pub fn unwrap(self) -> T {
match self {
Success(t) => t,
LocalErr(err) => panic!("{:?}", err),
FatalErr(err) => panic!("{:?}", err),
}
}
#[inline]
pub fn expect(self, msg: &str) -> T {
match self {
Success(t) => t,
LocalErr(_) => panic!("{}", msg),
FatalErr(_) => panic!("{}", msg),
}
}
}
#[cfg(feature = "either")]
impl<T, L, F> Result<T, L, F>
where
T: Debug,
L: Debug,
F: Debug,
{
#[inline]
pub fn unwrap_err(self) -> Either<L, F> {
match self {
Success(t) => panic!("{:?}", t),
LocalErr(err) => Left(err),
FatalErr(err) => Right(err),
}
}
#[inline]
pub fn expect_err(self, msg: &str) -> Either<L, F> {
match self {
Success(_) => panic!("{}", msg),
LocalErr(err) => Left(err),
FatalErr(err) => Right(err),
}
}
}
impl<T, L, F> Result<T, L, F>
where
T: Debug,
F: Debug,
{
#[inline]
pub fn unwrap_local_err(self) -> L {
match self {
Success(t) => panic!("{:?}", t),
LocalErr(err) => err,
FatalErr(err) => panic!("{:?}", err),
}
}
#[inline]
pub fn expect_local_err(self, msg: &str) -> L {
match self {
Success(_) => panic!("{}", msg),
LocalErr(err) => err,
FatalErr(_) => panic!("{}", msg),
}
}
}
impl<T, L, F> Result<T, L, F>
where
T: Debug,
L: Debug,
{
#[inline]
pub fn unwrap_fatal_err(self) -> F {
match self {
Success(t) => panic!("{:?}", t),
LocalErr(err) => panic!("{:?}", err),
FatalErr(err) => err,
}
}
#[inline]
pub fn expect_fatal_err(self, msg: &str) -> F {
match self {
Success(_) => panic!("{}", msg),
LocalErr(_) => panic!("{}", msg),
FatalErr(err) => err,
}
}
}
impl<T, L, F> Result<T, L, F>
where
T: Default,
{
#[inline]
pub fn unwrap_or_default(self) -> T {
match self {
Success(t) => t,
_ => T::default(),
}
}
#[inline]
pub fn into_result_default(self) -> StdResult<T, F> {
match self {
Success(t) => Ok(t),
LocalErr(_) => Ok(T::default()),
FatalErr(err) => Err(err),
}
}
}
#[cfg(feature = "nightly")]
impl<T, L, F> Result<T, L, F>
where
L: Into<!>,
F: Into<!>,
{
#[inline]
pub fn into_success(self) -> T {
match self {
Success(t) => t,
LocalErr(err) => err.into(),
FatalErr(err) => err.into(),
}
}
}
impl<T, L, F> Result<T, L, F>
where
T: Deref,
{
#[inline]
pub fn as_deref(&self) -> Result<&<T as Deref>::Target, &L, &F> {
match self {
Success(t) => Success(t.deref()),
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err),
}
}
}
impl<T, L, F> Result<T, L, F>
where
L: Deref,
F: Deref,
{
#[inline]
pub fn as_deref_err(&self) -> Result<&T, &<L as Deref>::Target, &<F as Deref>::Target> {
match self {
Success(t) => Success(t),
LocalErr(err) => LocalErr(err.deref()),
FatalErr(err) => FatalErr(err.deref()),
}
}
}
impl<T, L, F> Result<T, L, F>
where
L: Deref,
{
#[inline]
pub fn as_deref_local_err(&self) -> Result<&T, &<L as Deref>::Target, &F> {
match self {
Success(t) => Success(t),
LocalErr(err) => LocalErr(err.deref()),
FatalErr(err) => FatalErr(err),
}
}
}
impl<T, L, F> Result<T, L, F>
where
F: Deref,
{
#[inline]
pub fn as_deref_fatal_err(&self) -> Result<&T, &L, &<F as Deref>::Target> {
match self {
Success(t) => Success(t),
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err.deref()),
}
}
}
impl<T, L, F> Result<T, L, F>
where
T: DerefMut,
{
#[inline]
pub fn as_deref_mut(&mut self) -> Result<&mut <T as Deref>::Target, &mut L, &mut F> {
match self {
Success(t) => Success(t.deref_mut()),
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err),
}
}
}
impl<T, L, F> Result<T, L, F>
where
L: DerefMut,
F: DerefMut,
{
#[inline]
pub fn as_deref_mut_err(
&mut self,
) -> Result<&mut T, &mut <L as Deref>::Target, &mut <F as Deref>::Target> {
match self {
Success(t) => Success(t),
LocalErr(err) => LocalErr(err.deref_mut()),
FatalErr(err) => FatalErr(err.deref_mut()),
}
}
}
impl<T, L, F> Result<T, L, F>
where
L: DerefMut,
{
#[inline]
pub fn as_deref_mut_local_err(&mut self) -> Result<&mut T, &mut <L as Deref>::Target, &mut F> {
match self {
Success(t) => Success(t),
LocalErr(err) => LocalErr(err.deref_mut()),
FatalErr(err) => FatalErr(err),
}
}
}
impl<T, L, F> Result<T, L, F>
where
F: DerefMut,
{
#[inline]
pub fn as_deref_mut_fatal_err(&mut self) -> Result<&mut T, &mut L, &mut <F as Deref>::Target> {
match self {
Success(t) => Success(t),
LocalErr(err) => LocalErr(err),
FatalErr(err) => FatalErr(err.deref_mut()),
}
}
}
impl<T, L, F> Result<Option<T>, L, F> {
#[inline]
pub fn transpose(self) -> Option<Result<T, L, F>> {
match self {
Success(Some(t)) => Some(Success(t)),
Success(None) => None,
LocalErr(err) => Some(LocalErr(err)),
FatalErr(err) => Some(FatalErr(err)),
}
}
}
impl<T, L, F> Clone for Result<T, L, F>
where
T: Clone,
L: Clone,
F: Clone,
{
#[inline]
fn clone(&self) -> Result<T, L, F> {
match self {
Success(t) => Success(t.clone()),
LocalErr(err) => LocalErr(err.clone()),
FatalErr(err) => FatalErr(err.clone()),
}
}
#[inline]
fn clone_from(&mut self, source: &Result<T, L, F>) {
match (self, source) {
(Success(to), Success(from)) => to.clone_from(from),
(LocalErr(to), LocalErr(from)) => to.clone_from(from),
(FatalErr(to), FatalErr(from)) => to.clone_from(from),
(to, from) => *to = from.clone(),
}
}
}
#[cfg(feature = "nightly")]
impl<A, V, L, F> FromIterator<Result<A, L, F>> for Result<V, L, F>
where
V: FromIterator<A>,
{
#[inline]
fn from_iter<I>(iter: I) -> Result<V, L, F>
where
I: IntoIterator<Item = Result<A, L, F>>,
{
process_results(iter.into_iter(), |i| i.collect())
}
}
impl<'a, T, L, F> IntoIterator for &'a mut Result<T, L, F> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
#[inline]
fn into_iter(self) -> IterMut<'a, T> {
self.iter_mut()
}
}
impl<'a, T, L, F> IntoIterator for &'a Result<T, L, F> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
#[inline]
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
impl<T, L, F> IntoIterator for Result<T, L, F> {
type Item = T;
type IntoIter = IntoIter<T>;
#[inline]
fn into_iter(self) -> IntoIter<T> {
IntoIter {
inner: self.success(),
}
}
}
#[cfg(feature = "nightly")]
impl<T, U, L, F> Product<Result<U, L, F>> for Result<T, L, F>
where
T: Product<U>,
{
#[inline]
fn product<I>(iter: I) -> Result<T, L, F>
where
I: Iterator<Item = Result<U, L, F>>,
{
process_results(iter, |i| i.product())
}
}
#[cfg(feature = "nightly")]
impl<T, U, L, F> Sum<Result<U, L, F>> for Result<T, L, F>
where
T: Sum<U>,
{
#[inline]
fn sum<I>(iter: I) -> Result<T, L, F>
where
I: Iterator<Item = Result<U, L, F>>,
{
process_results(iter, |i| i.sum())
}
}
#[cfg(feature = "std")]
impl<L, F> Termination for Result<(), L, F>
where
L: Debug,
F: Debug,
{
#[inline]
fn report(self) -> ExitCode {
match self {
Success(()) => ().report(),
LocalErr(err) => {
eprintln!("Error: {:?}", err);
ExitCode::FAILURE.report()
}
FatalErr(err) => {
eprintln!("Error: {:?}", err);
ExitCode::FAILURE.report()
}
}
}
}
#[cfg(all(feature = "nightly", feature = "std"))]
impl<L, F> Termination for Result<!, L, F>
where
L: Debug,
F: Debug,
{
#[inline]
fn report(self) -> ExitCode {
match self {
LocalErr(err) => {
eprintln!("Error: {:?}", err);
ExitCode::FAILURE.report()
}
FatalErr(err) => {
eprintln!("Error: {:?}", err);
ExitCode::FAILURE.report()
}
Success(t) => t,
}
}
}
#[derive(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()
}
}
#[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<'a, T> FusedIterator for Iter<'a, T> {}
#[cfg(feature = "nightly")]
unsafe impl<'a, T> TrustedLen for Iter<'a, T> {}
#[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<'a, T> FusedIterator for IterMut<'a, T> {}
#[cfg(feature = "nightly")]
unsafe impl<'a, T> TrustedLen for IterMut<'a, T> {}
#[cfg(feature = "nightly")]
pub(crate) struct ResultShunt<'a, I, L, F> {
iter: I,
error: &'a mut Result<(), L, F>,
}
#[cfg(feature = "nightly")]
#[inline]
pub(crate) fn process_results<I, T, L, F, G, U>(iter: I, mut f: G) -> Result<U, L, F>
where
I: Iterator<Item = Result<T, L, F>>,
for<'a> G: FnMut(ResultShunt<'a, I, L, F>) -> U,
{
let mut error = Success(());
let shunt = ResultShunt {
iter,
error: &mut error,
};
let value = f(shunt);
error.map(|()| value)
}
#[cfg(feature = "nightly")]
impl<I, T, L, F> Iterator for ResultShunt<'_, I, L, F>
where
I: Iterator<Item = Result<T, L, F>>,
{
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.find(|_| true)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
if self.error.is_err() {
(0, Some(0))
} else {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
#[inline]
fn try_fold<B, G, R>(&mut self, init: B, mut f: G) -> R
where
G: FnMut(B, Self::Item) -> R,
R: Try<Output = B>,
{
let error = &mut *self.error;
into_try(self.iter.try_fold(init, |acc, x| match x {
Success(x) => from_try(f(acc, x)),
LocalErr(l) => {
*error = LocalErr(l);
ControlFlow::Break(try { acc })
}
FatalErr(f) => {
*error = FatalErr(f);
ControlFlow::Break(try { acc })
}
}))
}
}
#[cfg(feature = "nightly")]
#[inline]
fn from_try<R: Try>(r: R) -> ControlFlow<R, R::Output> {
match R::branch(r) {
ControlFlow::Continue(v) => ControlFlow::Continue(v),
ControlFlow::Break(v) => ControlFlow::Break(R::from_residual(v)),
}
}
#[cfg(feature = "nightly")]
#[inline]
fn into_try<R: Try>(cf: ControlFlow<R, R::Output>) -> R {
match cf {
ControlFlow::Continue(v) => R::from_output(v),
ControlFlow::Break(v) => v,
}
}
impl<T, L, F> From<StdResult<T, L>> for Result<T, L, F> {
fn from(result: StdResult<T, L>) -> Result<T, L, F> {
match result {
Ok(t) => Success(t),
Err(l) => LocalErr(l),
}
}
}
impl<T, L, F> From<StdResult<StdResult<T, L>, F>> for Result<T, L, F> {
fn from(result: StdResult<StdResult<T, L>, F>) -> Result<T, L, F> {
match result {
Ok(inner) => match inner {
Ok(ok) => Success(ok),
Err(err) => LocalErr(err),
},
Err(err) => FatalErr(err),
}
}
}
impl<T, L, F> From<Result<T, L, F>> for StdResult<StdResult<T, L>, F> {
fn from(other: Result<T, L, F>) -> StdResult<StdResult<T, L>, F> {
match other {
Success(ok) => Ok(Ok(ok)),
LocalErr(err) => Ok(Err(err)),
FatalErr(err) => Err(err),
}
}
}
#[cfg(feature = "serde")]
impl<T, L, F> Serialize for Result<T, L, F>
where
T: Serialize,
L: Serialize,
F: Serialize,
{
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where
S: Serializer,
{
self.as_ref().into_result().serialize(serializer)
}
}
#[cfg(feature = "serde")]
impl<'de, T, L, F> Deserialize<'de> for Result<T, L, F>
where
T: Deserialize<'de>,
L: Deserialize<'de>,
F: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> StdResult<Self, D::Error>
where
D: Deserializer<'de>,
{
let result: StdResult<StdResult<T, L>, F> = StdResult::deserialize(deserializer)?;
let result: Result<T, L, F> = result.into();
Ok(result)
}
}