11use crate :: ops:: Try ;
22
3- /// Used to make try_fold closures more like normal loops
3+ /// Used to tell an operation whether it should exit early or go on as usual.
4+ ///
5+ /// This is used when exposing things (like graph traversals or visitors) where
6+ /// you want the user to be able to choose whether to exit early.
7+ /// Having the enum makes it clearer -- no more wondering "wait, what did `false`
8+ /// mean again?" -- and allows including a value.
9+ ///
10+ /// # Examples
11+ ///
12+ /// Early-exiting from [`Iterator::try_for_each`]:
13+ /// ```
14+ /// #![feature(control_flow_enum)]
15+ /// use std::ops::ControlFlow;
16+ ///
17+ /// let r = (2..100).try_for_each(|x| {
18+ /// if 403 % x == 0 {
19+ /// return ControlFlow::Break(x)
20+ /// }
21+ ///
22+ /// ControlFlow::Continue(())
23+ /// });
24+ /// assert_eq!(r, ControlFlow::Break(13));
25+ /// ```
26+ ///
27+ /// A basic tree traversal:
28+ /// ```no_run
29+ /// #![feature(control_flow_enum)]
30+ /// use std::ops::ControlFlow;
31+ ///
32+ /// pub struct TreeNode<T> {
33+ /// value: T,
34+ /// left: Option<Box<TreeNode<T>>>,
35+ /// right: Option<Box<TreeNode<T>>>,
36+ /// }
37+ ///
38+ /// impl<T> TreeNode<T> {
39+ /// pub fn traverse_inorder<B>(&self, mut f: impl FnMut(&T) -> ControlFlow<B>) -> ControlFlow<B> {
40+ /// if let Some(left) = &self.left {
41+ /// left.traverse_inorder(&mut f)?;
42+ /// }
43+ /// f(&self.value)?;
44+ /// if let Some(right) = &self.right {
45+ /// right.traverse_inorder(&mut f)?;
46+ /// }
47+ /// ControlFlow::Continue(())
48+ /// }
49+ /// }
50+ /// ```
451#[ unstable( feature = "control_flow_enum" , reason = "new API" , issue = "75744" ) ]
552#[ derive( Debug , Clone , Copy , PartialEq ) ]
653pub enum ControlFlow < B , C = ( ) > {
7- /// Continue in the loop, using the given value for the next iteration
54+ /// Move on to the next phase of the operation as normal.
855 Continue ( C ) ,
9- /// Exit the loop, yielding the given value
56+ /// Exit the operation without running subsequent phases.
1057 Break ( B ) ,
58+ // Yes, the order of the variants doesn't match the type parameters.
59+ // They're in this order so that `ControlFlow<A, B>` <-> `Result<B, A>`
60+ // is a no-op conversion in the `Try` implementation.
1161}
1262
1363#[ unstable( feature = "control_flow_enum" , reason = "new API" , issue = "75744" ) ]
@@ -33,13 +83,33 @@ impl<B, C> Try for ControlFlow<B, C> {
3383
3484impl < B , C > ControlFlow < B , C > {
3585 /// Returns `true` if this is a `Break` variant.
86+ ///
87+ /// # Examples
88+ ///
89+ /// ```
90+ /// #![feature(control_flow_enum)]
91+ /// use std::ops::ControlFlow;
92+ ///
93+ /// assert!(ControlFlow::<i32, String>::Break(3).is_break());
94+ /// assert!(!ControlFlow::<String, i32>::Continue(3).is_break());
95+ /// ```
3696 #[ inline]
3797 #[ unstable( feature = "control_flow_enum" , reason = "new API" , issue = "75744" ) ]
3898 pub fn is_break ( & self ) -> bool {
3999 matches ! ( * self , ControlFlow :: Break ( _) )
40100 }
41101
42102 /// Returns `true` if this is a `Continue` variant.
103+ ///
104+ /// # Examples
105+ ///
106+ /// ```
107+ /// #![feature(control_flow_enum)]
108+ /// use std::ops::ControlFlow;
109+ ///
110+ /// assert!(!ControlFlow::<i32, String>::Break(3).is_continue());
111+ /// assert!(ControlFlow::<String, i32>::Continue(3).is_continue());
112+ /// ```
43113 #[ inline]
44114 #[ unstable( feature = "control_flow_enum" , reason = "new API" , issue = "75744" ) ]
45115 pub fn is_continue ( & self ) -> bool {
@@ -48,6 +118,16 @@ impl<B, C> ControlFlow<B, C> {
48118
49119 /// Converts the `ControlFlow` into an `Option` which is `Some` if the
50120 /// `ControlFlow` was `Break` and `None` otherwise.
121+ ///
122+ /// # Examples
123+ ///
124+ /// ```
125+ /// #![feature(control_flow_enum)]
126+ /// use std::ops::ControlFlow;
127+ ///
128+ /// assert_eq!(ControlFlow::<i32, String>::Break(3).break_value(), Some(3));
129+ /// assert_eq!(ControlFlow::<String, i32>::Continue(3).break_value(), None);
130+ /// ```
51131 #[ inline]
52132 #[ unstable( feature = "control_flow_enum" , reason = "new API" , issue = "75744" ) ]
53133 pub fn break_value ( self ) -> Option < B > {
0 commit comments