
com.github.dakusui.crest.core.Matcher Maven / Gradle / Ivy
package com.github.dakusui.crest.core;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import static java.util.Objects.requireNonNull;
public interface Matcher {
boolean matches(T value, Session session, List exceptions);
void describeExpectation(Session session);
void describeMismatch(T value, Session session);
interface Composite extends Matcher {
default void describeExpectation(Session session) {
session.describeExpectation(this);
}
default void describeMismatch(T value, Session session) {
session.describeMismatch(value, this);
}
boolean isTopLevel();
List> children();
String name();
abstract class Base implements Composite {
private final List> children;
private final boolean topLevel;
@SuppressWarnings("unchecked")
protected Base(boolean topLevel, List> children) {
this.children = (List>) Collections.unmodifiableList((List extends T>) requireNonNull(children));
this.topLevel = topLevel;
}
@Override
public boolean matches(T value, Session session, List exceptions) {
List work = new LinkedList<>();
boolean ret = first();
for (Matcher eachChild : children())
ret = op(ret, eachChild.matches(value, session, work));
exceptions.addAll(work);
return ret && work.isEmpty();
}
@Override
public boolean isTopLevel() {
return this.topLevel;
}
@Override
public List> children() {
return this.children;
}
abstract protected boolean first();
abstract protected boolean op(boolean current, boolean next);
}
}
interface Conjunctive extends Composite {
@SuppressWarnings("unchecked")
static Matcher create(boolean topLevel, List> matchers) {
return new Conjunctive.Base(topLevel, matchers) {
@Override
public String name() {
return "and";
}
@Override
protected boolean first() {
return true;
}
@Override
protected boolean op(boolean current, boolean next) {
return current && next;
}
};
}
}
interface Disjunctive extends Composite {
@SuppressWarnings("unchecked")
static Matcher create(boolean topLevel, List> matchers) {
return new Composite.Base(topLevel, matchers) {
@Override
public String name() {
return "or";
}
@Override
protected boolean first() {
return false;
}
@Override
protected boolean op(boolean current, boolean next) {
return current || next;
}
};
}
}
interface Negative extends Composite {
static Matcher create(Matcher super T> matcher) {
return new Composite.Base(true, Collections.singletonList(matcher)) {
@Override
public String name() {
return "not";
}
@Override
protected boolean first() {
return true;
}
@Override
protected boolean op(boolean current, boolean next) {
return current && !next;
}
};
}
}
interface Leaf extends Matcher {
default void describeExpectation(Session session) {
session.describeExpectation(this);
}
default void describeMismatch(T value, Session session) {
session.describeMismatch(value, this);
}
Predicate> p();
Function func();
static Leaf create(Predicate super O> p, Function super I, ? extends O> function) {
return new Leaf() {
@Override
public Predicate> p() {
return p;
}
@SuppressWarnings("unchecked")
@Override
public Function func() {
return (Function) function;
}
@Override
public boolean matches(I value, Session session, List exceptions) {
try {
return session.matches(this, value, exceptions::add) && exceptions.isEmpty();
} catch (Throwable e) {
return false;
}
}
};
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy