one.xingyi.optics.IOptional Maven / Gradle / Ivy
package one.xingyi.optics;
import one.xingyi.helpers.StreamHelper;
import one.xingyi.tuples.Tuple2;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Stream;
import static one.xingyi.helpers.StreamHelper.*;
public interface IOptional extends ITraversal {
static IOptional of(Function> optGetFn, BiFunction> optSetFn) {
return new OptionalOptic<>(optGetFn, optSetFn);
}
Optional optGet(Main main);
Optional optSet(Main main, Child child);
IOptional chainOptional(IOptional t);
IOptional merge(IOptional other, IISO, Merged> iso);
}
abstract class AbstractOptional extends AbstractTraversal implements IOptional {
@Override
public Stream all(Main main) {
Optional opt = optGet(main);
return streamOf(opt);
}
@Override
public Main modify(Main main, Function fn) {
Optional opt = optGet(main);
Optional result = opt.map(fn).flatMap(child -> optSet(main, child));
return result.orElse(main);
}
@Override
public IOptional chainOptional(IOptional t) {
return new OptionalOptic<>(
main -> optGet(main).flatMap(t::optGet),
(main, grandChild) -> optGet(main).flatMap(child -> t.optSet(child, grandChild)).flatMap(child -> optSet(main, child))
);
}
public IOptional merge(IOptional other, IISO, Merged> iso) {
return new OptionalOptic<>(
main -> optGet(main).flatMap(child -> other.optGet(main).map(child2 -> iso.get(Tuple2.of(child, child2)))),
(main, merged) -> {
Tuple2 t = iso.reverseGet(merged);
return optSet(main, t.t1).flatMap(newMain -> other.optSet(newMain, t.t2));
}
);
}
}
class OptionalOptic extends AbstractOptional implements IOptional {
protected final Function> optGetFn;
protected final BiFunction> optSetFn;
OptionalOptic(Function> optGetFn, BiFunction> optSetFn) {
this.optGetFn = optGetFn;
this.optSetFn = optSetFn;
}
@Override
public Optional optGet(Main main) {
return Optional.empty();
}
@Override
public Optional optSet(Main main, Child child) {
return optSetFn.apply(main, child);
}
}