From 7fa7f5caf04b911b4b99dc4cfead4d1206ddbc83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Merino=20Garc=C3=ADa?= Date: Fri, 14 Aug 2020 02:44:11 +0200 Subject: [PATCH] v8.3.0 (#150) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 🐛 lenses methods returns impls, nullpointer compose Closes: #149 * ci: 🎡 release v8.3.0 pom, changes and readme --- docs/CHANGELOG.md | 11 +-- docs/README.md | 4 +- pom.xml | 2 +- src/main/java/jsonvalues/JsArrayLens.java | 22 ++++- src/main/java/jsonvalues/JsBigIntLens.java | 6 +- src/main/java/jsonvalues/JsBinaryLens.java | 6 +- src/main/java/jsonvalues/JsBoolLens.java | 6 +- src/main/java/jsonvalues/JsDecimalLens.java | 6 +- src/main/java/jsonvalues/JsDoubleLens.java | 9 +- src/main/java/jsonvalues/JsInstantLens.java | 6 +- src/main/java/jsonvalues/JsIntLens.java | 6 +- src/main/java/jsonvalues/JsLongLens.java | 6 +- src/main/java/jsonvalues/JsObj.java | 2 + src/main/java/jsonvalues/JsObjLens.java | 23 ++++- src/main/java/jsonvalues/JsOptics.java | 98 +++++++++---------- src/main/java/jsonvalues/JsStrLens.java | 13 ++- src/main/java/jsonvalues/Lens.java | 17 ++-- src/test/java/jsonvalues/TestExample.java | 14 +-- .../java/jsonvalues/TestJsArrayOptics.java | 18 ++-- src/test/java/jsonvalues/TestJsObjOptics.java | 26 ++--- src/test/java/jsonvalues/TestLenses.java | 7 +- 21 files changed, 185 insertions(+), 123 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 2e7ca4d1..c64d5aea 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,12 +1,11 @@ # JSON-VALUES -## v8.2.2 ( Tue Aug 04 2020 15:37:27 GMT+0200 (Central European Summer Time) ) +## v8.3.0 ( Fri Aug 14 2020 02:37:38 GMT+0200 (Central European Summer Time) ) -## Features - - 🎸 Lens,Option and Prism are public - ([5bd2459d](https://github.com/imrafaelmerino/json-values/commit/5bd2459db0551e7b2da182e45965242e1b69ce3f)) - - 🎸 TesProperty class to do property based testing - ([6ba34465](https://github.com/imrafaelmerino/json-values/commit/6ba34465163e23e7ecd18525424129757f4bfc1c)) +## Bug Fixes + - 🐛 lenses methods returns impls, nullpointer compose + ([be84679e](https://github.com/imrafaelmerino/json-values/commit/be84679e796dea2f883363470338265c32d14b7b)) + diff --git a/docs/README.md b/docs/README.md index 7c7d3381..e8d95af5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,7 @@ [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/) [![Javadocs](https://www.javadoc.io/badge/com.github.imrafaelmerino/json-values.svg)](https://www.javadoc.io/doc/com.github.imrafaelmerino/json-values) -[![Maven](https://img.shields.io/maven-central/v/com.github.imrafaelmerino/json-values/8.2.2)](https://search.maven.org/artifact/com.github.imrafaelmerino/json-values/8.2.2/jar) +[![Maven](https://img.shields.io/maven-central/v/com.github.imrafaelmerino/json-values/8.3.0)](https://search.maven.org/artifact/com.github.imrafaelmerino/json-values/8.3.0/jar) [![](https://jitpack.io/v/imrafaelmerino/json-values.svg)](https://jitpack.io/#imrafaelmerino/json-values) [![Gitter](https://badges.gitter.im/json-values/community.svg)](https://gitter.im/json-values/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) @@ -214,7 +214,7 @@ Add the following dependency to your building tool: com.github.imrafaelmerino json-values - 8.2.2 + 8.3.0 ``` diff --git a/pom.xml b/pom.xml index aad7f953..c1f351d8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.imrafaelmerino json-values jar - 8.2.2 + 8.3.0 json-values json-values is a functional Java library to work with immutable jsons using persistent data structures. diff --git a/src/main/java/jsonvalues/JsArrayLens.java b/src/main/java/jsonvalues/JsArrayLens.java index a4bdb24f..8a93eb75 100644 --- a/src/main/java/jsonvalues/JsArrayLens.java +++ b/src/main/java/jsonvalues/JsArrayLens.java @@ -1,15 +1,31 @@ package jsonvalues; +import static java.util.Objects.requireNonNull; + /** Represent a Lens which focus is an array located at a path in a Json @param the type of the whole part, an array or an object */ class JsArrayLens> extends Lens { JsArrayLens(final JsPath path) { - super(json -> json.getArray(path), - a -> json -> json.set(path, - a) + super(json -> requireNonNull(json).getArray(path), + a -> json -> requireNonNull(json).set(path, + a + ) ); } + + @Override + public Lens compose(final Lens other) { + return new Lens<>(this.get.andThen(other.get), + b -> s -> { + JsArray o = this.get.apply(requireNonNull(s)); + JsArray newO = other.set.apply(requireNonNull(b)) + .apply(o == null ? JsArray.empty() : o); + return this.set.apply(newO) + .apply(s); + } + ); + } } diff --git a/src/main/java/jsonvalues/JsBigIntLens.java b/src/main/java/jsonvalues/JsBigIntLens.java index da611020..eb1b75fb 100644 --- a/src/main/java/jsonvalues/JsBigIntLens.java +++ b/src/main/java/jsonvalues/JsBigIntLens.java @@ -3,14 +3,16 @@ import java.math.BigInteger; +import static java.util.Objects.requireNonNull; + /** Represent a Lens which focus is a biginteger number located at a path in a Json @param the type of the whole part, an array or an object */ class JsBigIntLens> extends Lens { JsBigIntLens(final JsPath path) { - super(json -> json.getBigInt(path), - n -> json -> json.set(path, + super(json -> requireNonNull(json).getBigInt(path), + n -> json -> requireNonNull(json).set(path, JsBigInt.of(n)) ); } diff --git a/src/main/java/jsonvalues/JsBinaryLens.java b/src/main/java/jsonvalues/JsBinaryLens.java index 1d0673d3..3ed4ffbb 100644 --- a/src/main/java/jsonvalues/JsBinaryLens.java +++ b/src/main/java/jsonvalues/JsBinaryLens.java @@ -1,14 +1,16 @@ package jsonvalues; +import static java.util.Objects.requireNonNull; + /** Represent a Lens which focus is an array of bytes located at a path in a Json @param the type of the whole part, an array or an object */ public class JsBinaryLens> extends Lens { JsBinaryLens(final JsPath path) { - super(json -> json.getBinary(path), - o -> json -> json.set(path, + super(json -> requireNonNull(json).getBinary(path), + o -> json -> requireNonNull(json).set(path, JsBinary.of(o)) ); } diff --git a/src/main/java/jsonvalues/JsBoolLens.java b/src/main/java/jsonvalues/JsBoolLens.java index 507a362b..903c420c 100644 --- a/src/main/java/jsonvalues/JsBoolLens.java +++ b/src/main/java/jsonvalues/JsBoolLens.java @@ -1,6 +1,8 @@ package jsonvalues; +import static java.util.Objects.requireNonNull; + /** * Represent a Lens which focus is a boolean located at a path in a Json * @@ -8,8 +10,8 @@ */ class JsBoolLens> extends Lens { JsBoolLens(final JsPath path) { - super(json -> json.getBool(path), - n -> json -> json.set(path, JsBool.of(n)) + super(json -> requireNonNull(json).getBool(path), + n -> json -> requireNonNull(json).set(path, JsBool.of(n)) ); } } diff --git a/src/main/java/jsonvalues/JsDecimalLens.java b/src/main/java/jsonvalues/JsDecimalLens.java index 6d3e35d1..3008d1f5 100644 --- a/src/main/java/jsonvalues/JsDecimalLens.java +++ b/src/main/java/jsonvalues/JsDecimalLens.java @@ -2,14 +2,16 @@ import java.math.BigDecimal; +import static java.util.Objects.requireNonNull; + /** Represent a Lens which focus is a decimal number located at a path in a Json @param the type of the whole part, an array or an object */ class JsDecimalLens> extends Lens { JsDecimalLens(final JsPath path) { - super(json -> json.getBigDec(path), - n -> json -> json.set(path, + super(json -> requireNonNull(json).getBigDec(path), + n -> json -> requireNonNull(json).set(path, JsBigDec.of(n)) ); } diff --git a/src/main/java/jsonvalues/JsDoubleLens.java b/src/main/java/jsonvalues/JsDoubleLens.java index f1ed4d62..946c530c 100644 --- a/src/main/java/jsonvalues/JsDoubleLens.java +++ b/src/main/java/jsonvalues/JsDoubleLens.java @@ -1,15 +1,18 @@ package jsonvalues; +import static java.util.Objects.requireNonNull; + /** Represent a Lens which focus is a double number located at a path in a Json @param the type of the whole part, an array or an object */ class JsDoubleLens> extends Lens { JsDoubleLens(final JsPath path) { - super(json -> json.getDouble(path), - n -> json -> json.set(path, - JsDouble.of(n)) + super(json -> requireNonNull(json).getDouble(path), + n -> json -> requireNonNull(json).set(path, + JsDouble.of(n) + ) ); } } diff --git a/src/main/java/jsonvalues/JsInstantLens.java b/src/main/java/jsonvalues/JsInstantLens.java index 63b1a88f..36c0def6 100644 --- a/src/main/java/jsonvalues/JsInstantLens.java +++ b/src/main/java/jsonvalues/JsInstantLens.java @@ -3,14 +3,16 @@ import java.time.Instant; +import static java.util.Objects.requireNonNull; + /** Represent a Lens which focus is an Instant located at a path in a Json @param the type of the whole part, an array or an object */ public class JsInstantLens> extends Lens { JsInstantLens(final JsPath path) { - super(json -> json.getInstant(path), - o -> json -> json.set(path, + super(json -> requireNonNull(json).getInstant(path), + o -> json -> requireNonNull(json).set(path, JsInstant.of(o)) ); } diff --git a/src/main/java/jsonvalues/JsIntLens.java b/src/main/java/jsonvalues/JsIntLens.java index f915018d..c09e1643 100644 --- a/src/main/java/jsonvalues/JsIntLens.java +++ b/src/main/java/jsonvalues/JsIntLens.java @@ -1,5 +1,7 @@ package jsonvalues; +import static java.util.Objects.requireNonNull; + /** * Represent a Lens which focus is an integer number located at a path in a Json * @@ -7,8 +9,8 @@ */ class JsIntLens> extends Lens { JsIntLens(final JsPath path) { - super(json -> json.getInt(path), - n -> json -> json.set(path, JsInt.of(n)) + super(json -> requireNonNull(json).getInt(path), + n -> json -> requireNonNull(json).set(path, JsInt.of(n)) ); } } diff --git a/src/main/java/jsonvalues/JsLongLens.java b/src/main/java/jsonvalues/JsLongLens.java index 9bec567c..af5e299e 100644 --- a/src/main/java/jsonvalues/JsLongLens.java +++ b/src/main/java/jsonvalues/JsLongLens.java @@ -1,13 +1,15 @@ package jsonvalues; +import static java.util.Objects.requireNonNull; + /** Represent a Lens which focus is a long number located at a path is a Json @param the type of the whole part, an array or an object */ class JsLongLens> extends Lens { JsLongLens(final JsPath path) { - super(json -> json.getLong(path), - n -> json -> json.set(path, + super(json -> requireNonNull(json).getLong(path), + n -> json -> requireNonNull(json).set(path, JsLong.of(n)) ); } diff --git a/src/main/java/jsonvalues/JsObj.java b/src/main/java/jsonvalues/JsObj.java index cf8275f7..5407b246 100644 --- a/src/main/java/jsonvalues/JsObj.java +++ b/src/main/java/jsonvalues/JsObj.java @@ -1938,5 +1938,7 @@ private Trampoline unionAll(final JsObj a, } + + } diff --git a/src/main/java/jsonvalues/JsObjLens.java b/src/main/java/jsonvalues/JsObjLens.java index 1267835b..955036e9 100644 --- a/src/main/java/jsonvalues/JsObjLens.java +++ b/src/main/java/jsonvalues/JsObjLens.java @@ -1,15 +1,32 @@ package jsonvalues; +import static java.util.Objects.requireNonNull; + /** Represent a Lens which focus is a json object located at a path is a Json @param the type of the whole part, an array or an object */ -public class JsObjLens> extends Lens { +class JsObjLens> extends Lens { JsObjLens(final JsPath path) { - super(json -> json.getObj(path), - o -> json -> json.set(path, + super(json -> requireNonNull(json).getObj(path), + o -> json -> requireNonNull(json).set(path, o) ); } + + + @Override + public Lens compose(final Lens other) { + return new Lens<>(this.get.andThen(other.get), + b -> s -> { + JsObj o = this.get.apply(requireNonNull(s)); + JsObj newO = other.set.apply(requireNonNull(b)) + .apply(o == null ? JsObj.empty() : o); + return this.set.apply(newO) + .apply(s); + } + ); + } + } diff --git a/src/main/java/jsonvalues/JsOptics.java b/src/main/java/jsonvalues/JsOptics.java index b2c99b09..cc88ae29 100644 --- a/src/main/java/jsonvalues/JsOptics.java +++ b/src/main/java/jsonvalues/JsOptics.java @@ -34,7 +34,7 @@ public static class JsArrayLenses { @param path the path where the value is located at @return a lens */ - public Lens value(final JsPath path) { + public Lens value(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsValueLens<>(requireNonNull(path)); @@ -46,7 +46,7 @@ public Lens value(final JsPath path) { @param index the index where the value is located at @return a lens */ - public JsValueLens value(final int index) { + public Lensvalue(final int index) { return new JsValueLens<>(requireNonNull(JsPath.fromIndex(index))); } @@ -56,7 +56,7 @@ public JsValueLens value(final int index) { @param path the path where the string is located at @return a lens */ - public JsStrLens str(final JsPath path) { + public Lens str(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsStrLens<>(requireNonNull(path)); @@ -68,7 +68,7 @@ public JsStrLens str(final JsPath path) { @param index the index where the string is located at @return a lens */ - public JsStrLens str(final int index) { + public Lens str(final int index) { return new JsStrLens<>(requireNonNull(JsPath.fromIndex(index))); } @@ -78,7 +78,7 @@ public JsStrLens str(final int index) { @param path the path where the boolean is located at @return a lens */ - public JsBoolLens bool(final JsPath path) { + public Lens bool(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsBoolLens<>(requireNonNull(path)); @@ -90,7 +90,7 @@ public JsBoolLens bool(final JsPath path) { @param index the index where the boolean is located at @return a lens */ - public JsBoolLens bool(final int index) { + public Lens bool(final int index) { return new JsBoolLens<>(requireNonNull(JsPath.fromIndex(index))); } @@ -100,7 +100,7 @@ public JsBoolLens bool(final int index) { @param path the path where the long number is located at @return a lens */ - public JsLongLens longNum(final JsPath path) { + public Lens longNum(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsLongLens<>(requireNonNull(path)); @@ -112,7 +112,7 @@ public JsLongLens longNum(final JsPath path) { @param index the index where the long number is located at @return a lens */ - public JsLongLens longNum(final int index) { + public Lens longNum(final int index) { return new JsLongLens<>(requireNonNull(JsPath.fromIndex(index))); } @@ -122,7 +122,7 @@ public JsLongLens longNum(final int index) { @param path the path where the integer number is located at @return a lens */ - public JsIntLens intNum(final JsPath path) { + public Lens intNum(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsIntLens<>(requireNonNull(path)); @@ -134,7 +134,7 @@ public JsIntLens intNum(final JsPath path) { @param index the index where the integer number is located at @return a lens */ - public JsIntLens intNum(final int index) { + public Lens intNum(final int index) { return new JsIntLens<>(requireNonNull(JsPath.fromIndex(index))); } @@ -144,7 +144,7 @@ public JsIntLens intNum(final int index) { @param path the path where the double number is located at @return a lens */ - public JsDoubleLens doubleNum(final JsPath path) { + public Lens doubleNum(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsDoubleLens<>(requireNonNull(path)); @@ -156,7 +156,7 @@ public JsDoubleLens doubleNum(final JsPath path) { @param index the index where the double number is located at @return a lens */ - public JsDoubleLens doubleNum(final int index) { + public Lens doubleNum(final int index) { return new JsDoubleLens<>(requireNonNull(JsPath.fromIndex(index))); } @@ -166,7 +166,7 @@ public JsDoubleLens doubleNum(final int index) { @param path the path where the decimal number is located at @return a lens */ - public JsDecimalLens decimalNum(final JsPath path) { + public Lens decimalNum(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsDecimalLens<>(requireNonNull(path)); @@ -178,7 +178,7 @@ public JsDecimalLens decimalNum(final JsPath path) { @param index the index where the decimal number is located at @return a lens */ - public JsDecimalLens decimalNum(final int index) { + public Lens decimalNum(final int index) { return new JsDecimalLens<>(requireNonNull(JsPath.fromIndex(index))); } @@ -188,7 +188,7 @@ public JsDecimalLens decimalNum(final int index) { @param path the path where the integral number is located at @return a lens */ - public JsBigIntLens integralNum(final JsPath path) { + public Lens integralNum(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsBigIntLens<>(requireNonNull(path)); @@ -200,7 +200,7 @@ public JsBigIntLens integralNum(final JsPath path) { @param index the index where the integral number is located at @return a lens */ - public JsBigIntLens integralNum(final int index) { + public Lens integralNum(final int index) { return new JsBigIntLens<>(requireNonNull(JsPath.fromIndex(index))); } @@ -210,7 +210,7 @@ public JsBigIntLens integralNum(final int index) { @param path the path where the json object is located at @return a lens */ - public JsObjLens obj(final JsPath path) { + public Lens obj(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsObjLens<>(requireNonNull(path)); @@ -222,7 +222,7 @@ public JsObjLens obj(final JsPath path) { @param index the index where the json object is located at @return a lens */ - public JsObjLens obj(final int index) { + public Lens obj(final int index) { return new JsObjLens<>(requireNonNull(JsPath.fromIndex(index))); } @@ -232,7 +232,7 @@ public JsObjLens obj(final int index) { @param path the path where the json array is located at @return a lens */ - public JsArrayLens array(final JsPath path) { + public Lens array(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsArrayLens<>(requireNonNull(path)); @@ -244,7 +244,7 @@ public JsArrayLens array(final JsPath path) { @param index the index where the json array is located at @return a lens */ - public JsArrayLens array(final int index) { + public Lens array(final int index) { return new JsArrayLens<>(requireNonNull(JsPath.fromIndex(index))); } @@ -255,7 +255,7 @@ public JsArrayLens array(final int index) { @param path the path where the bytes are located at @return a lens */ - public JsBinaryLens binary(final JsPath path) { + public Lens binary(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsBinaryLens<>(requireNonNull(path)); @@ -267,7 +267,7 @@ public JsBinaryLens binary(final JsPath path) { @param index the index where the bytes are located at @return a lens */ - public JsBinaryLens binary(final int index) { + public Lens binary(final int index) { return new JsBinaryLens<>(requireNonNull(JsPath.fromIndex(index))); } @@ -278,7 +278,7 @@ public JsBinaryLens binary(final int index) { @param path the path where the bytes are located at @return a lens */ - public JsInstantLens instant(final JsPath path) { + public Lens instant(final JsPath path) { if (path.head() .isKey()) throw UserError.pathHeadIsNotAnIndex(path); return new JsInstantLens<>(requireNonNull(path)); @@ -290,7 +290,7 @@ public JsInstantLens instant(final JsPath path) { @param index the index where the bytes are located at @return a lens */ - public JsInstantLens instant(final int index) { + public Lens instant(final int index) { return new JsInstantLens<>(requireNonNull(JsPath.fromIndex(index))); } } @@ -848,7 +848,7 @@ public static class JsObjLenses { @param path the path where the value is located at @return an optional */ - public JsValueLens value(final JsPath path) { + public Lens value(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -861,7 +861,7 @@ public JsValueLens value(final JsPath path) { @param key the key where the value is located at @return an optional */ - public JsValueLens value(final String key) { + public Lens value(final String key) { return new JsValueLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } @@ -871,7 +871,7 @@ public JsValueLens value(final String key) { @param path the path where the string is located at @return an optional */ - public JsStrLens str(final JsPath path) { + public Lens str(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -884,7 +884,7 @@ public JsStrLens str(final JsPath path) { @param key the key where the string is located at @return an optional */ - public JsStrLens str(final String key) { + public Lens str(final String key) { return new JsStrLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } @@ -894,7 +894,7 @@ public JsStrLens str(final String key) { @param path the path where the boolean is located at @return an optional */ - public JsBoolLens bool(final JsPath path) { + public Lens bool(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -907,7 +907,7 @@ public JsBoolLens bool(final JsPath path) { @param key the key where the boolean is located at @return an optional */ - public JsBoolLens bool(final String key) { + public Lens bool(final String key) { return new JsBoolLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } @@ -917,7 +917,7 @@ public JsBoolLens bool(final String key) { @param path the path where the long number is located at @return an optional */ - public JsLongLens longNum(final JsPath path) { + public Lens longNum(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -930,7 +930,7 @@ public JsLongLens longNum(final JsPath path) { @param key the key where the long number is located at @return an optional */ - public JsLongLens longNum(final String key) { + public Lens longNum(final String key) { return new JsLongLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } @@ -940,7 +940,7 @@ public JsLongLens longNum(final String key) { @param path the path where the integer number is located at @return an optional */ - public JsIntLens intNum(final JsPath path) { + public Lens intNum(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -953,7 +953,7 @@ public JsIntLens intNum(final JsPath path) { @param key the key where the integer number is located at @return an optional */ - public JsIntLens intNum(final String key) { + public Lens intNum(final String key) { return new JsIntLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } @@ -963,7 +963,7 @@ public JsIntLens intNum(final String key) { @param path the path where the double number is located at @return an optional */ - public JsDoubleLens doubleNum(final JsPath path) { + public Lens doubleNum(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -976,7 +976,7 @@ public JsDoubleLens doubleNum(final JsPath path) { @param key the key where the double number is located at @return an optional */ - public JsDoubleLens doubleNum(final String key) { + public Lens doubleNum(final String key) { return new JsDoubleLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } @@ -986,7 +986,7 @@ public JsDoubleLens doubleNum(final String key) { @param path the path where the decimal number is located at @return an optional */ - public JsDecimalLens decimalNum(final JsPath path) { + public Lens decimalNum(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -999,7 +999,7 @@ public JsDecimalLens decimalNum(final JsPath path) { @param key the key where the decimal number is located at @return an optional */ - public JsDecimalLens decimalNum(final String key) { + public Lens decimalNum(final String key) { return new JsDecimalLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } @@ -1009,7 +1009,7 @@ public JsDecimalLens decimalNum(final String key) { @param path the path where the integral number is located at @return an optional */ - public JsBigIntLens integralNum(final JsPath path) { + public Lens integralNum(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -1022,7 +1022,7 @@ public JsBigIntLens integralNum(final JsPath path) { @param key the key where the integral number is located at @return an optional */ - public JsBigIntLens integralNum(final String key) { + public Lens integralNum(final String key) { return new JsBigIntLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } @@ -1032,7 +1032,7 @@ public JsBigIntLens integralNum(final String key) { @param path the path where the json object is located at @return an optional */ - public JsObjLens obj(final JsPath path) { + public Lens obj(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -1045,7 +1045,7 @@ public JsObjLens obj(final JsPath path) { @param key the key where the json object is located at @return an optional */ - public JsObjLens obj(final String key) { + public Lens obj(final String key) { return new JsObjLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } @@ -1055,7 +1055,7 @@ public JsObjLens obj(final String key) { @param path the path where the json array is located at @return an optional */ - public JsArrayLens array(final JsPath path) { + public Lens array(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -1068,20 +1068,18 @@ public JsArrayLens array(final JsPath path) { @param key the key where the json array is located at @return an optional */ - public JsArrayLens array(final String key) { + public Lens array(final String key) { return new JsArrayLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } - - /** lens that focus on an array of bytes located at a path in an object. @param path the path where the array of bytes is located at @return an optional */ - public JsBinaryLens binary(final JsPath path) { + public Lens binary(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -1094,7 +1092,7 @@ public JsBinaryLens binary(final JsPath path) { @param key the key where the array of bytes is located at @return an optional */ - public JsBinaryLens binary(final String key) { + public Lens binary(final String key) { return new JsBinaryLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } @@ -1105,7 +1103,7 @@ public JsBinaryLens binary(final String key) { @param path the path where the instant is located at @return an optional */ - public JsInstantLens instant(final JsPath path) { + public Lens instant(final JsPath path) { if (path.head() .isIndex()) throw UserError.pathHeadIsNotAKey(requireNonNull(path)); @@ -1118,7 +1116,7 @@ public JsInstantLens instant(final JsPath path) { @param key the key where the instant is located at @return an optional */ - public JsInstantLens instant(final String key) { + public Lens instant(final String key) { return new JsInstantLens<>(requireNonNull(JsPath.fromKey(requireNonNull(key)))); } diff --git a/src/main/java/jsonvalues/JsStrLens.java b/src/main/java/jsonvalues/JsStrLens.java index fd4678e0..7c3efcce 100644 --- a/src/main/java/jsonvalues/JsStrLens.java +++ b/src/main/java/jsonvalues/JsStrLens.java @@ -1,10 +1,17 @@ package jsonvalues; + +import static java.util.Objects.requireNonNull; + class JsStrLens> extends Lens { JsStrLens(final JsPath path) { - super(json -> json.getStr(path), - str -> json -> json.set(path, - JsStr.of(str)) + super(json -> requireNonNull(json).getStr(path), + str -> json -> requireNonNull(json) + .set(path, + JsStr.of(str) + ) ); } + + } diff --git a/src/main/java/jsonvalues/Lens.java b/src/main/java/jsonvalues/Lens.java index 763823bc..f6946d2e 100644 --- a/src/main/java/jsonvalues/Lens.java +++ b/src/main/java/jsonvalues/Lens.java @@ -1,5 +1,6 @@ package jsonvalues; +import java.util.Objects; import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; @@ -48,8 +49,8 @@ public class Lens { public Lens(final Function get, final Function> set) { - this.set = set; - this.get = get; + this.set = requireNonNull(set); + this.get = requireNonNull(get); this.modify = f -> json -> set.apply(f.apply(get.apply(json))) .apply(json); this.find = predicate -> s -> predicate.test(get.apply(s)) ? @@ -68,8 +69,8 @@ public Lens(final Function get, */ public Option compose(final Prism prism) { return new Option<>(json -> requireNonNull(prism).getOptional.apply(get.apply(json)), - value -> json -> set.apply(prism.reverseGet.apply(value)) - .apply(json) + value -> json -> set.apply(prism.reverseGet.apply(requireNonNull(value))) + .apply(requireNonNull(json)) ); @@ -86,9 +87,11 @@ public Lens compose(final Lens other) { return new Lens<>(this.get.andThen(other.get), b -> s -> { - O o = other.set.apply(b) - .apply(this.get.apply(s)); - return this.set.apply(o) + O o = this.get.apply(requireNonNull(s)); + if (o == null) return s; + O newO = other.set.apply(requireNonNull(b)) + .apply(o); + return this.set.apply(newO) .apply(s); } ); diff --git a/src/test/java/jsonvalues/TestExample.java b/src/test/java/jsonvalues/TestExample.java index b22ebf3d..ae4c1d18 100644 --- a/src/test/java/jsonvalues/TestExample.java +++ b/src/test/java/jsonvalues/TestExample.java @@ -72,21 +72,21 @@ public void test() { parser.parse(person.toPrettyString())); - JsStrLens nameLens = JsObj.lens.str("name"); + Lens nameLens = JsObj.lens.str("name"); Option surnameOpt = JsObj.optional.str("surname"); Option ageOpt = JsObj.optional.intNum("age"); - JsStrLens streetLens = JsObj.lens.str(JsPath.path("/address/street")); - JsValueLens cityLens = JsObj.lens.value(JsPath.path("/address/city")); + Lens streetLens = JsObj.lens.str(JsPath.path("/address/street")); + Lens cityLens = JsObj.lens.value(JsPath.path("/address/city")); - JsArrayLens languagesLens = JsObj.lens.array("languages"); + Lens languagesLens = JsObj.lens.array("languages"); - JsValueLens numberLens = JsObj.lens.value(JsPath.path("/address/number")); + Lens numberLens = JsObj.lens.value(JsPath.path("/address/number")); - JsDoubleLens latitudeLens = JsObj.lens.doubleNum(JsPath.path("/address/coordinates/0")); + Lens latitudeLens = JsObj.lens.doubleNum(JsPath.path("/address/coordinates/0")); - JsDoubleLens longitudeLens = JsObj.lens.doubleNum(JsPath.path("/address/coordinates/1")); + Lens longitudeLens = JsObj.lens.doubleNum(JsPath.path("/address/coordinates/1")); IntFunction> incAge = n -> ageOpt.modify.apply(i -> i + n); diff --git a/src/test/java/jsonvalues/TestJsArrayOptics.java b/src/test/java/jsonvalues/TestJsArrayOptics.java index 4457697c..8e02b300 100644 --- a/src/test/java/jsonvalues/TestJsArrayOptics.java +++ b/src/test/java/jsonvalues/TestJsArrayOptics.java @@ -18,7 +18,7 @@ public void testBigDecLenses() { ) ); - JsBigIntLens lens = JsArray.lens.integralNum(path); + Lens lens = JsArray.lens.integralNum(path); Assertions.assertEquals( BigInteger.TEN,lens.get.apply(a)); @@ -47,7 +47,7 @@ public void testStrLenses() { ) ); - JsStrLens lens = JsArray.lens.str(path); + Lens lens = JsArray.lens.str(path); Assertions.assertEquals( "abc",lens.get.apply(a)); @@ -76,7 +76,7 @@ public void testDoubleLenses() { ) ); - JsDoubleLens lens = JsArray.lens.doubleNum(path); + Lens lens = JsArray.lens.doubleNum(path); Assertions.assertEquals( Double.valueOf(1.5),lens.get.apply(a)); @@ -103,7 +103,7 @@ public void testLongLenses() { ) ); - JsLongLens lens = JsArray.lens.longNum(path); + Lens lens = JsArray.lens.longNum(path); Assertions.assertEquals( Long.valueOf(Long.MAX_VALUE),lens.get.apply(a)); @@ -131,7 +131,7 @@ public void testIntegerLenses() { ) ); - JsIntLens lens = JsArray.lens.intNum(path); + Lens lens = JsArray.lens.intNum(path); Assertions.assertEquals( Integer.valueOf(Integer.MAX_VALUE),lens.get.apply(a)); @@ -159,7 +159,7 @@ public void testDecimalLenses() { ) ); - JsDecimalLens lens = JsArray.lens.decimalNum(path); + Lens lens = JsArray.lens.decimalNum(path); Assertions.assertEquals(new BigDecimal("1.11") ,lens.get.apply(a)); @@ -188,7 +188,7 @@ public void testBoolLenses() { ) ); - JsBoolLens lens = JsArray.lens.bool(path); + Lens lens = JsArray.lens.bool(path); Assertions.assertEquals(true ,lens.get.apply(a)); @@ -217,7 +217,7 @@ public void testObjLenses() { ) ); - JsObjLens lens = JsArray.lens.obj(path); + Lens lens = JsArray.lens.obj(path); Assertions.assertEquals(JsObj.empty() ,lens.get.apply(a)); @@ -250,7 +250,7 @@ public void testArrayLenses() { ) ); - JsArrayLens lens = JsArray.lens.array(path); + Lens lens = JsArray.lens.array(path); Assertions.assertEquals(JsArray.empty() ,lens.get.apply(a)); diff --git a/src/test/java/jsonvalues/TestJsObjOptics.java b/src/test/java/jsonvalues/TestJsObjOptics.java index ab965502..ea21c372 100644 --- a/src/test/java/jsonvalues/TestJsObjOptics.java +++ b/src/test/java/jsonvalues/TestJsObjOptics.java @@ -19,9 +19,9 @@ public void testBigDecLenses() { ) ); - JsValueLens valueLens = JsObj.lens.value(path); - JsBigIntLens lens = JsObj.lens.integralNum(path); - JsObjLens lenByKey = JsObj.lens.obj("a"); + Lens valueLens = JsObj.lens.value(path); + Lens lens = JsObj.lens.integralNum(path); + Lens lenByKey = JsObj.lens.obj("a"); Assertions.assertTrue(lenByKey.exists.apply(it -> it.containsKey("b")) @@ -73,7 +73,7 @@ public void testStrLenses() { ) ); - JsStrLens lens = JsObj.lens.str(path); + Lens lens = JsObj.lens.str(path); Assertions.assertEquals("abc", lens.get.apply(a)); @@ -104,7 +104,7 @@ public void testDoubleLenses() { ) ); - JsDoubleLens lens = JsObj.lens.doubleNum(path); + Lens lens = JsObj.lens.doubleNum(path); Assertions.assertEquals(Double.valueOf(1.5), lens.get.apply(a)); @@ -134,7 +134,7 @@ public void testLongLenses() { ) ); - JsLongLens lens = JsObj.lens.longNum(path); + Lens lens = JsObj.lens.longNum(path); Assertions.assertEquals(Long.valueOf(Long.MAX_VALUE), lens.get.apply(a)); @@ -164,7 +164,7 @@ public void testIntegerLenses() { ) ); - JsIntLens lens = JsObj.lens.intNum(path); + Lens lens = JsObj.lens.intNum(path); Assertions.assertEquals(Integer.valueOf(Integer.MAX_VALUE), lens.get.apply(a)); @@ -194,7 +194,7 @@ public void testDecimalLenses() { ) ); - JsDecimalLens lens = JsObj.lens.decimalNum(path); + Lens lens = JsObj.lens.decimalNum(path); Assertions.assertEquals(new BigDecimal("1.11"), lens.get.apply(a)); @@ -226,7 +226,7 @@ public void testBoolLenses() { ) ); - JsBoolLens lens = JsObj.lens.bool(path); + Lens lens = JsObj.lens.bool(path); Assertions.assertEquals(true, lens.get.apply(a)); @@ -257,7 +257,7 @@ public void testObjLenses() { ) ); - JsObjLens lens = JsObj.lens.obj(path); + Lens lens = JsObj.lens.obj(path); Assertions.assertEquals(JsObj.empty(), lens.get.apply(a)); @@ -298,7 +298,7 @@ public void testArrayLenses() { ) ); - JsArrayLens lens = JsObj.lens.array(path); + Lens lens = JsObj.lens.array(path); Assertions.assertEquals(JsArray.empty(), lens.get.apply(a)); @@ -482,8 +482,8 @@ public void testDecimalOptional() { @Test public void testValueLenses(){ - JsValueLens b = JsObj.lens.value(JsPath.path("/a/b")); - JsValueLens head = JsObj.lens.value(JsPath.path("/a/c/0")); + Lens b = JsObj.lens.value(JsPath.path("/a/b")); + Lens head = JsObj.lens.value(JsPath.path("/a/c/0")); JsObj obj = JsObj.of("a", JsObj.of("b", diff --git a/src/test/java/jsonvalues/TestLenses.java b/src/test/java/jsonvalues/TestLenses.java index 6bbe8216..cea38313 100644 --- a/src/test/java/jsonvalues/TestLenses.java +++ b/src/test/java/jsonvalues/TestLenses.java @@ -23,6 +23,9 @@ public void testCompose() { ) ); + Assertions.assertEquals(obj,compose.set.apply("a") + .apply(JsObj.empty())); + Assertions.assertEquals("a", compose.get.apply(obj)); @@ -34,7 +37,7 @@ public void testCompose() { @Test public void test_binary_lens() { - JsBinaryLens binaryLens = JsObj.lens.binary("a"); + Lens binaryLens = JsObj.lens.binary("a"); byte[] bytes = binaryLens.get.apply(JsObj.of("a", @@ -52,7 +55,7 @@ public void test_binary_lens() { @Test public void test_instant_lens() { - JsInstantLens intantLens = JsObj.lens.instant("a"); + Lens intantLens = JsObj.lens.instant("a"); Instant now = Instant.now();