
com.github.dakusui.crest.core.Eater Maven / Gradle / Ivy
package com.github.dakusui.crest.core;
import com.github.dakusui.crest.utils.printable.Printable;
import junit.framework.AssertionFailedError;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.github.dakusui.crest.utils.printable.Predicates.equalTo;
import static java.util.Objects.requireNonNull;
public interface Eater {
Eater after(T target);
/**
* Builds a function.
*
* @return The function.
*/
Function build();
/**
* A synonym of {@code build} method.
*
* @return A built function.
*/
default Function $() {
return build();
}
abstract class Base implements Eater {
final T finder;
final Eater parent;
Base(Eater parent, T finder) {
this.parent = parent;
this.finder = requireNonNull(finder);
}
@SuppressWarnings("unchecked")
@Override
public Function build() {
return this.parent == null
? toFunction()
: this.parent.build().andThen(toFunction());
}
Function toFunction() {
return ChainedFunction.create(
Printable.function(
describeFunction(),
createFunction()
));
}
String describeFunction() {
return String.format("->after[%s]", this.finder);
}
protected abstract Function createFunction();
}
class RegexEater extends Base {
public RegexEater(Eater parent, String target) {
super(parent, target);
}
/**
* @param target A regex
* @return A new {@code RegexEater}
*/
@Override
public RegexEater after(String target) {
return new RegexEater(this, target);
}
protected Function createFunction() {
return (String container) -> {
Matcher matcher = Pattern.compile(String.format("(%s)", finder)).matcher(container);
if (matcher.find())
return restOf(container, matcher.group(1));
throw new AssertionFailedError(String.format("regex:%s was not found", finder));
};
}
private String restOf(String container, String matched) {
return container.substring(matched.length() + container.indexOf(matched));
}
}
class ListEater extends Base, List> {
public ListEater(Eater, List> parent, Predicate target) {
super(parent, target);
}
@Override
protected Function, List> createFunction() {
return container -> {
int index = findTarget(container);
if (index < 0)
throw new AssertionFailedError(String.format("Element:%s was not found", finder));
return container.subList(index + 1, container.size());
};
}
@Override
public ListEater after(Predicate finder) {
return new ListEater<>(this, finder);
}
public ListEater afterElement(T target) {
return new ListEater<>(this, equalTo(target));
}
int findTarget(List container) {
int i = 0;
for (T elem : container) {
if (this.finder.test(elem))
return i;
i++;
}
return -1;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy