macro_rules! is_contained_in {
    ($(,)?) => { ... };
    ($(($key_matcher:expr, $value_matcher:expr)),* $(,)?) => { ... };
    ($($matcher:expr),* $(,)?) => { ... };
}
Expand description

Matches a container all of whose elements are matched by the given matchers.

To match, each element in the container must have a corresponding matcher which matches it. There must be a 1-1 mapping from container elements to matchers, so that no matcher has more than one corresponding element.

There may, however, be matchers not corresponding to any elements in the container.

Put another way, is_contained_in! matches if there is a subset of the matchers which would match with unordered_elements_are.

verify_that!(vec![2, 1], is_contained_in![eq(1), ge(2)])?;   // Passes
verify_that!(vec![2, 1], is_contained_in![ge(1), ge(1)])?;   // Passes
verify_that!(vec![1, 2, 3], is_contained_in![eq(1), ge(2)])?; // Fails: container too large
verify_that!(vec![2, 1], is_contained_in![eq(1), ge(4)])?;    // Fails: second matcher unmatched
verify_that!(vec![3, 1], is_contained_in![ge(3), ge(3), ge(3)])?; // Fails: no matching

The actual value must be a container such as a Vec, an array, or a dereferenced slice. More precisely, a shared borrow of the actual value must implement IntoIterator.

This can also match against HashMap and similar collections. The arguments are a sequence of pairs of matchers corresponding to the keys and their respective values.

let value: HashMap<u32, &'static str> = HashMap::from_iter([(1, "One"), (2, "Two")]);
verify_that!(
    value,
    is_contained_in![(eq(2), eq("Two")), (eq(1), eq("One")), (eq(3), eq("Three"))]
)

This matcher does not support matching directly against an Iterator. To match against an iterator, use Iterator::collect to build a Vec.

The matcher proceeds in three stages:

  1. It first checks whether the actual value is too large to possibly be matched by each of the given matchers. If so, it immediately fails explaining that the size is too large.

  2. It then checks whether each actual container element is matched by at least one matcher and fails if that is not the case. The failure message indicates which element had no corresponding matcher.

  3. Finally, it checks whether the mapping of elements to corresponding matchers is 1-1 and fails if that is not the case. The failure message then shows the best matching it could find, including which container elements did not have corresponding matchers.