net.hamnaberg.json.codec.DecodeJson Maven / Gradle / Ivy
package net.hamnaberg.json.codec;
import net.hamnaberg.json.Json;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public interface DecodeJson {
DecodeResult fromJson(Json.JValue value);
default Optional defaultValue() {
return Optional.empty();
}
default A fromJsonUnsafe(Json.JValue value) {
return fromJson(value).unsafeGet();
}
default DecodeJson map(Function f) {
return (json) -> this.fromJson(json).map(f);
}
default DecodeJson tryMap(Function> f) {
return json -> this.fromJson(json).map(f).flatMap(DecodeResult::fromCallable);
}
default DecodeJson flatMap(Function> f) {
return value -> {
DecodeResult result = this.fromJson(value);
return result.flatMap(a -> f.apply(a).fromJson(value));
};
}
default DecodeJson withDefaultValue(A defaultValue) {
if (this instanceof DecodeJsonWithDefault) {
return new DecodeJsonWithDefault<>(((DecodeJsonWithDefault)this).delegate, defaultValue);
}
return new DecodeJsonWithDefault<>(this, defaultValue);
}
default DecodeJson or(DecodeJson orElse) {
return value -> fromJson(value).fold(aFail -> orElse.fromJson(value).fold(bFail -> DecodeResult.fail(aFail + " " + bFail), DecodeResult::ok), DecodeResult::ok);
}
default DecodeJson> and(DecodeJson next) {
return value -> {
DecodeResult aRes = fromJson(value);
DecodeResult bRes = next.fromJson(value);
return aRes.flatMap(a -> bRes.map(b -> Map.entry(a, b)));
};
}
default DecodeJson> option() {
return Decoders.optionalDecoder(this);
}
default DecodeJson> list() {
return Decoders.listDecoder(this);
}
default FieldDecoder fieldDecoder(String name) {
return FieldDecoder.typedFieldOf(name, this);
}
default DecodeJson filter(Predicate p) {
return filter(p, () -> "Filter failed");
}
default DecodeJson filter(Predicate p, Supplier errorSupplier) {
return value -> fromJson(value).filter(p, errorSupplier);
}
static DecodeJson> sequence(List> toSequence) {
return value -> DecodeResult.sequence(
toSequence.stream().map(d -> d.fromJson(value)).collect(Collectors.toUnmodifiableList())
);
}
static DecodeJson sequence(final Iterable> results, final Collector collector) {
return value ->
DecodeResult.sequence(
() -> StreamSupport.stream(results.spliterator(), false).map(d -> d.fromJson(value)).iterator(),
collector
);
}
static DecodeJson successful(A value) {
return result(DecodeResult.ok(value));
}
static DecodeJson failure(String message) {
return result(DecodeResult.fail(message));
}
static DecodeJson result(DecodeResult value) {
return ignore -> value;
}
class DecodeJsonWithDefault implements DecodeJson {
final DecodeJson delegate;
private final A defaultValue;
public DecodeJsonWithDefault(DecodeJson delegate, A defaultValue) {
this.delegate = delegate;
this.defaultValue = defaultValue;
}
@Override
public DecodeResult fromJson(Json.JValue value) {
DecodeResult res = delegate.fromJson(value);
return res.fold(ignore -> DecodeResult.ok(defaultValue), DecodeResult::ok);
}
@Override
public Optional defaultValue() {
return Optional.of(defaultValue);
}
@Override
public String toString() {
return getClass().getSimpleName() + String.format(" {delegate=%s, default=%s}", delegate, defaultValue);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy