pub trait Matcher {
    type ActualT: Debug + ?Sized;

    // Required methods
    fn matches(&self, actual: &Self::ActualT) -> MatcherResult;
    fn describe(&self, matcher_result: MatcherResult) -> Description;

    // Provided methods
    fn explain_match(&self, actual: &Self::ActualT) -> Description { ... }
    fn and<Right: Matcher<ActualT = Self::ActualT>>(
        self,
        right: Right
    ) -> ConjunctionMatcher<Self, Right>
       where Self: Sized { ... }
    fn or<Right: Matcher<ActualT = Self::ActualT>>(
        self,
        right: Right
    ) -> DisjunctionMatcher<Self, Right>
       where Self: Sized { ... }
}
Expand description

An interface for checking an arbitrary condition on a datum.

Required Associated Types§

source

type ActualT: Debug + ?Sized

The type against which this matcher matches.

Required Methods§

source

fn matches(&self, actual: &Self::ActualT) -> MatcherResult

Returns whether the condition matches the datum actual.

The trait implementation defines what it means to “match”. Often the matching condition is based on data stored in the matcher. For example, eq matches when its stored expected value is equal (in the sense of the == operator) to the value actual.

source

fn describe(&self, matcher_result: MatcherResult) -> Description

Returns a description of self or a negative description if matcher_result is DoesNotMatch.

The function should print a verb phrase that describes the property a value matching, respectively not matching, this matcher should have. The subject of the verb phrase is the value being matched.

The output appears next to Expected in an assertion failure message. For example:

Value of: ...
Expected: is equal to 7
          ^^^^^^^^^^^^^
Actual: ...

When the matcher contains one or more inner matchers, the implementation should invoke Self::describe on the inner matchers to complete the description. It should place the inner description at a point where a verb phrase would fit. For example, the matcher some implements describe as follows:

fn describe(&self, matcher_result: MatcherResult) -> Description {
    match matcher_result {
        MatcherResult::Matches => {
            Description::new()
                .text("has a value which")
                .nested(self.inner.describe(MatcherResult::Matches))
      // Inner matcher: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        }
        MatcherResult::DoesNotMatch => {...} // Similar to the above
    }
}

The output expectation differs from that of explain_match in that it is a verb phrase (beginning with a verb like “is”) rather than a relative clause (beginning with “which” or “whose”). This difference is because the output of explain_match is always used adjectivally to describe the actual value, while describe is used in contexts where a relative clause would not make sense.

Provided Methods§

source

fn explain_match(&self, actual: &Self::ActualT) -> Description

Prepares a String describing how the expected value encoded in this instance matches or does not match the given value actual.

This should be in the form of a relative clause, i.e. something starting with a relative pronoun such as “which” or “whose”. It will appear next to the actual value in an assertion failure. For example:

Value of: ...
Expected: ...
Actual: ["Something"], which does not contain "Something else"
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The default implementation relies on describe. Thus it does not make any use of the actual value itself, but rather only whether the value is matched.

Override the default implementation to provide additional context on why a particular value matched or did not match. For example, the container_eq matcher displays information on which elements of the actual value were not present in the expected value and vice versa.

This implementation should be overridden in any matcher which contains one or more inner matchers. The implementation should invoke explain_match on the inner matchers, so that the generated match explanation also reflects their implementation. Without this, the match explanation of the inner matchers will not be able to make use of the actual value at all.

For example, the explain_match implementation of the matcher points_to defers immediately to the inner matcher and appears as follows:

fn explain_match(&self, actual: &Self::ActualT) -> Description {
    self.expected.explain_match(actual.deref())
}

The matcher can also provide some additional context before deferring to an inner matcher. In that case it should invoke explain_match on the inner matcher at a point where a relative clause would fit. For example:

fn explain_match(&self, actual: &Self::ActualT) -> Description {
    Description::new()
        .text("which points to a value")
        .nested(self.expected.explain_match(actual.deref()))
}
source

fn and<Right: Matcher<ActualT = Self::ActualT>>( self, right: Right ) -> ConjunctionMatcher<Self, Right>
where Self: Sized,

Constructs a matcher that matches both self and right.

verify_that!("A string", starts_with("A").and(ends_with("string")))?; // Passes
verify_that!("A string", starts_with("Another").and(ends_with("string")))?; // Fails
verify_that!("A string", starts_with("A").and(ends_with("non-string")))?; // Fails
source

fn or<Right: Matcher<ActualT = Self::ActualT>>( self, right: Right ) -> DisjunctionMatcher<Self, Right>
where Self: Sized,

Constructs a matcher that matches when at least one of self or right matches the input.

verify_that!(10, eq(2).or(ge(5)))?;  // Passes
verify_that!(10, eq(2).or(eq(5)).or(ge(9)))?;  // Passes
verify_that!(10, eq(2).or(ge(15)))?; // Fails

Implementations on Foreign Types§

source§

impl Matcher for ()

§

type ActualT = ()

source§

fn matches(&self, _: &Self::ActualT) -> MatcherResult

source§

fn describe(&self, matcher_result: MatcherResult) -> Description

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>> Matcher for (I0,)

§

type ActualT = (T0,)

source§

fn matches(&self, actual: &(T0,)) -> MatcherResult

source§

fn explain_match(&self, actual: &(T0,)) -> Description

source§

fn describe(&self, matcher_result: MatcherResult) -> Description

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>, T1: Debug, I1: Matcher<ActualT = T1>> Matcher for (I0, I1)

§

type ActualT = (T0, T1)

source§

fn matches(&self, actual: &(T0, T1)) -> MatcherResult

source§

fn explain_match(&self, actual: &(T0, T1)) -> Description

source§

fn describe(&self, matcher_result: MatcherResult) -> Description

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>, T1: Debug, I1: Matcher<ActualT = T1>, T2: Debug, I2: Matcher<ActualT = T2>> Matcher for (I0, I1, I2)

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>, T1: Debug, I1: Matcher<ActualT = T1>, T2: Debug, I2: Matcher<ActualT = T2>, T3: Debug, I3: Matcher<ActualT = T3>> Matcher for (I0, I1, I2, I3)

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>, T1: Debug, I1: Matcher<ActualT = T1>, T2: Debug, I2: Matcher<ActualT = T2>, T3: Debug, I3: Matcher<ActualT = T3>, T4: Debug, I4: Matcher<ActualT = T4>> Matcher for (I0, I1, I2, I3, I4)

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>, T1: Debug, I1: Matcher<ActualT = T1>, T2: Debug, I2: Matcher<ActualT = T2>, T3: Debug, I3: Matcher<ActualT = T3>, T4: Debug, I4: Matcher<ActualT = T4>, T5: Debug, I5: Matcher<ActualT = T5>> Matcher for (I0, I1, I2, I3, I4, I5)

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>, T1: Debug, I1: Matcher<ActualT = T1>, T2: Debug, I2: Matcher<ActualT = T2>, T3: Debug, I3: Matcher<ActualT = T3>, T4: Debug, I4: Matcher<ActualT = T4>, T5: Debug, I5: Matcher<ActualT = T5>, T6: Debug, I6: Matcher<ActualT = T6>> Matcher for (I0, I1, I2, I3, I4, I5, I6)

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>, T1: Debug, I1: Matcher<ActualT = T1>, T2: Debug, I2: Matcher<ActualT = T2>, T3: Debug, I3: Matcher<ActualT = T3>, T4: Debug, I4: Matcher<ActualT = T4>, T5: Debug, I5: Matcher<ActualT = T5>, T6: Debug, I6: Matcher<ActualT = T6>, T7: Debug, I7: Matcher<ActualT = T7>> Matcher for (I0, I1, I2, I3, I4, I5, I6, I7)

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>, T1: Debug, I1: Matcher<ActualT = T1>, T2: Debug, I2: Matcher<ActualT = T2>, T3: Debug, I3: Matcher<ActualT = T3>, T4: Debug, I4: Matcher<ActualT = T4>, T5: Debug, I5: Matcher<ActualT = T5>, T6: Debug, I6: Matcher<ActualT = T6>, T7: Debug, I7: Matcher<ActualT = T7>, T8: Debug, I8: Matcher<ActualT = T8>> Matcher for (I0, I1, I2, I3, I4, I5, I6, I7, I8)

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>, T1: Debug, I1: Matcher<ActualT = T1>, T2: Debug, I2: Matcher<ActualT = T2>, T3: Debug, I3: Matcher<ActualT = T3>, T4: Debug, I4: Matcher<ActualT = T4>, T5: Debug, I5: Matcher<ActualT = T5>, T6: Debug, I6: Matcher<ActualT = T6>, T7: Debug, I7: Matcher<ActualT = T7>, T8: Debug, I8: Matcher<ActualT = T8>, T9: Debug, I9: Matcher<ActualT = T9>> Matcher for (I0, I1, I2, I3, I4, I5, I6, I7, I8, I9)

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>, T1: Debug, I1: Matcher<ActualT = T1>, T2: Debug, I2: Matcher<ActualT = T2>, T3: Debug, I3: Matcher<ActualT = T3>, T4: Debug, I4: Matcher<ActualT = T4>, T5: Debug, I5: Matcher<ActualT = T5>, T6: Debug, I6: Matcher<ActualT = T6>, T7: Debug, I7: Matcher<ActualT = T7>, T8: Debug, I8: Matcher<ActualT = T8>, T9: Debug, I9: Matcher<ActualT = T9>, T10: Debug, I10: Matcher<ActualT = T10>> Matcher for (I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10)

source§

impl<T0: Debug, I0: Matcher<ActualT = T0>, T1: Debug, I1: Matcher<ActualT = T1>, T2: Debug, I2: Matcher<ActualT = T2>, T3: Debug, I3: Matcher<ActualT = T3>, T4: Debug, I4: Matcher<ActualT = T4>, T5: Debug, I5: Matcher<ActualT = T5>, T6: Debug, I6: Matcher<ActualT = T6>, T7: Debug, I7: Matcher<ActualT = T7>, T8: Debug, I8: Matcher<ActualT = T8>, T9: Debug, I9: Matcher<ActualT = T9>, T10: Debug, I10: Matcher<ActualT = T10>, T11: Debug, I11: Matcher<ActualT = T11>> Matcher for (I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11)

Implementors§

source§

impl<ExpectedT, ActualT> Matcher for StrMatcher<ActualT, ExpectedT>
where ExpectedT: Deref<Target = str> + Debug, ActualT: AsRef<str> + Debug + ?Sized,

§

type ActualT = ActualT

source§

impl<T: Debug + Float> Matcher for NearMatcher<T>

§

type ActualT = T

source§

impl<T: Debug, A: Debug + ?Sized + PartialEq<T>> Matcher for EqMatcher<A, T>

§

type ActualT = A

source§

impl<T: Debug, InnerMatcherT: Matcher<ActualT = T>, ContainerT: Debug> Matcher for ContainsMatcher<ContainerT, InnerMatcherT>
where for<'a> &'a ContainerT: IntoIterator<Item = &'a T>,

§

type ActualT = ContainerT

source§

impl<T: Debug, P, D1: PredicateDescription, D2: PredicateDescription> Matcher for PredicateMatcher<T, P, D1, D2>
where for<'a> P: Fn(&'a T) -> bool,

§

type ActualT = T