@@ -187,6 +187,80 @@ impl<B, C> ControlFlow<B, C> {
187
187
}
188
188
}
189
189
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
+
190
264
/// Maps `ControlFlow<B, C>` to `ControlFlow<T, C>` by applying a function
191
265
/// to the break value in case it exists.
192
266
#[ inline]
@@ -218,6 +292,79 @@ impl<B, C> ControlFlow<B, C> {
218
292
}
219
293
}
220
294
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
+
221
368
/// Maps `ControlFlow<B, C>` to `ControlFlow<B, T>` by applying a function
222
369
/// to the continue value in case it exists.
223
370
#[ inline]
0 commit comments