#![allow(dead_code, deprecated, unused_variables, unused_mut)] #![feature(control_flow_ok)] use std::ops::ControlFlow; struct TreeNode { value: T, left: Option>>, right: Option>>, } impl TreeNode { fn validate(&self, f: &mut impl FnMut(&T) -> ControlFlow) -> Result<(), B> { self.traverse_inorder(f).continue_ok() } fn traverse_inorder( &self, f: &mut impl FnMut(&T) -> ControlFlow, ) -> ControlFlow { if let Some(left) = &self.left { left.traverse_inorder(f)?; } f(&self.value)?; if let Some(right) = &self.right { right.traverse_inorder(f)?; } ControlFlow::Continue(()) } fn leaf(value: T) -> Option>> { Some( Box::new(Self { value, left: None, right: None, }), ) } } fn main() { let node = TreeNode { value: 0, left: TreeNode::leaf(1), right: Some( Box::new(TreeNode { value: -1, left: TreeNode::leaf(5), right: TreeNode::leaf(2), }), ), }; let res = node .validate( &mut |val| { if *val < 0 { return ControlFlow::Break("negative value detected"); } if *val > 4 { return ControlFlow::Break("too big value detected"); } ControlFlow::Continue(()) }, ); assert_eq!(res, Err("too big value detected")); }