pub use Validated::{Invalid, Valid};
use crate::and_then::AndThen;
use crate::apply::Apply;
use crate::bifunctor::Bifunctor;
use crate::functor::Functor;
use crate::higher::{Higher, Higher2};
use crate::invariant_functor;
use crate::pure::Pure;
use crate::semigroup::Semigroup;
use crate::semigroupal::Semigroupal;
mod from;
#[cfg(feature = "std")]
pub type ValidatedNev<T, E> = Validated<T, super::NEVec<E>>;
#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
pub enum Validated<T, E> {
Valid(T),
Invalid(E),
}
impl<T, E> Validated<T, E> {
#[inline]
pub const fn is_valid(&self) -> bool {
matches!(*self, Valid(_))
}
#[inline]
pub const fn is_invalid(&self) -> bool {
!self.is_valid()
}
#[inline]
pub fn valid(self) -> Option<T> {
match self {
Valid(x) => Some(x),
Invalid(_) => None,
}
}
#[inline]
pub fn invalid(self) -> Option<E> {
match self {
Valid(_) => None,
Invalid(x) => Some(x),
}
}
#[inline]
pub fn into_result(self) -> Result<T, E> {
match self {
Valid(x) => Ok(x),
Invalid(x) => Err(x),
}
}
#[inline]
pub const fn as_ref(&self) -> Validated<&T, &E> {
match *self {
Valid(ref x) => Valid(x),
Invalid(ref x) => Invalid(x),
}
}
#[inline]
pub fn as_mut(&mut self) -> Validated<&mut T, &mut E> {
match *self {
Valid(ref mut x) => Valid(x),
Invalid(ref mut x) => Invalid(x),
}
}
#[inline]
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Validated<U, E> {
match self {
Valid(x) => Valid(f(x)),
Invalid(x) => Invalid(x),
}
}
#[inline]
pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
match self {
Valid(x) => f(x),
Invalid(_) => default,
}
}
#[inline]
pub fn map_or_else<U, D: FnOnce(E) -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
match self {
Valid(x) => f(x),
Invalid(x) => default(x),
}
}
#[inline]
pub fn map_err<U, F: FnOnce(E) -> U>(self, f: F) -> Validated<T, U> {
match self {
Valid(x) => Valid(x),
Invalid(x) => Invalid(f(x)),
}
}
#[inline]
pub fn as_deref(&self) -> Validated<&T::Target, &E>
where
T: core::ops::Deref,
{
self.as_ref().map(|x| x.deref())
}
#[inline]
pub fn as_deref_mut(&mut self) -> Validated<&mut T::Target, &mut E>
where
T: core::ops::DerefMut,
{
self.as_mut().map(|x| x.deref_mut())
}
#[inline]
#[track_caller]
pub fn expect(self, msg: &str) -> T
where
E: core::fmt::Debug,
{
match self {
Valid(x) => x,
Invalid(e) => unwrap_failed(msg, &e),
}
}
#[inline]
#[track_caller]
pub fn unwrap(self) -> T
where
E: core::fmt::Debug,
{
match self {
Valid(x) => x,
Invalid(e) => unwrap_failed("called `Validated::unwrap()` on an `Invalid` value", &e),
}
}
#[inline]
pub fn unwrap_or_default(self) -> T
where
T: Default,
{
match self {
Valid(x) => x,
Invalid(_) => Default::default(),
}
}
#[inline]
#[track_caller]
pub fn expect_err(self, msg: &str) -> E
where
T: core::fmt::Debug,
{
match self {
Valid(x) => unwrap_failed(msg, &x),
Invalid(x) => x,
}
}
#[inline]
#[track_caller]
pub fn unwrap_err(self) -> E
where
T: core::fmt::Debug,
{
match self {
Valid(x) => unwrap_failed("called `Validated::unwrap_err()` on a `Valid` value", &x),
Invalid(x) => x,
}
}
#[inline]
pub fn and<U>(self, other: Validated<U, E>) -> Validated<U, E> {
match self {
Valid(_) => other,
Invalid(x) => Invalid(x),
}
}
#[inline]
pub fn and_then<U, F: FnOnce(T) -> Validated<U, E>>(self, f: F) -> Validated<U, E> {
match self {
Valid(x) => f(x),
Invalid(x) => Invalid(x),
}
}
#[inline]
pub fn or<U>(self, other: Validated<T, U>) -> Validated<T, U> {
match self {
Valid(x) => Valid(x),
Invalid(_) => other,
}
}
#[inline]
pub fn or_else<U, F: FnOnce(E) -> Validated<T, U>>(self, f: F) -> Validated<T, U> {
match self {
Valid(x) => Valid(x),
Invalid(x) => f(x),
}
}
#[inline]
pub fn unwrap_or(self, default: T) -> T {
match self {
Valid(x) => x,
Invalid(_) => default,
}
}
#[inline]
pub fn unwrap_or_else<F: FnOnce(E) -> T>(self, f: F) -> T {
match self {
Valid(x) => x,
Invalid(x) => f(x),
}
}
}
#[inline(never)]
#[cold]
#[track_caller]
fn unwrap_failed(msg: &str, error: &dyn core::fmt::Debug) -> ! {
panic!("{msg}: {error:?}")
}
impl<T, E> Clone for Validated<T, E>
where
T: Clone,
E: Clone,
{
fn clone(&self) -> Self {
match self {
Valid(x) => Valid(x.clone()),
Invalid(x) => Invalid(x.clone()),
}
}
fn clone_from(&mut self, source: &Self) {
match (self, source) {
(Valid(to), Valid(from)) => to.clone_from(from),
(Invalid(to), Invalid(from)) => to.clone_from(from),
(x, y) => *x = y.clone(),
}
}
}
impl<P, E> Higher for Validated<P, E> {
type Param = P;
type Target<T> = Validated<T, E>;
}
impl<T, E> Higher2 for Validated<T, E> {
type Param1 = T;
type Param2 = E;
type Target<TV, TE> = Validated<TV, TE>;
}
invariant_functor!(Validated<T, E>);
impl<A, B, E> Functor<B> for Validated<A, E> {
#[inline]
fn map(self, f: impl FnMut(A) -> B) -> Validated<B, E> {
self.map(f)
}
}
impl<A, B, E: Semigroup> Semigroupal<B> for Validated<A, E> {
#[inline]
fn product(self, fb: Validated<B, E>) -> Validated<(A, B), E> {
match (self, fb) {
(Valid(a), Valid(b)) => Valid((a, b)),
(Invalid(lhs), Invalid(rhs)) => Invalid(lhs.combine(rhs)),
(Invalid(e), _) | (_, Invalid(e)) => Invalid(e),
}
}
}
impl<F, A, B, E: Semigroup> Apply<A, B> for Validated<F, E> {
#[inline]
fn ap(self, fa: Validated<A, E>) -> Validated<B, E>
where
F: FnOnce(A) -> B,
{
match (self, fa) {
(Valid(f), Valid(a)) => Valid(f(a)),
(Invalid(lhs), Invalid(rhs)) => Invalid(lhs.combine(rhs)),
(Invalid(e), _) | (_, Invalid(e)) => Invalid(e),
}
}
}
impl<A, E: Semigroup> Pure for Validated<A, E> {
#[inline]
fn pure(x: A) -> Self {
Valid(x)
}
}
impl<T: Semigroup, E: Semigroup> Semigroup for Validated<T, E> {
#[inline]
fn combine(self, other: Self) -> Self {
match (self, other) {
(Valid(lhs), Valid(rhs)) => Valid(lhs.combine(rhs)),
(Invalid(lhs), Invalid(rhs)) => Invalid(lhs.combine(rhs)),
(e @ Invalid(_), _) | (_, e @ Invalid(_)) => e,
}
}
}
impl<A, B, C, D> Bifunctor<C, D> for Validated<A, B> {
#[inline]
fn bimap(self, mut f: impl FnMut(A) -> C, mut g: impl FnMut(B) -> D) -> Validated<C, D> {
match self {
Valid(x) => Valid(f(x)),
Invalid(e) => Invalid(g(e)),
}
}
}
impl<A, B, E> AndThen<B> for Validated<A, E> {
#[inline]
fn and_then<F>(self, f: F) -> Validated<B, E>
where
F: FnMut(A) -> Validated<B, E>,
{
self.and_then(f)
}
}