diff --git a/src/assert_any.rs b/src/assert_any/assert_any.rs
similarity index 100%
rename from src/assert_any.rs
rename to src/assert_any/assert_any.rs
diff --git a/src/assert_any/assert_any_eq.rs b/src/assert_any/assert_any_eq.rs
new file mode 100644
index 00000000..025a92f4
--- /dev/null
+++ b/src/assert_any/assert_any_eq.rs
@@ -0,0 +1,267 @@
+//! Assert an iter contains an element.
+//!
+//! Pseudocode:
+//! (collection1 into iter) contains (item)
+//!
+//! # Example
+//!
+//! ```rust
+//! use assertables::*;
+//!
+//! let a = [1, 2];
+//! let b = 1;
+//! assert_any_eq!(&a, &b);
+//! ```
+//!
+//! This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+//!
+//! # Module macros
+//!
+//! * [`assert_any_eq`](macro@crate::assert_any_eq)
+//! * [`assert_any_eq_as_result`](macro@crate::assert_any_eq_as_result)
+//! * [`debug_assert_any_eq`](macro@crate::debug_assert_any_eq)
+
+/// Assert an iter contains an element.
+///
+/// Pseudocode:
+/// (collection1 into iter) contains (item)
+///
+/// * If true, return Result `Ok(())`.
+///
+/// * Otherwise, return Result `Err(message)`.
+///
+/// This macro is useful for runtime checks, such as checking parameters,
+/// or sanitizing inputs, or handling different results in different ways.
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_eq`](macro@crate::assert_any_eq)
+/// * [`assert_any_eq_as_result`](macro@crate::assert_any_eq_as_result)
+/// * [`debug_assert_any_eq`](macro@crate::debug_assert_any_eq)
+///
+#[macro_export]
+macro_rules! assert_any_eq_as_result {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match ($a_collection, $b_item) {
+ (a_collection, b_item) => {
+ let mut a = a_collection.into_iter();
+ if a.any(|x| x == b_item) {
+ Ok(())
+ } else {
+ Err(format!(
+ concat!(
+ "assertion failed: `assert_any_eq!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_eq.html\n",
+ " a label: `{}`,\n",
+ " a debug: `{:?}`,\n",
+ " b label: `{}`,\n",
+ " b debug: `{:?}`"
+ ),
+ stringify!($a_collection),
+ a_collection,
+ stringify!($b_item),
+ b_item
+ ))
+ }
+ }
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_eq_as_result {
+ // use std::sync::Once;
+
+ #[test]
+ fn success_int() {
+ let a = [1, 2];
+ let b = 1;
+ for _ in 0..1 {
+ let actual = assert_any_eq_as_result!(&a, &b);
+ assert_eq!(actual.unwrap(), ());
+ }
+ }
+
+ #[test]
+ fn success_struct() {
+ #[derive(Debug, PartialEq)]
+ struct Point {
+ x: i32,
+ y: i32,
+ }
+ let points: [Point; 2] = [Point { x: 1, y: 2 }, Point { x: 2, y: 3 }];
+ let point = Point { x: 1, y: 2 };
+ for _ in 0..1 {
+ let actual = assert_any_eq_as_result!(&points, &point);
+ assert_eq!(actual.unwrap(), ());
+ }
+ }
+
+ #[test]
+ fn failure() {
+ let a = [1, 2];
+ let b = 0;
+ let actual = assert_any_eq_as_result!(&a, &b);
+ let message = concat!(
+ "assertion failed: `assert_any_eq!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_eq.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[1, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `0`"
+ );
+ assert_eq!(actual.unwrap_err(), message);
+ }
+}
+
+/// Assert an iterable is equal to another.
+///
+/// Pseudocode:
+/// (collection1 into iter) = (collection2 into iter)
+///
+/// * If true, return `()`.
+///
+/// * Otherwise, call [`panic!`] with a message and the values of the
+/// expressions with their debug representations.
+///
+/// # Examples
+///
+/// ```rust
+/// use assertables::*;
+/// # use std::panic;
+///
+/// # fn main() {
+/// let a = [1, 2];
+/// let b = 1;
+/// assert_any_eq!(&a, &b);
+///
+/// # let result = panic::catch_unwind(|| {
+/// // This will panic
+/// let a = [1, 2];
+/// let b = 0;
+/// assert_any_eq!(&a, &b);
+/// # });
+/// // assertion failed: `assert_any_eq!(a_collection, b_item)`
+/// // https://docs.rs/assertables/…/assertables/macro.assert_any_eq.html
+/// // a label: `&a`,
+/// // a debug: `[1, 2]`,
+/// // b label: `&b`,
+/// // b debug: `0`
+/// # let actual = result.unwrap_err().downcast::().unwrap().to_string();
+/// # let message = concat!(
+/// # "assertion failed: `assert_any_eq!(a_collection, b_item)`\n",
+/// # "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_eq.html\n",
+/// # " a label: `&a`,\n",
+/// # " a debug: `[1, 2]`,\n",
+/// # " b label: `&b`,\n",
+/// # " b debug: `0`",
+/// # );
+/// # assert_eq!(actual, message);
+/// # }
+/// ```
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_eq`](macro@crate::assert_any_eq)
+/// * [`assert_any_eq_as_result`](macro@crate::assert_any_eq_as_result)
+/// * [`debug_assert_any_eq`](macro@crate::debug_assert_any_eq)
+///
+#[macro_export]
+macro_rules! assert_any_eq {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match $crate::assert_any_eq_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}", err),
+ }
+ };
+ ($a_collection:expr, $b_item:expr, $($message:tt)+) => {
+ match $crate::assert_any_eq_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_eq {
+ use std::panic;
+
+ #[test]
+ fn success() {
+ let a = [1, 2];
+ let b = 2;
+ for _ in 0..1 {
+ let actual = assert_any_eq!(&a, &b);
+ assert_eq!(actual, ());
+ }
+ }
+
+ #[test]
+ fn failure() {
+ let a = [1, 2];
+ let b = 0;
+ let result = panic::catch_unwind(|| {
+ let _actual = assert_any_eq!(&a, &b);
+ });
+ let message = concat!(
+ "assertion failed: `assert_any_eq!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_eq.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[1, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `0`"
+ );
+ assert_eq!(
+ result
+ .unwrap_err()
+ .downcast::()
+ .unwrap()
+ .to_string(),
+ message
+ );
+ }
+}
+
+/// Assert an iterable is equal to another.
+///
+/// Pseudocode:
+/// (collection1 into iter) = (collection2 into iter)
+///
+/// This macro provides the same statements as [`assert_any_eq`](macro.assert_any_eq.html),
+/// except this macro's statements are only enabled in non-optimized
+/// builds by default. An optimized build will not execute this macro's
+/// statements unless `-C debug-assertions` is passed to the compiler.
+///
+/// This macro is useful for checks that are too expensive to be present
+/// in a release build but may be helpful during development.
+///
+/// The result of expanding this macro is always type checked.
+///
+/// An unchecked assertion allows a program in an inconsistent state to
+/// keep running, which might have unexpected consequences but does not
+/// introduce unsafety as long as this only happens in safe code. The
+/// performance cost of assertions, however, is not measurable in general.
+/// Replacing `assert*!` with `debug_assert*!` is thus only encouraged
+/// after thorough profiling, and more importantly, only in safe code!
+///
+/// This macro is intended to work in a similar way to
+/// [`::std::debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_eq`](macro@crate::assert_any_eq)
+/// * [`assert_any_eq`](macro@crate::assert_any_eq)
+/// * [`debug_assert_any_eq`](macro@crate::debug_assert_any_eq)
+///
+#[macro_export]
+macro_rules! debug_assert_any_eq {
+ ($($arg:tt)*) => {
+ if $crate::cfg!(debug_assertions) {
+ $crate::assert_any_eq!($($arg)*);
+ }
+ };
+}
diff --git a/src/assert_any/assert_any_ge.rs b/src/assert_any/assert_any_ge.rs
new file mode 100644
index 00000000..3e387b57
--- /dev/null
+++ b/src/assert_any/assert_any_ge.rs
@@ -0,0 +1,293 @@
+//! Assert an iter is greater than or equal to another.
+//!
+//! Pseudocode:
+//! (collection into iter) ≥ item
+//!
+//! # Example
+//!
+//! ```rust
+//! use assertables::*;
+//!
+//! let a = [1, 2];
+//! let b = 2;
+//! assert_any_ge!(&a, &b);
+//! ```
+//!
+//! This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+//!
+//! # Module macros
+//!
+//! * [`assert_any_ge`](macro@crate::assert_any_ge)
+//! * [`assert_any_ge_as_result`](macro@crate::assert_any_ge_as_result)
+//! * [`debug_assert_any_ge`](macro@crate::debug_assert_any_ge)
+
+/// Assert an iterable is greater than or equal to another.
+///
+/// Pseudocode:
+/// (collection into iter) ≥ item
+///
+/// * If true, return Result `Ok(())`.
+///
+/// * Otherwise, return Result `Err(message)`.
+///
+/// This macro is useful for runtime checks, such as checking parameters,
+/// or sanitizing inputs, or handling different results in different ways.
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_ge`](macro@crate::assert_any_ge)
+/// * [`assert_any_ge_as_result`](macro@crate::assert_any_ge_as_result)
+/// * [`debug_assert_any_ge`](macro@crate::debug_assert_any_ge)
+///
+#[macro_export]
+macro_rules! assert_any_ge_as_result {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match ($a_collection, $b_item) {
+ (a_collection, b_item) => {
+ let mut a = a_collection.into_iter();
+ if a.any(|x| x >= b_item) {
+ Ok(())
+ } else {
+ Err(format!(
+ concat!(
+ "assertion failed: `assert_any_ge!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_ge.html\n",
+ " a label: `{}`,\n",
+ " a debug: `{:?}`,\n",
+ " b label: `{}`,\n",
+ " b debug: `{:?}`"
+ ),
+ stringify!($a_collection),
+ a_collection,
+ stringify!($b_item),
+ b_item
+ ))
+ }
+ }
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_ge_as_result {
+ // use std::sync::Once;
+
+ #[test]
+ fn gt() {
+ let a = [3, 7];
+ let b = 5;
+ for _ in 0..1 {
+ let actual = assert_any_ge_as_result!(&a, &b);
+ assert_eq!(actual.unwrap(), ());
+ }
+ }
+
+ #[test]
+ fn eq() {
+ let a = [1, 2];
+ let b = 1;
+ for _ in 0..1 {
+ let actual = assert_any_ge_as_result!(&a, &b);
+ assert_eq!(actual.unwrap(), ());
+ }
+ }
+
+ #[test]
+ fn lt() {
+ let a = [1, 2];
+ let b = 3;
+ let actual = assert_any_ge_as_result!(&a, &b);
+ let message = concat!(
+ "assertion failed: `assert_any_ge!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_ge.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[1, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `3`"
+ );
+ assert_eq!(actual.unwrap_err(), message);
+ }
+
+ #[test]
+ fn success_struct() {
+ use std::cmp::Ordering;
+ #[derive(Debug, PartialEq)]
+ struct Point {
+ x: i32,
+ }
+ impl PartialOrd for Point {
+ fn partial_cmp(&self, other: &Self) -> Option {
+ // Reuses the implementation of the field's type (u32)
+ self.x.partial_cmp(&other.x)
+ }
+ }
+ let points: [Point; 2] = [Point { x: 1 }, Point { x: 2 }];
+ let point = Point { x: 1 };
+ for _ in 0..1 {
+ let actual = assert_any_ge_as_result!(&points, &point);
+ assert_eq!(actual.unwrap(), ());
+ }
+ }
+}
+
+/// Assert an iterable is greater than or equal to another.
+///
+/// Pseudocode:
+/// (collection into iter) ≥ item
+///
+/// * If true, return `()`.
+///
+/// * Otherwise, call [`panic!`] with a message and the values of the
+/// expressions with their debug representations.
+///
+/// # Examples
+///
+/// ```rust
+/// use assertables::*;
+/// # use std::panic;
+///
+/// # fn main() {
+/// let a = [3, 4];
+/// let b = 4;
+/// assert_any_ge!(&a, &b);
+///
+/// # let result = panic::catch_unwind(|| {
+/// // This will panic
+/// let a = [1, 2];
+/// let b = 5;
+/// assert_any_ge!(&a, &b);
+/// # });
+/// // assertion failed: `assert_any_ge!(a_collection, b_item)`
+/// // https://docs.rs/assertables/…/assertables/macro.assert_any_ge.html
+/// // a label: `&a`,
+/// // a debug: `[1, 2]`,
+/// // b label: `&b`,
+/// // b debug: `5`
+/// # let actual = result.unwrap_err().downcast::().unwrap().to_string();
+/// # let message = concat!(
+/// # "assertion failed: `assert_any_ge!(a_collection, b_item)`\n",
+/// # "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_ge.html\n",
+/// # " a label: `&a`,\n",
+/// # " a debug: `[1, 2]`,\n",
+/// # " b label: `&b`,\n",
+/// # " b debug: `5`",
+/// # );
+/// # assert_eq!(actual, message);
+/// # }
+/// ```
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_ge`](macro@crate::assert_any_ge)
+/// * [`assert_any_ge_as_result`](macro@crate::assert_any_ge_as_result)
+/// * [`debug_assert_any_ge`](macro@crate::debug_assert_any_ge)
+///
+#[macro_export]
+macro_rules! assert_any_ge {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match $crate::assert_any_ge_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}", err),
+ }
+ };
+ ($a_collection:expr, $b_item:expr, $($message:tt)+) => {
+ match $crate::assert_any_ge_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_ge {
+ use std::panic;
+
+ #[test]
+ fn gt() {
+ let a = [3, 7];
+ let b = 5;
+ for _ in 0..1 {
+ let actual = assert_any_ge!(&a, &b);
+ assert_eq!(actual, ());
+ }
+ }
+
+ #[test]
+ fn eq() {
+ let a = [1, 2];
+ let b = 2;
+ for _ in 0..1 {
+ let actual = assert_any_ge!(&a, &b);
+ assert_eq!(actual, ());
+ }
+ }
+
+ #[test]
+ fn lt() {
+ let a = [1, 2];
+ let b = 3;
+ let result = panic::catch_unwind(|| {
+ let _actual = assert_any_ge!(&a, &b);
+ });
+ let message = concat!(
+ "assertion failed: `assert_any_ge!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_ge.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[1, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `3`"
+ );
+ assert_eq!(
+ result
+ .unwrap_err()
+ .downcast::()
+ .unwrap()
+ .to_string(),
+ message
+ );
+ }
+}
+
+/// Assert an iterable is greater than or equal to another.
+///
+/// Pseudocode:
+/// (collection into iter) ≥ item
+///
+/// This macro provides the same statements as [`assert_any_ge`](macro.assert_any_ge.html),
+/// except this macro's statements are only enabled in non-optimized
+/// builds by default. An optimized build will not execute this macro's
+/// statements unless `-C debug-assertions` is passed to the compiler.
+///
+/// This macro is useful for checks that are too expensive to be present
+/// in a release build but may be helpful during development.
+///
+/// The result of expanding this macro is always type checked.
+///
+/// An unchecked assertion allows a program in an inconsistent state to
+/// keep running, which might have unexpected consequences but does not
+/// introduce unsafety as long as this only happens in safe code. The
+/// performance cost of assertions, however, is not measurable in general.
+/// Replacing `assert*!` with `debug_assert*!` is thus only encouraged
+/// after thorough profiling, and more importantly, only in safe code!
+///
+/// This macro is intended to work in a similar way to
+/// [`::std::debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_ge`](macro@crate::assert_any_ge)
+/// * [`assert_any_ge`](macro@crate::assert_any_ge)
+/// * [`debug_assert_any_ge`](macro@crate::debug_assert_any_ge)
+///
+#[macro_export]
+macro_rules! debug_assert_any_ge {
+ ($($arg:tt)*) => {
+ if $crate::cfg!(debug_assertions) {
+ $crate::assert_any_ge!($($arg)*);
+ }
+ };
+}
diff --git a/src/assert_any/assert_any_gt.rs b/src/assert_any/assert_any_gt.rs
new file mode 100644
index 00000000..85862cb1
--- /dev/null
+++ b/src/assert_any/assert_any_gt.rs
@@ -0,0 +1,293 @@
+//! Assert an iter is greater than another.
+//!
+//! Pseudocode:
+//! (collection into iter) > item
+//!
+//! # Example
+//!
+//! ```rust
+//! use assertables::*;
+//!
+//! let a = [3, 4];
+//! let b = 2;
+//! assert_any_gt!(&a, &b);
+//! ```
+//!
+//! This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+//!
+//! # Module macros
+//!
+//! * [`assert_any_gt`](macro@crate::assert_any_gt)
+//! * [`assert_any_gt_as_result`](macro@crate::assert_any_gt_as_result)
+//! * [`debug_assert_any_gt`](macro@crate::debug_assert_any_gt)
+
+/// Assert an iterable is greater than another.
+///
+/// Pseudocode:
+/// (collection into iter) > item
+///
+/// * If true, return Result `Ok(())`.
+///
+/// * Otherwise, return Result `Err(message)`.
+///
+/// This macro is useful for runtime checks, such as checking parameters,
+/// or sanitizing inputs, or handling different results in different ways.
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_gt`](macro@crate::assert_any_gt)
+/// * [`assert_any_gt_as_result`](macro@crate::assert_any_gt_as_result)
+/// * [`debug_assert_any_gt`](macro@crate::debug_assert_any_gt)
+///
+#[macro_export]
+macro_rules! assert_any_gt_as_result {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match ($a_collection, $b_item) {
+ (a_collection, b_item) => {
+ let mut a = a_collection.into_iter();
+ if a.any(|x| x > b_item) {
+ Ok(())
+ } else {
+ Err(format!(
+ concat!(
+ "assertion failed: `assert_any_gt!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_gt.html\n",
+ " a label: `{}`,\n",
+ " a debug: `{:?}`,\n",
+ " b label: `{}`,\n",
+ " b debug: `{:?}`"
+ ),
+ stringify!($a_collection),
+ a_collection,
+ stringify!($b_item),
+ b_item
+ ))
+ }
+ }
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_gt_as_result {
+ // use std::sync::Once;
+
+ #[test]
+ fn gt() {
+ let a = [3, 7];
+ let b = 4;
+ for _ in 0..1 {
+ let actual = assert_any_gt_as_result!(&a, &b);
+ assert_eq!(actual.unwrap(), ());
+ }
+ }
+
+ #[test]
+ fn eq() {
+ let a = [1, 2];
+ let b = 2;
+ let actual = assert_any_gt_as_result!(&a, &b);
+ let message = concat!(
+ "assertion failed: `assert_any_gt!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_gt.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[1, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `2`"
+ );
+ assert_eq!(actual.unwrap_err(), message);
+ }
+
+ #[test]
+ fn lt() {
+ let a = [1, 2];
+ let b = 5;
+ let actual = assert_any_gt_as_result!(&a, &b);
+ let message = concat!(
+ "assertion failed: `assert_any_gt!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_gt.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[1, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `5`"
+ );
+ assert_eq!(actual.unwrap_err(), message);
+ }
+}
+
+/// Assert an iterable is greater than another.
+///
+/// Pseudocode:
+/// (collection into iter) > item
+///
+/// * If true, return `()`.
+///
+/// * Otherwise, call [`panic!`] with a message and the values of the
+/// expressions with their debug representations.
+///
+/// # Examples
+///
+/// ```rust
+/// use assertables::*;
+/// # use std::panic;
+///
+/// # fn main() {
+/// let a = [3, 4];
+/// let b = 3;
+/// assert_any_gt!(&a, &b);
+///
+/// # let result = panic::catch_unwind(|| {
+/// // This will panic
+/// let a = [1, 2];
+/// let b = 2;
+/// assert_any_gt!(&a, &b);
+/// # });
+/// // assertion failed: `assert_any_gt!(a_collection, b_item)`
+/// // https://docs.rs/assertables/…/assertables/macro.assert_any_gt.html
+/// // a label: `&a`,
+/// // a debug: `[1, 2]`,
+/// // b label: `&b`,
+/// // b debug: `2`
+/// # let actual = result.unwrap_err().downcast::().unwrap().to_string();
+/// # let message = concat!(
+/// # "assertion failed: `assert_any_gt!(a_collection, b_item)`\n",
+/// # "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_gt.html\n",
+/// # " a label: `&a`,\n",
+/// # " a debug: `[1, 2]`,\n",
+/// # " b label: `&b`,\n",
+/// # " b debug: `2`",
+/// # );
+/// # assert_eq!(actual, message);
+/// # }
+/// ```
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_gt`](macro@crate::assert_any_gt)
+/// * [`assert_any_gt_as_result`](macro@crate::assert_any_gt_as_result)
+/// * [`debug_assert_any_gt`](macro@crate::debug_assert_any_gt)
+///
+#[macro_export]
+macro_rules! assert_any_gt {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match $crate::assert_any_gt_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}", err),
+ }
+ };
+ ($a_collection:expr, $b_item:expr, $($message:tt)+) => {
+ match $crate::assert_any_gt_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_gt {
+ use std::panic;
+
+ #[test]
+ fn gt() {
+ let a = [3, 7];
+ let b = 4;
+ for _ in 0..1 {
+ let actual = assert_any_gt!(&a, &b);
+ assert_eq!(actual, ());
+ }
+ }
+
+ #[test]
+ fn eq() {
+ let a = [1, 2];
+ let b = 2;
+ let result = panic::catch_unwind(|| {
+ let _actual = assert_any_gt!(&a, &b);
+ });
+ let message = concat!(
+ "assertion failed: `assert_any_gt!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_gt.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[1, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `2`"
+ );
+ assert_eq!(
+ result
+ .unwrap_err()
+ .downcast::()
+ .unwrap()
+ .to_string(),
+ message
+ );
+ }
+
+ #[test]
+ fn lt() {
+ let a = [1, 2];
+ let b = 5;
+ let result = panic::catch_unwind(|| {
+ let _actual = assert_any_gt!(&a, &b);
+ });
+ let message = concat!(
+ "assertion failed: `assert_any_gt!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_gt.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[1, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `5`"
+ );
+ assert_eq!(
+ result
+ .unwrap_err()
+ .downcast::()
+ .unwrap()
+ .to_string(),
+ message
+ );
+ }
+}
+
+/// Assert an iterable is greater than another.
+///
+/// Pseudocode:
+/// (collection into iter) > item
+///
+/// This macro provides the same statements as [`assert_any_gt`](macro.assert_any_gt.html),
+/// except this macro's statements are only enabled in non-optimized
+/// builds by default. An optimized build will not execute this macro's
+/// statements unless `-C debug-assertions` is passed to the compiler.
+///
+/// This macro is useful for checks that are too expensive to be present
+/// in a release build but may be helpful during development.
+///
+/// The result of expanding this macro is always type checked.
+///
+/// An unchecked assertion allows a program in an inconsistent state to
+/// keep running, which might have unexpected consequences but does not
+/// introduce unsafety as long as this only happens in safe code. The
+/// performance cost of assertions, however, is not measurable in general.
+/// Replacing `assert*!` with `debug_assert*!` is thus only encouraged
+/// after thorough profiling, and more importantly, only in safe code!
+///
+/// This macro is intended to work in a similar way to
+/// [`::std::debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_gt`](macro@crate::assert_any_gt)
+/// * [`assert_any_gt`](macro@crate::assert_any_gt)
+/// * [`debug_assert_any_gt`](macro@crate::debug_assert_any_gt)
+///
+#[macro_export]
+macro_rules! debug_assert_any_gt {
+ ($($arg:tt)*) => {
+ if $crate::cfg!(debug_assertions) {
+ $crate::assert_any_gt!($($arg)*);
+ }
+ };
+}
diff --git a/src/assert_any/assert_any_le.rs b/src/assert_any/assert_any_le.rs
new file mode 100644
index 00000000..ba555687
--- /dev/null
+++ b/src/assert_any/assert_any_le.rs
@@ -0,0 +1,272 @@
+//! Assert an iter is less than or equal to another.
+//!
+//! Pseudocode:
+//! (collection into iter) ≤ item
+//!
+//! # Example
+//!
+//! ```rust
+//! use assertables::*;
+//!
+//! let a = [1, 2];
+//! let b = 3;
+//! assert_any_le!(&a, &b);
+//! ```
+//!
+//! This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+//!
+//! # Module macros
+//!
+//! * [`assert_any_le`](macro@crate::assert_any_le)
+//! * [`assert_any_le_as_result`](macro@crate::assert_any_le_as_result)
+//! * [`debug_assert_any_le`](macro@crate::debug_assert_any_le)
+
+/// Assert an iterable is less than or equal to another.
+///
+/// Pseudocode:
+/// (collection into iter) ≤ item
+///
+/// * If true, return Result `Ok(())`.
+///
+/// * Otherwise, return Result `Err(message)`.
+///
+/// This macro is useful for runtime checks, such as checking parameters,
+/// or sanitizing inputs, or handling different results in different ways.
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_le`](macro@crate::assert_any_le)
+/// * [`assert_any_le_as_result`](macro@crate::assert_any_le_as_result)
+/// * [`debug_assert_any_le`](macro@crate::debug_assert_any_le)
+///
+#[macro_export]
+macro_rules! assert_any_le_as_result {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match ($a_collection, $b_item) {
+ (a_collection, b_item) => {
+ let mut a = a_collection.into_iter();
+ if a.any(|x| x <= b_item) {
+ Ok(())
+ } else {
+ Err(format!(
+ concat!(
+ "assertion failed: `assert_any_le!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_le.html\n",
+ " a label: `{}`,\n",
+ " a debug: `{:?}`,\n",
+ " b label: `{}`,\n",
+ " b debug: `{:?}`"
+ ),
+ stringify!($a_collection),
+ a_collection,
+ stringify!($b_item),
+ b_item
+ ))
+ }
+ }
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_le_as_result {
+ // use std::sync::Once;
+
+ #[test]
+ fn lt() {
+ let a = [1, 2];
+ let b = 2;
+ for _ in 0..1 {
+ let actual = assert_any_le_as_result!(&a, &b);
+ assert_eq!(actual.unwrap(), ());
+ }
+ }
+
+ #[test]
+ fn eq() {
+ let a = [1, 2];
+ let b = 1;
+ for _ in 0..1 {
+ let actual = assert_any_le_as_result!(&a, &b);
+ assert_eq!(actual.unwrap(), ());
+ }
+ }
+
+ #[test]
+ fn gt() {
+ let a = [3, 4];
+ let b = 2;
+ let actual = assert_any_le_as_result!(&a, &b);
+ let message = concat!(
+ "assertion failed: `assert_any_le!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_le.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[3, 4]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `2`"
+ );
+ assert_eq!(actual.unwrap_err(), message);
+ }
+}
+
+/// Assert an iterable is less than or equal to another.
+///
+/// Pseudocode:
+/// (collection into iter) ≤ item
+///
+/// * If true, return `()`.
+///
+/// * Otherwise, call [`panic!`] with a message and the values of the
+/// expressions with their debug representations.
+///
+/// # Examples
+///
+/// ```rust
+/// use assertables::*;
+/// # use std::panic;
+///
+/// # fn main() {
+/// let a = [1, 2];
+/// let b = 1;
+/// assert_any_le!(&a, &b);
+///
+/// # let result = panic::catch_unwind(|| {
+/// // This will panic
+/// let a = [3, 4];
+/// let b = 2;
+/// assert_any_le!(&a, &b);
+/// # });
+/// // assertion failed: `assert_any_le!(a_collection, b_item)`
+/// // https://docs.rs/assertables/…/assertables/macro.assert_any_le.html
+/// // a label: `&a`,
+/// // a debug: `[3, 4]`,
+/// // b label: `&b`,
+/// // b debug: `2`
+/// # let actual = result.unwrap_err().downcast::().unwrap().to_string();
+/// # let message = concat!(
+/// # "assertion failed: `assert_any_le!(a_collection, b_item)`\n",
+/// # "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_le.html\n",
+/// # " a label: `&a`,\n",
+/// # " a debug: `[3, 4]`,\n",
+/// # " b label: `&b`,\n",
+/// # " b debug: `2`",
+/// # );
+/// # assert_eq!(actual, message);
+/// # }
+/// ```
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_le`](macro@crate::assert_any_le)
+/// * [`assert_any_le_as_result`](macro@crate::assert_any_le_as_result)
+/// * [`debug_assert_any_le`](macro@crate::debug_assert_any_le)
+///
+#[macro_export]
+macro_rules! assert_any_le {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match $crate::assert_any_le_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}", err),
+ }
+ };
+ ($a_collection:expr, $b_item:expr, $($message:tt)+) => {
+ match $crate::assert_any_le_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_le {
+ use std::panic;
+
+ #[test]
+ fn lt() {
+ let a = [1, 2];
+ let b = 5;
+ for _ in 0..1 {
+ let actual = assert_any_le!(&a, &b);
+ assert_eq!(actual, ());
+ }
+ }
+
+ #[test]
+ fn eq() {
+ let a = [1, 2];
+ let b = 1;
+ for _ in 0..1 {
+ let actual = assert_any_le!(&a, &b);
+ assert_eq!(actual, ());
+ }
+ }
+
+ #[test]
+ fn gt() {
+ let a = [3, 4];
+ let b = 2;
+ let result = panic::catch_unwind(|| {
+ let _actual = assert_any_le!(&a, &b);
+ });
+ let message = concat!(
+ "assertion failed: `assert_any_le!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_le.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[3, 4]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `2`"
+ );
+ assert_eq!(
+ result
+ .unwrap_err()
+ .downcast::()
+ .unwrap()
+ .to_string(),
+ message
+ );
+ }
+}
+
+/// Assert an iterable is less than or equal to another.
+///
+/// Pseudocode:
+/// (collection into iter) ≤ item
+///
+/// This macro provides the same statements as [`assert_any_le`](macro.assert_any_le.html),
+/// except this macro's statements are only enabled in non-optimized
+/// builds by default. An optimized build will not execute this macro's
+/// statements unless `-C debug-assertions` is passed to the compiler.
+///
+/// This macro is useful for checks that are too expensive to be present
+/// in a release build but may be helpful during development.
+///
+/// The result of expanding this macro is always type checked.
+///
+/// An unchecked assertion allows a program in an inconsistent state to
+/// keep running, which might have unexpected consequences but does not
+/// introduce unsafety as long as this only happens in safe code. The
+/// performance cost of assertions, however, is not measurable in general.
+/// Replacing `assert*!` with `debug_assert*!` is thus only encouraged
+/// after thorough profiling, and more importantly, only in safe code!
+///
+/// This macro is intended to work in a similar way to
+/// [`::std::debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_le`](macro@crate::assert_any_le)
+/// * [`assert_any_le`](macro@crate::assert_any_le)
+/// * [`debug_assert_any_le`](macro@crate::debug_assert_any_le)
+///
+#[macro_export]
+macro_rules! debug_assert_any_le {
+ ($($arg:tt)*) => {
+ if $crate::cfg!(debug_assertions) {
+ $crate::assert_any_le!($($arg)*);
+ }
+ };
+}
diff --git a/src/assert_any/assert_any_lt.rs b/src/assert_any/assert_any_lt.rs
new file mode 100644
index 00000000..3b1cfd63
--- /dev/null
+++ b/src/assert_any/assert_any_lt.rs
@@ -0,0 +1,293 @@
+//! Assert an iter is less than another.
+//!
+//! Pseudocode:
+//! (collection into iter) < item
+//!
+//! # Example
+//!
+//! ```rust
+//! use assertables::*;
+//!
+//! let a = [1, 2];
+//! let b = 3;
+//! assert_any_lt!(&a, &b);
+//! ```
+//!
+//! This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+//!
+//! # Module macros
+//!
+//! * [`assert_any_lt`](macro@crate::assert_any_lt)
+//! * [`assert_any_lt_as_result`](macro@crate::assert_any_lt_as_result)
+//! * [`debug_assert_any_lt`](macro@crate::debug_assert_any_lt)
+
+/// Assert an iterable is less than another.
+///
+/// Pseudocode:
+/// (collection into iter) < item
+///
+/// * If true, return Result `Ok(())`.
+///
+/// * Otherwise, return Result `Err(message)`.
+///
+/// This macro is useful for runtime checks, such as checking parameters,
+/// or sanitizing inputs, or handling different results in different ways.
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_lt`](macro@crate::assert_any_lt)
+/// * [`assert_any_lt_as_result`](macro@crate::assert_any_lt_as_result)
+/// * [`debug_assert_any_lt`](macro@crate::debug_assert_any_lt)
+///
+#[macro_export]
+macro_rules! assert_any_lt_as_result {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match ($a_collection, $b_item) {
+ (a_collection, b_item) => {
+ let mut a = a_collection.into_iter();
+ if a.any(|x| x < b_item) {
+ Ok(())
+ } else {
+ Err(format!(
+ concat!(
+ "assertion failed: `assert_any_lt!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_lt.html\n",
+ " a label: `{}`,\n",
+ " a debug: `{:?}`,\n",
+ " b label: `{}`,\n",
+ " b debug: `{:?}`"
+ ),
+ stringify!($a_collection),
+ a_collection,
+ stringify!($b_item),
+ b_item
+ ))
+ }
+ }
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_lt_as_result {
+ // use std::sync::Once;
+
+ #[test]
+ fn lt() {
+ let a = [1, 2];
+ let b = 3;
+ for _ in 0..1 {
+ let actual = assert_any_lt_as_result!(&a, &b);
+ assert_eq!(actual.unwrap(), ());
+ }
+ }
+
+ #[test]
+ fn eq() {
+ let a = [1, 2];
+ let b = 1;
+ let actual = assert_any_lt_as_result!(&a, &b);
+ let message = concat!(
+ "assertion failed: `assert_any_lt!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_lt.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[1, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `1`"
+ );
+ assert_eq!(actual.unwrap_err(), message);
+ }
+
+ #[test]
+ fn gt() {
+ let a = [3, 4];
+ let b = 2;
+ let actual = assert_any_lt_as_result!(&a, &b);
+ let message = concat!(
+ "assertion failed: `assert_any_lt!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_lt.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[3, 4]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `2`"
+ );
+ assert_eq!(actual.unwrap_err(), message);
+ }
+}
+
+/// Assert an iterable is less than another.
+///
+/// Pseudocode:
+/// (collection into iter) < item
+///
+/// * If true, return `()`.
+///
+/// * Otherwise, call [`panic!`] with a message and the values of the
+/// expressions with their debug representations.
+///
+/// # Examples
+///
+/// ```rust
+/// use assertables::*;
+/// # use std::panic;
+///
+/// # fn main() {
+/// let a = [1, 2];
+/// let b = 3;
+/// assert_any_lt!(&a, &b);
+///
+/// # let result = panic::catch_unwind(|| {
+/// // This will panic
+/// let a = [3, 4];
+/// let b = 2;
+/// assert_any_lt!(&a, &b);
+/// # });
+/// // assertion failed: `assert_any_lt!(a_collection, b_item)`
+/// // https://docs.rs/assertables/…/assertables/macro.assert_any_lt.html
+/// // a label: `&a`,
+/// // a debug: `[3, 4]`,
+/// // b label: `&b`,
+/// // b debug: `2`
+/// # let actual = result.unwrap_err().downcast::().unwrap().to_string();
+/// # let message = concat!(
+/// # "assertion failed: `assert_any_lt!(a_collection, b_item)`\n",
+/// # "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_lt.html\n",
+/// # " a label: `&a`,\n",
+/// # " a debug: `[3, 4]`,\n",
+/// # " b label: `&b`,\n",
+/// # " b debug: `2`",
+/// # );
+/// # assert_eq!(actual, message);
+/// # }
+/// ```
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_lt`](macro@crate::assert_any_lt)
+/// * [`assert_any_lt_as_result`](macro@crate::assert_any_lt_as_result)
+/// * [`debug_assert_any_lt`](macro@crate::debug_assert_any_lt)
+///
+#[macro_export]
+macro_rules! assert_any_lt {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match $crate::assert_any_lt_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}", err),
+ }
+ };
+ ($a_collection:expr, $b_item:expr, $($message:tt)+) => {
+ match $crate::assert_any_lt_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_lt {
+ use std::panic;
+
+ #[test]
+ fn lt() {
+ let a = [1, 2];
+ let b = 2;
+ for _ in 0..1 {
+ let actual = assert_any_lt!(&a, &b);
+ assert_eq!(actual, ());
+ }
+ }
+
+ #[test]
+ fn eq() {
+ let a = [1, 2];
+ let b = 1;
+ let result = panic::catch_unwind(|| {
+ let _actual = assert_any_lt!(&a, &b);
+ });
+ let message = concat!(
+ "assertion failed: `assert_any_lt!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_lt.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[1, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `1`"
+ );
+ assert_eq!(
+ result
+ .unwrap_err()
+ .downcast::()
+ .unwrap()
+ .to_string(),
+ message
+ );
+ }
+
+ #[test]
+ fn gt() {
+ let a = [3, 4];
+ let b = 2;
+ let result = panic::catch_unwind(|| {
+ let _actual = assert_any_lt!(&a, &b);
+ });
+ let message = concat!(
+ "assertion failed: `assert_any_lt!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_lt.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[3, 4]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `2`"
+ );
+ assert_eq!(
+ result
+ .unwrap_err()
+ .downcast::()
+ .unwrap()
+ .to_string(),
+ message
+ );
+ }
+}
+
+/// Assert an iterable is less than another.
+///
+/// Pseudocode:
+/// (collection into iter) < item
+///
+/// This macro provides the same statements as [`assert_any_lt`](macro.assert_any_lt.html),
+/// except this macro's statements are only enabled in non-optimized
+/// builds by default. An optimized build will not execute this macro's
+/// statements unless `-C debug-assertions` is passed to the compiler.
+///
+/// This macro is useful for checks that are too expensive to be present
+/// in a release build but may be helpful during development.
+///
+/// The result of expanding this macro is always type checked.
+///
+/// An unchecked assertion allows a program in an inconsistent state to
+/// keep running, which might have unexpected consequences but does not
+/// introduce unsafety as long as this only happens in safe code. The
+/// performance cost of assertions, however, is not measurable in general.
+/// Replacing `assert*!` with `debug_assert*!` is thus only encouraged
+/// after thorough profiling, and more importantly, only in safe code!
+///
+/// This macro is intended to work in a similar way to
+/// [`::std::debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_lt`](macro@crate::assert_any_lt)
+/// * [`assert_any_lt`](macro@crate::assert_any_lt)
+/// * [`debug_assert_any_lt`](macro@crate::debug_assert_any_lt)
+///
+#[macro_export]
+macro_rules! debug_assert_any_lt {
+ ($($arg:tt)*) => {
+ if $crate::cfg!(debug_assertions) {
+ $crate::assert_any_lt!($($arg)*);
+ }
+ };
+}
diff --git a/src/assert_any/assert_any_ne.rs b/src/assert_any/assert_any_ne.rs
new file mode 100644
index 00000000..72298097
--- /dev/null
+++ b/src/assert_any/assert_any_ne.rs
@@ -0,0 +1,252 @@
+//! Assert an iter is not equal to another.
+//!
+//! Pseudocode:
+//! (collection into iter) ≠ item
+//!
+//! # Example
+//!
+//! ```rust
+//! use assertables::*;
+//!
+//! let a = [1, 2];
+//! let b = 1;
+//! assert_any_ne!(&a, &b);
+//! ```
+//!
+//! This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+//!
+//! # Module macros
+//!
+//! * [`assert_any_ne`](macro@crate::assert_any_ne)
+//! * [`assert_any_ne_as_result`](macro@crate::assert_any_ne_as_result)
+//! * [`debug_assert_any_ne`](macro@crate::debug_assert_any_ne)
+
+/// Assert an iterable is not equal to another.
+///
+/// Pseudocode:
+/// (collection into iter) ≠ item
+///
+/// * If true, return Result `Ok(())`.
+///
+/// * Otherwise, return Result `Err(message)`.
+///
+/// This macro is useful for runtime checks, such as checking parameters,
+/// or sanitizing inputs, or handling different results in different ways.
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_ne`](macro@crate::assert_any_ne)
+/// * [`assert_any_ne_as_result`](macro@crate::assert_any_ne_as_result)
+/// * [`debug_assert_any_ne`](macro@crate::debug_assert_any_ne)
+///
+#[macro_export]
+macro_rules! assert_any_ne_as_result {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match ($a_collection, $b_item) {
+ (a_collection, b_item) => {
+ let mut a = a_collection.into_iter();
+ if a.any(|x| x != b_item) {
+ Ok(())
+ } else {
+ Err(format!(
+ concat!(
+ "assertion failed: `assert_any_ne!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_ne.html\n",
+ " a label: `{}`,\n",
+ " a debug: `{:?}`,\n",
+ " b label: `{}`,\n",
+ " b debug: `{:?}`"
+ ),
+ stringify!($a_collection),
+ a_collection,
+ stringify!($b_item),
+ b_item
+ ))
+ }
+ }
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_ne_as_result {
+ // use std::sync::Once;
+
+ #[test]
+ fn success() {
+ let a = [2, 2];
+ let b = 1;
+ for _ in 0..1 {
+ let actual = assert_any_ne_as_result!(&a, &b);
+ assert_eq!(actual.unwrap(), ());
+ }
+ }
+
+ #[test]
+ fn failure() {
+ let a = [2, 2];
+ let b = 2;
+ let actual = assert_any_ne_as_result!(&a, &b);
+ let message = concat!(
+ "assertion failed: `assert_any_ne!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_ne.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[2, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `2`"
+ );
+ assert_eq!(actual.unwrap_err(), message);
+ }
+}
+
+/// Assert an iterable is not equal to another.
+///
+/// Pseudocode:
+/// (collection into iter) ≠ item
+///
+/// * If true, return `()`.
+///
+/// * Otherwise, call [`panic!`] with a message and the values of the
+/// expressions with their debug representations.
+///
+/// # Examples
+///
+/// ```rust
+/// use assertables::*;
+/// # use std::panic;
+///
+/// # fn main() {
+/// let a = [1, 2];
+/// let b = 2;
+/// assert_any_ne!(&a, &b);
+///
+/// # let result = panic::catch_unwind(|| {
+/// // This will panic
+/// let a = [2, 2];
+/// let b = 2;
+/// assert_any_ne!(&a, &b);
+/// # });
+/// // assertion failed: `assert_any_ne!(a_collection, b_item)`
+/// // https://docs.rs/assertables/…/assertables/macro.assert_any_ne.html
+/// // a label: `&a`,
+/// // a debug: `[2, 2]`,
+/// // b label: `&b`,
+/// // b debug: `2`
+/// # let actual = result.unwrap_err().downcast::().unwrap().to_string();
+/// # let message = concat!(
+/// # "assertion failed: `assert_any_ne!(a_collection, b_item)`\n",
+/// # "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_ne.html\n",
+/// # " a label: `&a`,\n",
+/// # " a debug: `[2, 2]`,\n",
+/// # " b label: `&b`,\n",
+/// # " b debug: `2`",
+/// # );
+/// # assert_eq!(actual, message);
+/// # }
+/// ```
+///
+/// This implementation uses [`::std::iter::Iterator`](https://doc.rust-lang.org/std/iter/trait.Iterator.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_ne`](macro@crate::assert_any_ne)
+/// * [`assert_any_ne_as_result`](macro@crate::assert_any_ne_as_result)
+/// * [`debug_assert_any_ne`](macro@crate::debug_assert_any_ne)
+///
+#[macro_export]
+macro_rules! assert_any_ne {
+ ($a_collection:expr, $b_item:expr $(,)?) => {
+ match $crate::assert_any_ne_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}", err),
+ }
+ };
+ ($a_collection:expr, $b_item:expr, $($message:tt)+) => {
+ match $crate::assert_any_ne_as_result!($a_collection, $b_item) {
+ Ok(()) => (),
+ Err(err) => panic!("{}\n{}", format_args!($($message)+), err),
+ }
+ };
+}
+
+#[cfg(test)]
+mod test_assert_any_ne {
+ use std::panic;
+
+ #[test]
+ fn success() {
+ let a = [1, 2];
+ let b = 2;
+ for _ in 0..1 {
+ let actual = assert_any_ne!(&a, &b);
+ assert_eq!(actual, ());
+ }
+ }
+
+ #[test]
+ fn failure() {
+ let a = [2, 2];
+ let b = 2;
+ let result = panic::catch_unwind(|| {
+ let _actual = assert_any_ne!(&a, &b);
+ });
+ let message = concat!(
+ "assertion failed: `assert_any_ne!(a_collection, b_item)`\n",
+ "https://docs.rs/assertables/9.8.4/assertables/macro.assert_any_ne.html\n",
+ " a label: `&a`,\n",
+ " a debug: `[2, 2]`,\n",
+ " b label: `&b`,\n",
+ " b debug: `2`"
+ );
+ assert_eq!(
+ result
+ .unwrap_err()
+ .downcast::()
+ .unwrap()
+ .to_string(),
+ message
+ );
+ }
+}
+
+/// Assert an iterable is not equal to another.
+///
+/// Pseudocode:
+/// (collection into iter) ≠ item
+///
+/// This macro provides the same statements as [`assert_any_ne`](macro.assert_any_ne.html),
+/// except this macro's statements are only enabled in non-optimized
+/// builds by default. An optimized build will not execute this macro's
+/// statements unless `-C debug-assertions` is passed to the compiler.
+///
+/// This macro is useful for checks that are too expensive to be present
+/// in a release build but may be helpful during development.
+///
+/// The result of expanding this macro is always type checked.
+///
+/// An unchecked assertion allows a program in an inconsistent state to
+/// keep running, which might have unexpected consequences but does not
+/// introduce unsafety as long as this only happens in safe code. The
+/// performance cost of assertions, however, is not measurable in general.
+/// Replacing `assert*!` with `debug_assert*!` is thus only encouraged
+/// after thorough profiling, and more importantly, only in safe code!
+///
+/// This macro is intended to work in a similar way to
+/// [`::std::debug_assert`](https://doc.rust-lang.org/std/macro.debug_assert.html).
+///
+/// # Module macros
+///
+/// * [`assert_any_ne`](macro@crate::assert_any_ne)
+/// * [`assert_any_ne`](macro@crate::assert_any_ne)
+/// * [`debug_assert_any_ne`](macro@crate::debug_assert_any_ne)
+///
+#[macro_export]
+macro_rules! debug_assert_any_ne {
+ ($($arg:tt)*) => {
+ if $crate::cfg!(debug_assertions) {
+ $crate::assert_any_ne!($($arg)*);
+ }
+ };
+}
diff --git a/src/assert_any/mod.rs b/src/assert_any/mod.rs
new file mode 100644
index 00000000..d8a312a5
--- /dev/null
+++ b/src/assert_any/mod.rs
@@ -0,0 +1,31 @@
+//! Assert for comparing an iter collection with a single element.
+//!
+//! These macros help with comparison of iter parameters, such as a collection of struct
+//! and a single struct.
+//! These macros convert each input using the std::iter::Iterator trait.
+//!
+//! * [`assert_any_eq!(collection, item)`](macro@crate::assert_any_eq) ≈ iter a contains b
+//! * [`assert_any_ne!(collection, item)`](macro@crate::assert_any_ne) ≈ iter a does not contain b
+//! * [`assert_any_lt!(collection, item)`](macro@crate::assert_any_gt) ≈ iter a contains ≥ one element < b
+//! * [`assert_any_le!(collection, item)`](macro@crate::assert_any_gt) ≈ iter a contains ≥ one element ≤ b
+//! * [`assert_any_gt!(collection, item)`](macro@crate::assert_any_gt) ≈ iter a contains ≥ one element > b
+//! * [`assert_any_ge!(collection, item)`](macro@crate::assert_any_ge) ≈ iter a contains ≥ one element ≥ b
+//!
+//! # Example
+//!
+//! ```rust
+//! use assertables::*;
+//!
+//! let a = [1, 2];
+//! let b = 1;
+//! assert_any_eq!(&a, &b);
+//! ```
+
+// Comparisons
+pub mod assert_any;
+pub mod assert_any_eq;
+pub mod assert_any_ge;
+pub mod assert_any_gt;
+pub mod assert_any_le;
+pub mod assert_any_lt;
+pub mod assert_any_ne;