[no description]
Diffstat (limited to 'src/try.rs')
-rw-r--r--src/try.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/try.rs b/src/try.rs
new file mode 100644
index 0000000..6fcd740
--- /dev/null
+++ b/src/try.rs
@@ -0,0 +1,71 @@
+use core::ops::{FromResidual, Residual, Try};
+
+use crate::{Pick, Tupl};
+
+macro_rules! option_of_ref_to_tuple {
+ ($name1:ident, $name2:ident, $as_ref:ident, $AsRef:ident $(, $mut:tt)?) => {
+
+pub trait $name1<'a, T: Tupl + 'a>: Try<Output = &'a $($mut)? T> + Sized {
+ fn on<const N: usize>(
+ self,
+ ) -> ChangeOutputType<Self, <T::$AsRef<'a> as Pick<N>>::At>
+ where
+ <T as Tupl>::$AsRef<'a>: Pick<N>,
+ Self:
+ Try<Residual: Residual<<T::$AsRef<'a> as Pick<N>>::At> + Sized>,
+ {
+ match self.branch() {
+ core::ops::ControlFlow::Continue(x) =>
+ <_>::from_output(x.$as_ref().pick()),
+ core::ops::ControlFlow::Break(x) => <_>::from_residual(x),
+ }
+ }
+}
+impl<'a, T: Tupl + 'a, R: Try<Output = &'a $($mut)? T>> $name1<'a, T> for R {}
+ };
+}
+pub trait TryTuple<T: Tupl>: Try<Output = T> {
+ fn on<const N: usize>(self) -> ChangeOutputType<Self, T::At>
+ where
+ T: Pick<N>,
+ Self: Try<Residual: Residual<T::At>> + Sized,
+ {
+ match self.branch() {
+ core::ops::ControlFlow::Continue(x) =>
+ <_>::from_output(x.pick()),
+ core::ops::ControlFlow::Break(x) => <_>::from_residual(x),
+ }
+ }
+}
+pub type ChangeOutputType<T: Try<Residual: Residual<V>>, V> =
+ <T::Residual as Residual<V>>::TryType;
+
+impl<T: Tupl, Tr: Try<Output = T>> TryTuple<T> for Tr {}
+
+// impl<T: Tupl, Tr: Try<Output = T>> TryTuple<T> for Tr {}
+// impl<T: Tupl, Tr: Try<Output = T>> TryTuple<T> for Tr {}
+
+option_of_ref_to_tuple!(
+ TryRefTuple,
+ OptionOfRefToTupleWithF,
+ as_ref,
+ AsRef
+);
+
+option_of_ref_to_tuple!(
+ TryRefMutTuple,
+ OptionOfMutRefToTupleWithF,
+ as_mut,
+ AsMut,
+ mut
+);
+
+#[test]
+fn x() {
+ struct Y;
+ let x = Some(&mut (Y, 2));
+ let x = x.on::<1>();
+ let x = &mut Some((Y, 2));
+ let x = x.as_mut().on::<1>();
+ let x = (&Ok::<_, ()>((Y, Y))).as_ref().on::<1>();
+}