permutohedron/
control.rs

1//! Control flow for callbacks.
2
3macro_rules! try_control {
4    ($e:expr) => {
5        match $e {
6            x => if x.should_break() {
7                return x;
8            }
9        }
10    }
11}
12
13/// Control flow for callbacks.
14///
15/// `Break` can carry a value.
16#[derive(Copy, Clone, Debug)]
17pub enum Control<B> {
18    Continue,
19    Break(B),
20}
21
22impl<B> Control<B> {
23    pub fn breaking() -> Control<()> { Control::Break(()) }
24    /// Get the value in `Control::Break(_)`, if present.
25    pub fn break_value(self) -> Option<B> {
26        match self {
27            Control::Continue => None,
28            Control::Break(b) => Some(b),
29        }
30    }
31}
32
33/// Control flow for callbacks.
34///
35/// The empty return value `()` is equivalent to continue.
36pub trait ControlFlow {
37    fn continuing() -> Self;
38    #[inline]
39    fn should_break(&self) -> bool { false }
40}
41
42impl ControlFlow for () {
43    fn continuing() { }
44}
45
46impl<B> ControlFlow for Control<B> {
47    fn continuing() -> Self { Control::Continue }
48    fn should_break(&self) -> bool {
49        if let Control::Break(_) = *self { true } else { false }
50    }
51}
52
53impl<E> ControlFlow for Result<(), E> {
54    fn continuing() -> Self { Ok(()) }
55    fn should_break(&self) -> bool {
56        if let Err(_) = *self { true } else { false }
57    }
58}