summaryrefslogtreecommitdiffstats
path: root/third_party/rust/matches/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/matches/lib.rs')
-rw-r--r--third_party/rust/matches/lib.rs161
1 files changed, 161 insertions, 0 deletions
diff --git a/third_party/rust/matches/lib.rs b/third_party/rust/matches/lib.rs
new file mode 100644
index 0000000000..262f8d0764
--- /dev/null
+++ b/third_party/rust/matches/lib.rs
@@ -0,0 +1,161 @@
+#![no_std]
+//! A macro to evaluate, as a boolean, whether an expression matches a pattern.
+//!
+//! For users who build using only Rust 1.42 and newer, consider using [`std::matches`], which
+//! is included in the [standard library prelude] and thus is automatically in scope.
+//!
+//! [`std::matches`]: core::matches
+//! [standard library prelude]: https://doc.rust-lang.org/stable/reference/names/preludes.html
+//!
+//! # Examples
+//!
+//! ```
+//! #[macro_use]
+//! extern crate matches;
+//!
+//! #[derive(Debug)]
+//! pub enum Foo<T> {
+//! A,
+//! B(T),
+//! }
+//!
+//! impl<T> Foo<T> {
+//! pub fn is_b(&self) -> bool {
+//! matches!(*self, Foo::B(_))
+//! }
+//! }
+//!
+//! impl<T: core::fmt::Debug> Foo<T> {
+//! pub fn assert_is_b(&self) {
+//! assert_matches!(&self, Foo::B(_));
+//! }
+//! }
+//! # fn main() { }
+//! ```
+
+/// Check if an expression matches a refutable pattern.
+///
+/// Syntax: `matches!(` *expression* `,` *pattern* `)`
+///
+/// Return a boolean, true if the expression matches the pattern, false otherwise.
+///
+/// # Examples
+///
+/// ```
+/// #[macro_use]
+/// extern crate matches;
+///
+/// pub enum Foo<T> {
+/// A,
+/// B(T),
+/// }
+///
+/// impl<T> Foo<T> {
+/// pub fn is_a(&self) -> bool {
+/// matches!(*self, Foo::A)
+/// }
+///
+/// pub fn is_b(&self) -> bool {
+/// matches!(*self, Foo::B(_))
+/// }
+/// }
+///
+/// # fn main() { }
+/// ```
+#[macro_export]
+macro_rules! matches {
+ ($expression:expr, $($pattern:tt)+) => {
+ match $expression {
+ $($pattern)+ => true,
+ _ => false
+ }
+ }
+}
+
+/// Assert that an expression matches a refutable pattern.
+///
+/// Syntax: `assert_matches!(` *expression* `,` *pattern* `)`
+///
+/// Panic with a message that shows the expression if it does not match the
+/// pattern.
+///
+/// # Examples
+///
+/// ```
+/// #[macro_use]
+/// extern crate matches;
+///
+/// fn main() {
+/// let data = [1, 2, 3];
+/// assert_matches!(data.get(1), Some(_));
+/// }
+/// ```
+#[macro_export]
+macro_rules! assert_matches {
+ ($expression:expr, $($pattern:tt)+) => {
+ match $expression {
+ $($pattern)+ => (),
+ ref e => panic!("assertion failed: `{:?}` does not match `{}`", e, stringify!($($pattern)+)),
+ }
+ }
+}
+
+/// Assert that an expression matches a refutable pattern using debug assertions.
+///
+/// Syntax: `debug_assert_matches!(` *expression* `,` *pattern* `)`
+///
+/// If debug assertions are enabled, panic with a message that shows the
+/// expression if it does not match the pattern.
+///
+/// When debug assertions are not enabled, this macro does nothing.
+///
+/// # Examples
+///
+/// ```
+/// #[macro_use]
+/// extern crate matches;
+///
+/// fn main() {
+/// let data = [1, 2, 3];
+/// debug_assert_matches!(data.get(1), Some(_));
+/// }
+/// ```
+#[macro_export]
+macro_rules! debug_assert_matches {
+ ($expression:expr, $($pattern:tt)+) => {
+ if cfg!(debug_assertions) {
+ match $expression {
+ $($pattern)+ => (),
+ ref e => panic!("assertion failed: `{:?}` does not match `{}`", e, stringify!($($pattern)+)),
+ }
+ }
+ }
+}
+
+#[test]
+fn matches_works() {
+ let foo = Some("-12");
+ assert!(matches!(foo, Some(bar) if
+ matches!(bar.as_bytes()[0], b'+' | b'-') &&
+ matches!(bar.as_bytes()[1], b'0'...b'9')
+ ));
+}
+
+#[test]
+fn assert_matches_works() {
+ let foo = Some("-12");
+ assert_matches!(foo, Some(bar) if
+ matches!(bar.as_bytes()[0], b'+' | b'-') &&
+ matches!(bar.as_bytes()[1], b'0'...b'9')
+ );
+}
+
+#[test]
+#[should_panic(expected = "assertion failed: `Some(\"-AB\")` does not match ")]
+fn assert_matches_panics() {
+ let foo = Some("-AB");
+ assert_matches!(foo, Some(bar) if
+ matches!(bar.as_bytes()[0], b'+' | b'-') &&
+ matches!(bar.as_bytes()[1], b'0'...b'9')
+ );
+}