#![doc = include_str!("../README.md")]
#![no_std]
use core::{
ops::{Deref, DerefMut},
option::IntoIter,
};
#[doc(hidden)]
pub trait ResultLike: Sized {
type T;
type E;
fn by(self) -> Result<Self::T, Self::E>;
fn by_ref(&self) -> Result<&Self::T, &Self::E>;
fn by_mut(&mut self) -> Result<&mut Self::T, &mut Self::E>;
}
#[doc(hidden)]
pub trait ThisRef<'a>: 'a {
type Out: ?Sized;
fn this_ref(self) -> &'a Self::Out;
}
impl<'a, T: ?Sized> ThisRef<'a> for &'a T {
type Out = T;
fn this_ref(self) -> &'a Self::Out {
self
}
}
impl<'a, T: ?Sized> ThisRef<'a> for &'a mut T {
type Out = T;
fn this_ref(self) -> &'a Self::Out {
self
}
}
impl<T, E> ResultLike for Result<T, E> {
type T = T;
type E = E;
#[inline]
fn by(self) -> Result<Self::T, Self::E> {
self
}
#[inline]
fn by_ref(&self) -> Result<&Self::T, &Self::E> {
self.as_ref()
}
#[inline]
fn by_mut(&mut self) -> Result<&mut Self::T, &mut Self::E> {
self.as_mut()
}
}
#[allow(private_bounds, private_interfaces)]
pub trait ResultExt: ResultLike {
fn err_as_deref(&self) -> Result<&Self::T, &<Self::E as Deref>::Target>
where Self::E: Deref,
{
self.by_ref().map_err(Deref::deref)
}
fn err_as_deref_mut(&mut self) -> Result<&mut Self::T, &mut <Self::E as Deref>::Target>
where Self::E: DerefMut,
{
self.by_mut().map_err(DerefMut::deref_mut)
}
fn copied_err<'a>(self) -> Result<Self::T, <Self::E as ThisRef<'a>>::Out>
where Self::E: ThisRef<'a>,
<Self::E as ThisRef<'a>>::Out: Copy,
{
self.by().map_err(|e| *e.this_ref())
}
fn cloned_err<'a>(self) -> Result<Self::T, <Self::E as ThisRef<'a>>::Out>
where Self::E: ThisRef<'a>,
<Self::E as ThisRef<'a>>::Out: Clone,
{
self.by().map_err(|e| e.this_ref().clone())
}
fn iter_err(&self) -> IntoIter<&Self::E> {
self.by_ref().err().into_iter()
}
fn iter_err_mut(&mut self) -> IntoIter<&mut Self::E> {
self.by_mut().err().into_iter()
}
fn into_iter_err(self) -> IntoIter<Self::E> {
self.by().err().into_iter()
}
fn map_err_or<E, F>(self, default: E, f: F) -> E
where F: FnOnce(Self::E) -> E,
{
match self.by() {
Ok(_) => default,
Err(e) => f(e),
}
}
fn map_err_or_else<E, D, F>(self, default: D, f: F) -> E
where F: FnOnce(Self::E) -> E,
D: FnOnce(Self::T) -> E,
{
match self.by() {
Ok(ok) => default(ok),
Err(e) => f(e),
}
}
fn unwrap_err_or(self, default: Self::E) -> Self::E {
match self.by() {
Ok(_) => default,
Err(e) => e,
}
}
fn unwrap_err_or_else<F>(self, op: F) -> Self::E
where F: FnOnce(Self::T) -> Self::E,
{
match self.by() {
Ok(ok) => op(ok),
Err(e) => e,
}
}
fn unwrap_err_or_default(self) -> Self::E
where Self::E: Default,
{
match self.by() {
Ok(_) => Default::default(),
Err(e) => e,
}
}
fn transpose_err<E>(self) -> Option<Result<Self::T, E>>
where Self: ResultLike<E = Option<E>>,
{
match self.by() {
Ok(x) => Some(Ok(x)),
Err(Some(e)) => Some(Err(e)),
Err(None) => None,
}
}
fn err_into<E>(self) -> Result<Self::T, E>
where Self::E: Into<E>,
{
self.by().map_err(Into::into)
}
fn flip(self) -> Result<Self::E, Self::T> {
match self.by() {
Ok(x) => Err(x),
Err(x) => Ok(x),
}
}
}
impl<T: ResultLike> ResultExt for T { }