InputResolver.java
package com.github.dakusui.thincrest.metamor;
import com.github.dakusui.thincrest_pcond.core.printable.PrintableFunction;
import com.github.dakusui.thincrest_pcond.forms.Printables;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import static java.util.Collections.emptyList;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
public interface InputResolver<I, O> extends Function<Dataset<IoPair<I, O>>, I> {
class Impl<I, O> extends PrintableFunction<Dataset<IoPair<I, O>>, I> implements InputResolver<I, O> {
public Impl(Supplier<String> s, Function<? super Dataset<IoPair<I, O>>, ? extends I> function) {
super(new Object(), emptyList(), s, function);
}
}
interface Sequence<I, O> extends Dataset<InputResolver<I, O>> {
class Impl<I, O> implements Sequence<I, O> {
private final String inputVariableName;
private final List<InputResolver<I, O>> inputResolvers;
public Impl(String inputVariableName, List<InputResolver<I, O>> inputResolvers) {
this.inputVariableName = requireNonNull(inputVariableName);
this.inputResolvers = requireNonNull(inputResolvers);
}
@Override
public InputResolver<I, O> get(int i) {
return inputResolvers.get(i);
}
@Override
public int size() {
return inputResolvers.size();
}
@Override
public String name() {
return this.inputVariableName;
}
@Override
public String toString() {
return inputVariableName + ":" + inputResolvers;
}
@Override
public Iterator<InputResolver<I, O>> iterator() {
return new AbstractList<InputResolver<I, O>>() {
@Override
public int size() {
return Impl.this.size();
}
@Override
public InputResolver<I, O> get(int index) {
return Impl.this.get(index);
}
}.iterator();
}
}
interface Factory<X, I, O> extends Function<X, Sequence<I, O>> {
int count();
class Impl<X, I, O>
extends PrintableFunction<X, Sequence<I, O>>
implements Factory<X, I, O> {
private final int count;
public Impl(Supplier<String> s, Function<? super X, ? extends Sequence<I, O>> function, int count) {
super(new Object(), emptyList(), s, function);
this.count = count;
}
public Impl(String inputVariableName, List<Function<? super X, ? extends InputResolver<I, O>>> functions) {
this(
() -> functions.stream()
.map(Objects::toString)
.collect(joining(",", "[", "]")),
Factory.Impl.toSequenceCreatorFunction(inputVariableName, functions), functions.size());
}
@Override
public int count() {
return this.count;
}
private static <X, I, O> Function<? super X, ? extends Sequence<I, O>> toSequenceCreatorFunction(String inputVariableName, List<Function<? super X, ? extends InputResolver<I, O>>> functions) {
return (X value) -> new Sequence.Impl<>(
inputVariableName,
functions.stream()
.map(f -> f.apply(value))
.collect(toList()));
}
}
class Builder<X, I, O> {
private final List<Function<? super X, ? extends InputResolver<I, O>>> functions = new LinkedList<>();
private final String placeHolderVariableName;
private final String inputVariableName;
public Builder(String inputVariableName, String placeHolderVariableName) {
this.placeHolderVariableName = placeHolderVariableName;
this.inputVariableName = inputVariableName;
}
public Builder<X, I, O> function(Function<Object, String> formatter, Function<X, I> f) {
this.functions.add(Printables.function(() -> formatter.apply(this.placeHolderVariableName), x -> new InputResolver.Impl<>(() -> formatter.apply(x), ds -> f.apply(x))));
return this;
}
public Factory<X, I, O> build() {
return new Impl<>(this.inputVariableName, this.functions);
}
}
}
}
}