@@ -187,6 +187,80 @@ impl<B, C> ControlFlow<B, C> {
187187 }
188188 }
189189
190+ /// Converts the `ControlFlow` into an `Result` which is `Ok` if the
191+ /// `ControlFlow` was `Break` and `Err` if otherwise.
192+ ///
193+ /// # Examples
194+ ///
195+ /// ```
196+ /// #![feature(control_flow_ok)]
197+ ///
198+ /// use std::ops::ControlFlow;
199+ ///
200+ /// struct TreeNode<T> {
201+ /// value: T,
202+ /// left: Option<Box<TreeNode<T>>>,
203+ /// right: Option<Box<TreeNode<T>>>,
204+ /// }
205+ ///
206+ /// impl<T> TreeNode<T> {
207+ /// fn find<'a>(&'a self, mut predicate: impl FnMut(&T) -> bool) -> Result<&'a T, ()> {
208+ /// let mut f = |t: &'a T| -> ControlFlow<&'a T> {
209+ /// if predicate(t) {
210+ /// ControlFlow::Break(t)
211+ /// } else {
212+ /// ControlFlow::Continue(())
213+ /// }
214+ /// };
215+ ///
216+ /// self.traverse_inorder(&mut f).break_ok()
217+ /// }
218+ ///
219+ /// fn traverse_inorder<'a, B>(
220+ /// &'a self,
221+ /// f: &mut impl FnMut(&'a T) -> ControlFlow<B>,
222+ /// ) -> ControlFlow<B> {
223+ /// if let Some(left) = &self.left {
224+ /// left.traverse_inorder(f)?;
225+ /// }
226+ /// f(&self.value)?;
227+ /// if let Some(right) = &self.right {
228+ /// right.traverse_inorder(f)?;
229+ /// }
230+ /// ControlFlow::Continue(())
231+ /// }
232+ ///
233+ /// fn leaf(value: T) -> Option<Box<TreeNode<T>>> {
234+ /// Some(Box::new(Self {
235+ /// value,
236+ /// left: None,
237+ /// right: None,
238+ /// }))
239+ /// }
240+ /// }
241+ ///
242+ /// let node = TreeNode {
243+ /// value: 0,
244+ /// left: TreeNode::leaf(1),
245+ /// right: Some(Box::new(TreeNode {
246+ /// value: -1,
247+ /// left: TreeNode::leaf(5),
248+ /// right: TreeNode::leaf(2),
249+ /// })),
250+ /// };
251+ ///
252+ /// let res = node.find(|val: &i32| *val > 3);
253+ /// assert_eq!(res, Ok(&5));
254+ /// ```
255+ #[ inline]
256+ #[ unstable( feature = "control_flow_ok" , issue = "140266" ) ]
257+ pub fn break_ok ( self ) -> Result < B , C > {
258+ match self {
259+ ControlFlow :: Continue ( c) => Err ( c) ,
260+ ControlFlow :: Break ( b) => Ok ( b) ,
261+ }
262+ }
263+
190264 /// Maps `ControlFlow<B, C>` to `ControlFlow<T, C>` by applying a function
191265 /// to the break value in case it exists.
192266 #[ inline]
@@ -218,6 +292,79 @@ impl<B, C> ControlFlow<B, C> {
218292 }
219293 }
220294
295+ /// Converts the `ControlFlow` into an `Result` which is `Ok` if the
296+ /// `ControlFlow` was `Continue` and `Err` if otherwise.
297+ ///
298+ /// # Examples
299+ ///
300+ /// ```
301+ /// #![feature(control_flow_ok)]
302+ ///
303+ /// use std::ops::ControlFlow;
304+ ///
305+ /// struct TreeNode<T> {
306+ /// value: T,
307+ /// left: Option<Box<TreeNode<T>>>,
308+ /// right: Option<Box<TreeNode<T>>>,
309+ /// }
310+ ///
311+ /// impl<T> TreeNode<T> {
312+ /// fn validate<B>(&self, f: &mut impl FnMut(&T) -> ControlFlow<B>) -> Result<(), B> {
313+ /// self.traverse_inorder(f).continue_ok()
314+ /// }
315+ ///
316+ /// fn traverse_inorder<B>(&self, f: &mut impl FnMut(&T) -> ControlFlow<B>) -> ControlFlow<B> {
317+ /// if let Some(left) = &self.left {
318+ /// left.traverse_inorder(f)?;
319+ /// }
320+ /// f(&self.value)?;
321+ /// if let Some(right) = &self.right {
322+ /// right.traverse_inorder(f)?;
323+ /// }
324+ /// ControlFlow::Continue(())
325+ /// }
326+ ///
327+ /// fn leaf(value: T) -> Option<Box<TreeNode<T>>> {
328+ /// Some(Box::new(Self {
329+ /// value,
330+ /// left: None,
331+ /// right: None,
332+ /// }))
333+ /// }
334+ /// }
335+ ///
336+ /// let node = TreeNode {
337+ /// value: 0,
338+ /// left: TreeNode::leaf(1),
339+ /// right: Some(Box::new(TreeNode {
340+ /// value: -1,
341+ /// left: TreeNode::leaf(5),
342+ /// right: TreeNode::leaf(2),
343+ /// })),
344+ /// };
345+ ///
346+ /// let res = node.validate(&mut |val| {
347+ /// if *val < 0 {
348+ /// return ControlFlow::Break("negative value detected");
349+ /// }
350+ ///
351+ /// if *val > 4 {
352+ /// return ControlFlow::Break("too big value detected");
353+ /// }
354+ ///
355+ /// ControlFlow::Continue(())
356+ /// });
357+ /// assert_eq!(res, Err("too big value detected"));
358+ /// ```
359+ #[ inline]
360+ #[ unstable( feature = "control_flow_ok" , issue = "140266" ) ]
361+ pub fn continue_ok ( self ) -> Result < C , B > {
362+ match self {
363+ ControlFlow :: Continue ( c) => Ok ( c) ,
364+ ControlFlow :: Break ( b) => Err ( b) ,
365+ }
366+ }
367+
221368 /// Maps `ControlFlow<B, C>` to `ControlFlow<B, T>` by applying a function
222369 /// to the continue value in case it exists.
223370 #[ inline]
0 commit comments