1use crate::{coproduct::CoprodInjector, error::VecError};
20use frunk::Generic;
21use itertools::Itertools;
22use std::error::Error;
23
24pub trait IsDefault {
25 fn is_default(&self) -> bool;
26}
27impl<T: Default + PartialEq> IsDefault for T {
28 fn is_default(&self) -> bool {
29 *self == T::default()
30 }
31}
32
33pub trait IntoGeneric {
35 fn into_generic<Dst>(self) -> Dst
36 where
37 Dst: Generic<Repr = Self>;
38}
39impl<Repr> IntoGeneric for Repr {
40 fn into_generic<Dst>(self) -> Dst
41 where
42 Dst: Generic<Repr = Self>,
43 {
44 <Dst as Generic>::from(self)
45 }
46}
47
48#[macro_export]
51macro_rules! Coprod {
52 () => { $crate::coproduct::CNil };
53 (...$Rest:ty) => { $Rest };
54 ($A:ty) => { $crate::Coprod![$A,] };
55 ($A:ty, $($tok:tt)*) => {
56 $crate::coproduct::Coproduct<$A, $crate::Coprod![$($tok)*]>
57 };
58}
59
60pub trait InjectErr<T, E> {
62 fn inject_err<F, Index>(self) -> Result<T, F>
63 where
64 Self: Sized,
65 F: CoprodInjector<E, Index>;
66}
67impl<T, E> InjectErr<T, E> for Result<T, E> {
68 #[inline(always)]
69 fn inject_err<F, Index>(self) -> Result<T, F>
70 where
71 Self: Sized,
72 F: CoprodInjector<E, Index>,
73 {
74 self.map_err(CoprodInjector::inject)
75 }
76}
77
78#[cfg(unix_without_macos)]
80pub trait InjectMapErr<T, E> {
81 fn inject_map_err<F1, F2, O, Index>(self, f: O) -> Result<T, F2>
82 where
83 Self: Sized,
84 F1: CoprodInjector<E, Index>,
85 O: FnOnce(F1) -> F2;
86}
87
88#[cfg(unix_without_macos)]
89impl<T, E> InjectMapErr<T, E> for Result<T, E> {
90 #[inline(always)]
91 fn inject_map_err<F1, F2, O, Index>(self, f: O) -> Result<T, F2>
92 where
93 Self: Sized,
94 F1: CoprodInjector<E, Index>,
95 O: FnOnce(F1) -> F2,
96 {
97 self.map_err(|e| f(CoprodInjector::inject(e)))
98 }
99}
100
101pub trait CollectResult<T, E: Error> {
103 fn collect_result(self) -> Result<Vec<T>, VecError<E>>;
104}
105impl<I, T, E: Error> CollectResult<T, E> for I
106where
107 I: Itertools<Item = Result<T, E>>,
108{
109 fn collect_result(self) -> Result<Vec<T>, VecError<E>> {
110 let (v, e): (Vec<T>, Vec<E>) = self.partition_result();
111 if e.is_empty() {
112 Ok(v)
113 } else {
114 Err(VecError(e))
115 }
116 }
117}