about summary refs log tree commit diff
path: root/library/core/src/ops
diff options
context:
space:
mode:
authorLeonora Tindall <nora@nora.codes>2020-09-01 11:44:32 -0500
committerLeonora Tindall <nora@nora.codes>2020-09-01 16:02:09 -0500
commitd0af12560c9672546a6434e2e1e9ec72ad8f8e70 (patch)
tree4f70d06493ab685d496280f760130b634c55159e /library/core/src/ops
parenteb9e7c357e26bf41c47661720e46f4498de32b83 (diff)
Rename and expose LoopState as ControlFlow
Diffstat (limited to 'library/core/src/ops')
-rw-r--r--library/core/src/ops/control_flow.rs67
-rw-r--r--library/core/src/ops/mod.rs4
2 files changed, 71 insertions, 0 deletions
diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs
new file mode 100644
index 00000000000..a0ed9557685
--- /dev/null
+++ b/library/core/src/ops/control_flow.rs
@@ -0,0 +1,67 @@
+use crate::ops::Try;
+
+/// Used to make try_fold closures more like normal loops
+#[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum ControlFlow<C, B> {
+    /// Continue in the loop, using the given value for the next iteration
+    Continue(C),
+    /// Exit the loop, yielding the given value
+    Break(B),
+}
+
+#[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
+impl<C, B> Try for ControlFlow<C, B> {
+    type Ok = C;
+    type Error = B;
+    #[inline]
+    fn into_result(self) -> Result<Self::Ok, Self::Error> {
+        match self {
+            ControlFlow::Continue(y) => Ok(y),
+            ControlFlow::Break(x) => Err(x),
+        }
+    }
+    #[inline]
+    fn from_error(v: Self::Error) -> Self {
+        ControlFlow::Break(v)
+    }
+    #[inline]
+    fn from_ok(v: Self::Ok) -> Self {
+        ControlFlow::Continue(v)
+    }
+}
+
+impl<C, B> ControlFlow<C, B> {
+    /// Converts the `ControlFlow` into an `Option` which is `Some` if the
+    /// `ControlFlow` was `Break` and `None` otherwise.
+    #[inline]
+    #[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
+    pub fn break_value(self) -> Option<B> {
+        match self {
+            ControlFlow::Continue(..) => None,
+            ControlFlow::Break(x) => Some(x),
+        }
+    }
+}
+
+impl<R: Try> ControlFlow<R::Ok, R> {
+    /// Create a `ControlFlow` from any type implementing `Try`.
+    #[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
+    #[inline]
+    pub fn from_try(r: R) -> Self {
+        match Try::into_result(r) {
+            Ok(v) => ControlFlow::Continue(v),
+            Err(v) => ControlFlow::Break(Try::from_error(v)),
+        }
+    }
+
+    /// Convert a `ControlFlow` into any type implementing `Try`;
+    #[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
+    #[inline]
+    pub fn into_try(self) -> R {
+        match self {
+            ControlFlow::Continue(v) => Try::from_ok(v),
+            ControlFlow::Break(v) => v,
+        }
+    }
+}
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
index c19bd6e441e..befc644054f 100644
--- a/library/core/src/ops/mod.rs
+++ b/library/core/src/ops/mod.rs
@@ -148,6 +148,7 @@ mod index;
 mod range;
 mod r#try;
 mod unsize;
+mod control_flow;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::arith::{Add, Div, Mul, Neg, Rem, Sub};
@@ -191,3 +192,6 @@ pub use self::unsize::CoerceUnsized;
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
 pub use self::unsize::DispatchFromDyn;
+
+#[unstable(feature="control_flow_enum", reason="new API", issue="75744")]
+pub use self::control_flow::ControlFlow;