Skip to content

Commit b981b84

Browse files
committed
moved simple test to coretests, introduced more fleshed out doctests for break_ok/continue_ok
1 parent e836a2f commit b981b84

File tree

3 files changed

+120
-4
lines changed

3 files changed

+120
-4
lines changed

library/core/src/ops/control_flow.rs

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,60 @@ impl<B, C> ControlFlow<B, C> {
197197
///
198198
/// use std::ops::ControlFlow;
199199
///
200-
/// assert_eq!(ControlFlow::<&str, i32>::Break("Stop right there!").break_ok(), Ok("Stop right there!"));
201-
/// assert_eq!(ControlFlow::<&str, i32>::Continue(3).break_ok(), Err(3));
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));
202254
/// ```
203255
#[inline]
204256
#[unstable(feature = "control_flow_ok", issue = "140266")]
@@ -250,8 +302,59 @@ impl<B, C> ControlFlow<B, C> {
250302
///
251303
/// use std::ops::ControlFlow;
252304
///
253-
/// assert_eq!(ControlFlow::<&str, i32>::Break("Stop right there!").continue_ok(), Err("Stop right there!"));
254-
/// assert_eq!(ControlFlow::<&str, i32>::Continue(3).continue_ok(), Ok(3));
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"));
255358
/// ```
256359
#[inline]
257360
#[unstable(feature = "control_flow_ok", issue = "140266")]

library/coretests/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#![feature(const_ref_cell)]
2323
#![feature(const_result_trait_fn)]
2424
#![feature(const_trait_impl)]
25+
#![feature(control_flow_ok)]
2526
#![feature(core_float_math)]
2627
#![feature(core_intrinsics)]
2728
#![feature(core_intrinsics_fallbacks)]

library/coretests/tests/ops/control_flow.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,15 @@ fn control_flow_discriminants_match_result() {
1616
discriminant_value(&Result::<i32, i32>::Ok(3)),
1717
);
1818
}
19+
20+
#[test]
21+
fn control_flow_break_ok() {
22+
assert_eq!(ControlFlow::<char, i32>::Break('b').break_ok(), Ok('b'));
23+
assert_eq!(ControlFlow::<char, i32>::Continue(3).break_ok(), Err(3));
24+
}
25+
26+
#[test]
27+
fn control_flow_continue_ok() {
28+
assert_eq!(ControlFlow::<char, i32>::Break('b').continue_ok(), Err('b'));
29+
assert_eq!(ControlFlow::<char, i32>::Continue(3).continue_ok(), Ok(3));
30+
}

0 commit comments

Comments
 (0)