use crate::{Tuple, TupleLike, Unit};
#[cfg_attr(docsrs, doc(cfg(feature = "unwrap")))]
pub trait Unwrap {
type UnwrapOutput;
fn unwrap(self) -> Self::UnwrapOutput;
fn has_value(&self) -> bool;
}
#[cfg_attr(docsrs, doc(cfg(feature = "unwrap")))]
pub trait UnwrapOrDefault {
type UnwrapOutput;
fn unwrap_or_default(self) -> Self::UnwrapOutput;
}
impl<T> Unwrap for Option<T> {
type UnwrapOutput = T;
fn unwrap(self) -> Self::UnwrapOutput {
self.unwrap()
}
fn has_value(&self) -> bool {
self.is_some()
}
}
impl<T, E: std::fmt::Debug> Unwrap for Result<T, E> {
type UnwrapOutput = T;
fn unwrap(self) -> Self::UnwrapOutput {
self.unwrap()
}
fn has_value(&self) -> bool {
self.is_ok()
}
}
impl<T: Default> UnwrapOrDefault for Option<T> {
type UnwrapOutput = T;
fn unwrap_or_default(self) -> Self::UnwrapOutput {
self.unwrap_or_default()
}
}
impl<T: Default, E> UnwrapOrDefault for Result<T, E> {
type UnwrapOutput = T;
fn unwrap_or_default(self) -> Self::UnwrapOutput {
self.unwrap_or_default()
}
}
impl Unwrap for Unit {
type UnwrapOutput = Unit;
fn unwrap(self) -> Self::UnwrapOutput {
Self
}
fn has_value(&self) -> bool {
true
}
}
impl<First, Other> Unwrap for Tuple<First, Other>
where
Other: TupleLike + Unwrap,
First: Unwrap,
{
type UnwrapOutput = Tuple<First::UnwrapOutput, Other::UnwrapOutput>;
fn unwrap(self) -> Self::UnwrapOutput {
Tuple(Unwrap::unwrap(self.0), Unwrap::unwrap(self.1))
}
fn has_value(&self) -> bool {
Unwrap::has_value(&self.0) && Unwrap::has_value(&self.1)
}
}
impl UnwrapOrDefault for Unit {
type UnwrapOutput = Unit;
fn unwrap_or_default(self) -> Self::UnwrapOutput {
Self
}
}
impl Unit {
pub fn try_unwrap(self) -> Option<Self> {
Some(self)
}
}
impl<First, Other> UnwrapOrDefault for Tuple<First, Other>
where
Other: TupleLike + UnwrapOrDefault,
First: UnwrapOrDefault,
{
type UnwrapOutput = Tuple<First::UnwrapOutput, Other::UnwrapOutput>;
fn unwrap_or_default(self) -> Self::UnwrapOutput {
Tuple(
UnwrapOrDefault::unwrap_or_default(self.0),
UnwrapOrDefault::unwrap_or_default(self.1),
)
}
}