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 + Sized { fn on( self, ) -> ChangeOutputType as Pick>::At> where ::$AsRef<'a>: Pick, Self: Try as Pick>::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> $name1<'a, T> for R {} }; } pub trait TryTuple: Try { fn on(self) -> ChangeOutputType where T: Pick, Self: Try> + Sized, { match self.branch() { core::ops::ControlFlow::Continue(x) => <_>::from_output(x.pick()), core::ops::ControlFlow::Break(x) => <_>::from_residual(x), } } } pub type ChangeOutputType>, V> = >::TryType; impl> TryTuple 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>(); }