diff options
author | Linnea Gräf <nea@nea.moe> | 2024-11-14 02:59:11 +0100 |
---|---|---|
committer | Linnea Gräf <nea@nea.moe> | 2024-11-14 02:59:11 +0100 |
commit | 5eea18ea497d4bc11466b2bd875582ba26f188f5 (patch) | |
tree | 26391b4e347a97eafed954a52cd81b14e10a8314 /src/main/java/moe/nea/pcj | |
parent | 05937d237c2fdf793e21b36523d06902c5a0a725 (diff) | |
download | profunctor-codecs-java-5eea18ea497d4bc11466b2bd875582ba26f188f5.tar.gz profunctor-codecs-java-5eea18ea497d4bc11466b2bd875582ba26f188f5.tar.bz2 profunctor-codecs-java-5eea18ea497d4bc11466b2bd875582ba26f188f5.zip |
Add lists
Diffstat (limited to 'src/main/java/moe/nea/pcj')
-rw-r--r-- | src/main/java/moe/nea/pcj/Result.java | 1 | ||||
-rw-r--r-- | src/main/java/moe/nea/pcj/json/AtIndex.java | 4 | ||||
-rw-r--r-- | src/main/java/moe/nea/pcj/json/JsonCodec.java | 40 | ||||
-rw-r--r-- | src/main/java/moe/nea/pcj/json/MapCodec.java | 4 |
4 files changed, 49 insertions, 0 deletions
diff --git a/src/main/java/moe/nea/pcj/Result.java b/src/main/java/moe/nea/pcj/Result.java index 22c94f9..af5398e 100644 --- a/src/main/java/moe/nea/pcj/Result.java +++ b/src/main/java/moe/nea/pcj/Result.java @@ -7,6 +7,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.function.Consumer; import java.util.function.Function; public sealed interface Result<Good, Bad> permits Result.Ok, Result.Fail { diff --git a/src/main/java/moe/nea/pcj/json/AtIndex.java b/src/main/java/moe/nea/pcj/json/AtIndex.java new file mode 100644 index 0000000..ec01112 --- /dev/null +++ b/src/main/java/moe/nea/pcj/json/AtIndex.java @@ -0,0 +1,4 @@ +package moe.nea.pcj.json; + +public record AtIndex(int index, JsonLikeError error) implements JsonLikeError { +} diff --git a/src/main/java/moe/nea/pcj/json/JsonCodec.java b/src/main/java/moe/nea/pcj/json/JsonCodec.java index 65f4a5e..6195bee 100644 --- a/src/main/java/moe/nea/pcj/json/JsonCodec.java +++ b/src/main/java/moe/nea/pcj/json/JsonCodec.java @@ -2,11 +2,51 @@ package moe.nea.pcj.json; import moe.nea.pcj.Codec; import moe.nea.pcj.Result; +import moe.nea.pcj.Unit; + +import java.util.ArrayList; +import java.util.List; public interface JsonCodec<T, Format> extends Codec< T, Format, JsonLikeOperations<Format>, JsonLikeError, JsonLikeError> { + default JsonCodec<List<T>, Format> listOf() { + return new JsonCodec<>() { + @Override + public Result<Format, JsonLikeError> encode(List<T> data, JsonLikeOperations<Format> ops) { + var list = ops.createList(); + var erros = new ArrayList<JsonLikeError>(); + for (int i = 0; i < data.size(); i++) { + var datum = data.get(i); + final var index = i; + var result = JsonCodec.this.encode(datum, ops) + .mapError(it -> new AtIndex(index, it)); + erros.addAll(result.errors()); + result.valueOrPartial().ifPresent(list::add); + } + return Result.<Format, JsonLikeError>ok(list.complete()).appendErrors(erros); + } + + @Override + public Result<List<T>, JsonLikeError> decode(Format format, JsonLikeOperations<Format> ops) { + var view = Result.<ListView<Format>, JsonLikeError>cast(ops.getList(format)); + return view.flatMap(elements -> { + var acc = new ArrayList<T>(elements.length()); + var errors = new ArrayList<JsonLikeError>(); + for (int i = 0; i < elements.length(); i++) { + final var index = i; + var result = JsonCodec.this.decode(elements.getUnsafe(i), ops) + .mapError(it -> new AtIndex(index, it)); + errors.addAll(result.errors()); + result.valueOrPartial().ifPresent(acc::add); + } + return Result.<List<T>, JsonLikeError>ok(acc).appendErrors(errors); + }); + } + }; + } + default MapCodec<T, Format> fieldOf(String key) { return new MapCodec<>() { @Override diff --git a/src/main/java/moe/nea/pcj/json/MapCodec.java b/src/main/java/moe/nea/pcj/json/MapCodec.java index 468e4cf..4b76150 100644 --- a/src/main/java/moe/nea/pcj/json/MapCodec.java +++ b/src/main/java/moe/nea/pcj/json/MapCodec.java @@ -11,6 +11,10 @@ public interface MapCodec<T, Format> { Result<RecordBuilder<Format>, JsonLikeError> encode(T value, JsonLikeOperations<Format> ops); + default JsonCodec<T, Format> codec() { + return RecordJoiners.join(withGetter(it -> it), it -> it); + } + default <O> RecordCodec<O, T, Format> withGetter(Function<O, T> getter) { return new RecordCodec<>(this, getter); } |