1
1
use crate :: ops:: Try ;
2
2
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
+ /// ```
4
51
#[ unstable( feature = "control_flow_enum" , reason = "new API" , issue = "75744" ) ]
5
52
#[ derive( Debug , Clone , Copy , PartialEq ) ]
6
53
pub 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.
8
55
Continue ( C ) ,
9
- /// Exit the loop, yielding the given value
56
+ /// Exit the operation without running subsequent phases.
10
57
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.
11
61
}
12
62
13
63
#[ unstable( feature = "control_flow_enum" , reason = "new API" , issue = "75744" ) ]
@@ -33,13 +83,33 @@ impl<B, C> Try for ControlFlow<B, C> {
33
83
34
84
impl < B , C > ControlFlow < B , C > {
35
85
/// 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
+ /// ```
36
96
#[ inline]
37
97
#[ unstable( feature = "control_flow_enum" , reason = "new API" , issue = "75744" ) ]
38
98
pub fn is_break ( & self ) -> bool {
39
99
matches ! ( * self , ControlFlow :: Break ( _) )
40
100
}
41
101
42
102
/// 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
+ /// ```
43
113
#[ inline]
44
114
#[ unstable( feature = "control_flow_enum" , reason = "new API" , issue = "75744" ) ]
45
115
pub fn is_continue ( & self ) -> bool {
@@ -48,6 +118,16 @@ impl<B, C> ControlFlow<B, C> {
48
118
49
119
/// Converts the `ControlFlow` into an `Option` which is `Some` if the
50
120
/// `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
+ /// ```
51
131
#[ inline]
52
132
#[ unstable( feature = "control_flow_enum" , reason = "new API" , issue = "75744" ) ]
53
133
pub fn break_value ( self ) -> Option < B > {
0 commit comments