Skip to content

Commit

Permalink
Implement Try for ()
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarcho committed Sep 24, 2023
1 parent 551c718 commit 45e5edc
Showing 1 changed file with 79 additions and 0 deletions.
79 changes: 79 additions & 0 deletions library/core/src/unit.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::convert::Infallible;
use crate::iter::FromIterator;
use crate::ops::{ControlFlow, FromResidual, Try};

/// Collapses all unit items from an iterator into one.
///
Expand All @@ -19,3 +21,80 @@ impl FromIterator<()> for () {
iter.into_iter().for_each(|()| {})
}
}

/// Allows the unit type to be used with the question mark operator.
///
/// This allows more easily writing internal iteration functions which can take
/// both fallible and infallible closures, or visitors which can have both
/// fallible and infallible implementations.
///
/// # Examples
///
/// ```
/// fn foreach<I, R>(iter: I, f: impl FnMut(I::Item) -> R) -> Option<R::Residual>
/// where
/// I: IntoIterator,
/// R: Try<Output = ()>,
/// {
/// for x in iter {
/// f(x)?;
/// }
/// R::from_output(())
/// }
///
/// // prints everything
/// foreach([1, 2, 3], |x| println!("{x}"));
///
/// // prints everything until an error occurs
/// let _ = foreach([Ok(1), Ok(2), Err(()), Ok(3)], |x| println!("{}", x?));
/// ```
///
/// ```
/// fn walk_children<V: Visitor>(visitor: &mut V, item: ()) -> V::ResultTy {
/// // can use the `?` operator if needed here.
/// <V as Visitor>::ResultTy::from_output(())
/// }
///
/// trait Visitor {
/// type ResultTy: Try<Output = ()> = ();
///
/// fn visit_x(&mut self, item: ()) -> Self::ResultTy {
/// // can use the `?` operator if needed here.
/// walk_children(item)
/// }
/// // some `visit_*` functions
/// }
///
/// struct InfallibleVisitor;
///
/// impl Visitor for InfallibleVisitor {
/// // implement `visit_*` functions
/// }
///
/// struct FallibleVisitor;
///
/// impl Visitor for FallibleVisitor {
/// type ResultTy = std::ops::ControlFlow<()>;
/// // implement `visit_*` functions
/// }
/// ```
#[unstable(feature = "try_trait_v2", issue = "84277")]
impl Try for () {
type Output = ();
type Residual = Infallible;

fn from_output(_: ()) -> Self {
()
}

fn branch(self) -> ControlFlow<Infallible, ()> {
ControlFlow::Continue(())
}
}

#[unstable(feature = "try_trait_v2", issue = "84277")]
impl FromResidual<Infallible> for () {
fn from_residual(_: Infallible) -> Self {
()
}
}

0 comments on commit 45e5edc

Please sign in to comment.