diff options
author | Daniel Baumann <daniel@debian.org> | 2024-11-20 06:55:23 +0100 |
---|---|---|
committer | Daniel Baumann <daniel@debian.org> | 2024-11-20 06:55:23 +0100 |
commit | ef3db3079ea065cf9df4cbbcac995d546ca5613e (patch) | |
tree | caeee98b4b9981506890992396a2d54d46042beb /src | |
parent | Initial commit. (diff) | |
download | rust-soft-assert-ef3db3079ea065cf9df4cbbcac995d546ca5613e.tar.xz rust-soft-assert-ef3db3079ea065cf9df4cbbcac995d546ca5613e.zip |
Adding upstream version 0.1.1.upstream/0.1.1upstream
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..024ba0e --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,310 @@ +#![deny(missing_docs)]
+#![no_std]
+
+//! A set of macros similar to the standard library's `assert_*` macros, but return early instead of panicking.
+//! # Example
+//! ```
+//! use soft_assert::*;
+//!
+//! fn not_twenty(x: i32) -> Option<i32> {
+//! // This will return `Option::default()`, which is `None`
+//! soft_assert_ne!(x, 20);
+//! Some(x)
+//! }
+//!
+//! fn double_if_greater_than_5(x: i32) -> i32 {
+//! // But here we don't want to return `i32::default()`,
+//! // so we specify a return value.
+//! soft_assert!(x > 5, x);
+//! x * 2
+//! }
+//!
+//! fn main() {
+//! assert!(not_twenty(10).is_some());
+//! assert!(not_twenty(20).is_none());
+//!
+//! let doubled = double_if_greater_than_5(13);
+//! assert_eq!(doubled, 26);
+//! let not_doubled = double_if_greater_than_5(2);
+//! assert_eq!(not_doubled, 2);
+//! }
+//!
+//! ```
+//!
+//! This crate is `#![no_std]`
+
+#[macro_export]
+/// Asserts a condition is true, returning otherwise.
+///
+/// Non-panicking version of [`assert`](https://doc.rust-lang.org/std/macro.assert.html).
+///
+/// # Custom return values
+/// Unless otherwise specified, this will return the default value of the return type (if it has one).
+/// A custom value can be returned instead by supplying it as an additional argument (similar to `assert`'s custom message),
+/// i.e. `soft_assert!(false, Err(e))`. Ownership of any captured values is only taken if the assertion fails, so you can
+/// continue to use them later on.
+///
+/// This does *not* perform `Err(..)`-wrapping, to allow returning any value.
+macro_rules! soft_assert {
+ ($e:expr) => {
+ if !$e {
+ return Default::default();
+ }
+ };
+ ($e:expr,) => {
+ $crate::soft_assert!($e)
+ };
+ ($e:expr, $failed:expr) => {
+ if !$e {
+ return $failed;
+ }
+ };
+ ($e:expr, $failed:expr,) => {
+ $crate::soft_assert!($e)
+ };
+}
+
+/// Asserts two values are equal, returning otherwise.
+///
+/// Non-panicking version of [`assert_eq`](https://doc.rust-lang.org/std/macro.assert_eq.html).
+///
+/// # Custom return values
+/// Unless otherwise specified, this will return the default value of the return type (if it has one).
+/// A custom value can be returned instead by supplying it as an additional argument (similar to `assert`'s custom message),
+/// i.e. `soft_assert_eq!(1, 2, Err(e))`. Ownership of any captured values is only taken if the assertion fails, so you can
+/// continue to use them later on.
+///
+/// This does *not* perform `Err(..)`-wrapping, to allow returning any value.
+#[macro_export]
+macro_rules! soft_assert_eq {
+ ($x:expr, $y:expr) => {
+ if { $x } != { $y } {
+ return Default::default();
+ }
+ };
+ ($x:expr, $y:expr,) => {
+ $crate::soft_assert_eq!($x, $y)
+ };
+ ($x:expr, $y:expr, $failed:expr) => {
+ if { $x } != { $y } {
+ return $failed;
+ }
+ };
+ ($x:expr, $y:expr, $failed:expr,) => {
+ $crate::soft_assert_eq!($x, $y, $failed)
+ };
+}
+
+/// Asserts two values are not equal, returning otherwise.
+///
+/// Non-panicking version of [`assert_ne`](https://doc.rust-lang.org/std/macro.assert_ne.html).
+///
+/// # Custom return values
+/// Unless otherwise specified, this will return the default value of the return type (if it has one).
+/// A custom value can be returned instead by supplying it as an additional argument (similar to `assert`'s custom message),
+/// i.e. `soft_assert_ne!(2 + 2, 4, Err(e))`. Ownership of any captured values is only taken if the assertion fails, so you can
+/// continue to use them later on.
+///
+/// This does *not* perform `Err(..)`-wrapping, to allow returning any value.
+#[macro_export]
+macro_rules! soft_assert_ne {
+ ($x:expr, $y:expr) => {
+ if { $x } == { $y } {
+ return Default::default();
+ }
+ };
+ ($x:expr, $y:expr,) => {
+ $crate::soft_assert_ne!($x, $y)
+ };
+ ($x:expr, $y:expr, $failed:expr) => {
+ if { $x } == { $y } {
+ return $failed;
+ }
+ };
+ ($x:expr, $y:expr, $failed:expr,) => {
+ $crate::soft_assert_ne!($x, $y, $failed)
+ };
+}
+
+#[macro_export]
+/// Asserts a value matches a pattern, returning otherwise.
+///
+/// Non-panicking version of [`assert_matches`](https://doc.rust-lang.org/std/assert_matches/macro.assert_matches.html).
+///
+/// # Custom return values
+/// Unless otherwise specified, this will return the default value of the return type (if it has one).
+/// A custom value can be returned instead by supplying it as an additional argument (similar to `assert`'s custom message),
+/// i.e. `soft_assert_matches!(x, None, Err(e))`. Ownership of any captured values is only taken if the assertion fails, so you can
+/// continue to use them later on.
+///
+/// This does *not* perform `Err(..)`-wrapping, to allow returning any value.
+macro_rules! soft_assert_matches {
+ ($e:expr, $p:pat) => {
+ match $e {
+ $p => (),
+ _ => return Default::default();
+ }
+ };
+ ($e:expr, $p:pat,) => {
+ $crate::soft_assert_matches!($x, $y)
+ };
+ ($e:expr, $p:pat, $failed:expr) => {
+ match $e {
+ $p => (),
+ _ => return $failed;
+ }
+ };
+ ($e:expr, $p:pat, $failed:expr,) => {
+ $crate::soft_assert_matches!($x, $y, $failed)
+ };
+}
+
+/// If debug assertions are enabled, asserts a condition is true, returning otherwise.
+///
+/// Non-panicking version of [`debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
+///
+/// # Custom return values
+/// Unless otherwise specified, this will return the default value of the return type (if it has one).
+/// A custom value can be returned instead by supplying it as an additional argument (similar to `assert`'s custom message),
+/// i.e. `soft_debug_assert!(false, Err(e))`. Ownership of the value is only taken if the assertion fails, so you can
+/// continue to use them later on.
+///
+/// This does *not* perform `Err(..)`-wrapping, to allow returning any value.
+#[macro_export]
+macro_rules! soft_debug_assert {
+ ($e:expr) => {
+ #[cfg(debug_assertions)]
+ $crate::soft_assert!($e);
+ };
+ ($e:expr,) => {
+ $crate::soft_debug_assert!($e);
+ };
+ ($e:expr, $failed:expr) => {
+ #[cfg(debug_assertions)]
+ $crate::soft_assert!($e, $failed);
+ };
+ ($e:expr, $failed:expr,) => {
+ #[cfg(debug_assertions)]
+ $crate::soft_assert!($e, $failed);
+ };
+}
+
+/// If debug assertions are enabled, asserts two values are equal, returning otherwise.
+///
+/// Non-panicking version of [`debug_assert_eq`](https://doc.rust-lang.org/std/macro.debug_assert_eq.html).
+///
+/// # Custom return values
+/// Unless otherwise specified, this will return the default value of the return type (if it has one).
+/// A custom value can be returned instead by supplying it as an additional argument (similar to `assert`'s custom message),
+/// i.e. `soft_debug_assert_eq!(1, 2, Err(e))`. Ownership of the value is only taken if the assertion fails, so you can
+/// continue to use them later on.
+///
+/// This does *not* perform `Err(..)`-wrapping, to allow returning any value.
+#[macro_export]
+macro_rules! soft_debug_assert_eq {
+ ($x:expr, $y:expr) => {
+ #[cfg(debug_assertions)]
+ $crate::soft_assert_eq!($x, $y);
+ };
+ ($x:expr, $y:expr,) => {
+ $crate::soft_debug_assert_eq!($x, $y);
+ };
+ ($x:expr, $y:expr, $failed:expr) => {
+ #[cfg(debug_assertions)]
+ $crate::soft_assert_eq!($x, $y, $failed);
+ };
+ ($x:expr, $y:expr, $failed:expr,) => {
+ $crate::soft_debug_assert_eq!($x, $y, $failed);
+ };
+}
+
+/// If debug assertions are enabled, asserts two values are not equal, returning otherwise.
+///
+/// Non-panicking version of [`debug_assert_ne`](https://doc.rust-lang.org/std/macro.debug_assert.html).
+///
+/// # Custom return values
+/// Unless otherwise specified, this will return the default value of the return type (if it has one).
+/// A custom value can be returned instead by supplying it as an additional argument (similar to `assert`'s custom message),
+/// i.e. `soft_debug_assert_ne!(2 + 2, 4, Err(e))`. Ownership of the value is only taken if the assertion fails, so you can
+/// continue to use them later on.
+///
+/// This does *not* perform `Err(..)`-wrapping, to allow returning any value.
+#[macro_export]
+macro_rules! soft_debug_assert_ne {
+ ($x:expr, $y:expr) => {
+ #[cfg(debug_assertions)]
+ $crate::soft_assert_ne!($x, $y);
+ };
+ ($x:expr, $y:expr,) => {
+ $crate::soft_debug_assert_ne!($x, $y);
+ };
+ ($x:expr, $y:expr, $failed:expr) => {
+ #[cfg(debug_assertions)]
+ $crate::soft_assert_ne!($x, $y, $failed);
+ };
+ ($x:expr, $y:expr, $failed:expr,) => {
+ $crate::soft_debug_assert_ne!($x, $y, $failed);
+ };
+}
+
+#[macro_export]
+/// Asserts a value matches a pattern, returning otherwise.
+///
+/// Non-panicking version of [`debug_assert_matches`](https://doc.rust-lang.org/std/assert_matches/macro.debug_assert_matches.html).
+///
+/// # Custom return values
+/// Unless otherwise specified, this will return the default value of the return type (if it has one).
+/// A custom value can be returned instead by supplying it as an additional argument (similar to `assert`'s custom message),
+/// i.e. `soft_debug_assert_match!(x, None, Err(e))`. Ownership of any captured values is only taken if the assertion fails, so you can
+/// continue to use them later on.
+///
+/// This does *not* perform `Err(..)`-wrapping, to allow returning any value.
+macro_rules! soft_debug_assert_matches {
+ ($e:expr, $p:pat) => {
+ #[cfg(debug_assertions)]
+ $crate::soft_assert_match!($e, $p);
+ };
+ ($e:expr, $p:pat,) => {
+ $crate::soft_debug_assert_match!($e, $p);
+ };
+ ($e:expr, $p:pat, $failed:expr) => {
+ #[cfg(debug_assertions)]
+ $crate::soft_assert_match!($e, $p, $failed);
+ };
+ ($e:expr, $p:pat, $failed:expr,) => {
+ $crate::soft_debug_assert_match!($e, $p, $failed);
+ };
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test() {
+ assert!((|| {
+ soft_assert!(true, false);
+ true
+ })());
+ assert!((|| {
+ soft_assert!(false, true);
+ false
+ })());
+ assert!((|| {
+ soft_assert_eq!((1..=10).sum::<i32>(), 55, false);
+ true
+ })());
+ assert!((|| {
+ soft_assert_eq!((1..=10).sum::<i32>(), 3141, true);
+ false
+ })());
+ assert!((|| {
+ soft_assert_ne!((1..=10).sum::<i32>(), 3151, false);
+ true
+ })());
+ assert!((|| {
+ soft_assert_ne!((1..=10).sum::<i32>(), 55, true);
+ false
+ })());
+ }
+}
|