package org.hamcrest;
/**
* A Condition implements part of a multi-step match. We sometimes need to write matchers
* that have a sequence of steps, where each step depends on the result of the previous
* step and we can stop processing as soon as a step fails. These classes provide
* infrastructure for writing such a sequence.
*
* Based on https://github.com/npryce/maybe-java
* @author Steve Freeman 2012 http://www.hamcrest.com
*/
public abstract class
Condition<T> {
public static final
NotMatched<
Object>
NOT_MATCHED = new
NotMatched<
Object>();
public interface
Step<I, O> {
Condition<O>
apply(I
value,
Description mismatch);
}
private
Condition() { }
public abstract boolean
matching(
Matcher<T>
match,
String message);
public abstract <U>
Condition<U>
and(
Step<? super T, U>
mapping);
public final boolean
matching(
Matcher<T>
match) { return
matching(
match, ""); }
public final <U>
Condition<U>
then(
Step<? super T, U>
mapping) { return
and(
mapping); }
@
SuppressWarnings("unchecked")
public static <T>
Condition<T>
notMatched() {
return (
Condition<T>)
NOT_MATCHED;
}
public static <T>
Condition<T>
matched(final T
theValue, final
Description mismatch) {
return new
Matched<T>(
theValue,
mismatch);
}
private static final class
Matched<T> extends
Condition<T> {
private final T
theValue;
private final
Description mismatch;
private
Matched(T
theValue,
Description mismatch) {
this.
theValue =
theValue;
this.
mismatch =
mismatch;
}
@
Override
public boolean
matching(
Matcher<T>
matcher,
String message) {
if (
matcher.
matches(
theValue)) {
return true;
}
mismatch.
appendText(
message);
matcher.
describeMismatch(
theValue,
mismatch);
return false;
}
@
Override
public <U>
Condition<U>
and(
Step<? super T, U>
next) {
return
next.
apply(
theValue,
mismatch);
}
}
private static final class
NotMatched<T> extends
Condition<T> {
@
Override public boolean
matching(
Matcher<T>
match,
String message) { return false; }
@
Override public <U>
Condition<U>
and(
Step<? super T, U>
mapping) {
return
notMatched();
}
}
}