Skip to content

Commit 582515e

Browse files
committed
moved simple test to coretests, introduced more fleshed out doctests for break_ok/continue_ok
1 parent 95d8b51 commit 582515e

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
@@ -177,8 +177,60 @@ impl<B, C> ControlFlow<B, C> {
177177
///
178178
/// use std::ops::ControlFlow;
179179
///
180-
/// assert_eq!(ControlFlow::<&str, i32>::Break("Stop right there!").break_ok(), Ok("Stop right there!"));
181-
/// assert_eq!(ControlFlow::<&str, i32>::Continue(3).break_ok(), Err(3));
180+
/// struct TreeNode<T> {
181+
/// value: T,
182+
/// left: Option<Box<TreeNode<T>>>,
183+
/// right: Option<Box<TreeNode<T>>>,
184+
/// }
185+
///
186+
/// impl<T> TreeNode<T> {
187+
/// fn find<'a>(&'a self, mut predicate: impl FnMut(&T) -> bool) -> Result<&'a T, ()> {
188+
/// let mut f = |t: &'a T| -> ControlFlow<&'a T> {
189+
/// if predicate(t) {
190+
/// ControlFlow::Break(t)
191+
/// } else {
192+
/// ControlFlow::Continue(())
193+
/// }
194+
/// };
195+
///
196+
/// self.traverse_inorder(&mut f).break_ok()
197+
/// }
198+
///
199+
/// fn traverse_inorder<'a, B>(
200+
/// &'a self,
201+
/// f: &mut impl FnMut(&'a T) -> ControlFlow<B>,
202+
/// ) -> ControlFlow<B> {
203+
/// if let Some(left) = &self.left {
204+
/// left.traverse_inorder(f)?;
205+
/// }
206+
/// f(&self.value)?;
207+
/// if let Some(right) = &self.right {
208+
/// right.traverse_inorder(f)?;
209+
/// }
210+
/// ControlFlow::Continue(())
211+
/// }
212+
///
213+
/// fn leaf(value: T) -> Option<Box<TreeNode<T>>> {
214+
/// Some(Box::new(Self {
215+
/// value,
216+
/// left: None,
217+
/// right: None,
218+
/// }))
219+
/// }
220+
/// }
221+
///
222+
/// let node = TreeNode {
223+
/// value: 0,
224+
/// left: TreeNode::leaf(1),
225+
/// right: Some(Box::new(TreeNode {
226+
/// value: -1,
227+
/// left: TreeNode::leaf(5),
228+
/// right: TreeNode::leaf(2),
229+
/// })),
230+
/// };
231+
///
232+
/// let res = node.find(|val: &i32| *val > 3);
233+
/// assert_eq!(res, Ok(&5));
182234
/// ```
183235
#[inline]
184236
#[unstable(feature = "control_flow_ok", issue = "140266")]
@@ -230,8 +282,59 @@ impl<B, C> ControlFlow<B, C> {
230282
///
231283
/// use std::ops::ControlFlow;
232284
///
233-
/// assert_eq!(ControlFlow::<&str, i32>::Break("Stop right there!").continue_ok(), Err("Stop right there!"));
234-
/// assert_eq!(ControlFlow::<&str, i32>::Continue(3).continue_ok(), Ok(3));
285+
/// struct TreeNode<T> {
286+
/// value: T,
287+
/// left: Option<Box<TreeNode<T>>>,
288+
/// right: Option<Box<TreeNode<T>>>,
289+
/// }
290+
///
291+
/// impl<T> TreeNode<T> {
292+
/// fn validate<B>(&self, f: &mut impl FnMut(&T) -> ControlFlow<B>) -> Result<(), B> {
293+
/// self.traverse_inorder(f).continue_ok()
294+
/// }
295+
///
296+
/// fn traverse_inorder<B>(&self, f: &mut impl FnMut(&T) -> ControlFlow<B>) -> ControlFlow<B> {
297+
/// if let Some(left) = &self.left {
298+
/// left.traverse_inorder(f)?;
299+
/// }
300+
/// f(&self.value)?;
301+
/// if let Some(right) = &self.right {
302+
/// right.traverse_inorder(f)?;
303+
/// }
304+
/// ControlFlow::Continue(())
305+
/// }
306+
///
307+
/// fn leaf(value: T) -> Option<Box<TreeNode<T>>> {
308+
/// Some(Box::new(Self {
309+
/// value,
310+
/// left: None,
311+
/// right: None,
312+
/// }))
313+
/// }
314+
/// }
315+
///
316+
/// let node = TreeNode {
317+
/// value: 0,
318+
/// left: TreeNode::leaf(1),
319+
/// right: Some(Box::new(TreeNode {
320+
/// value: -1,
321+
/// left: TreeNode::leaf(5),
322+
/// right: TreeNode::leaf(2),
323+
/// })),
324+
/// };
325+
///
326+
/// let res = node.validate(&mut |val| {
327+
/// if *val < 0 {
328+
/// return ControlFlow::Break("negative value detected");
329+
/// }
330+
///
331+
/// if *val > 4 {
332+
/// return ControlFlow::Break("too big value detected");
333+
/// }
334+
///
335+
/// ControlFlow::Continue(())
336+
/// });
337+
/// assert_eq!(res, Err("too big value detected"));
235338
/// ```
236339
#[inline]
237340
#[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
@@ -17,6 +17,7 @@
1717
#![feature(const_eval_select)]
1818
#![feature(const_swap_nonoverlapping)]
1919
#![feature(const_trait_impl)]
20+
#![feature(control_flow_ok)]
2021
#![feature(core_intrinsics)]
2122
#![feature(core_intrinsics_fallbacks)]
2223
#![feature(core_io_borrowed_buf)]

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)