diff --git a/README.md b/README.md
index 3118281..8096300 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
A Java JSON Library intended to be easy to learn and simple to teach.
-Requires Java 17+.
+Requires Java 21+.
## Dependency Information
@@ -16,7 +16,7 @@ Requires Java 17+.
dev.mccue
json
- 0.2.4
+ 0.3.0
```
@@ -24,7 +24,7 @@ Requires Java 17+.
```
dependencies {
- implementation("dev.mccue:json:0.2.4")
+ implementation("dev.mccue:json:0.3.0")
}
```
diff --git a/pom.xml b/pom.xml
index e157783..096c655 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,17 +6,17 @@
dev.mccue
json
- 0.2.4
+ 0.3.0
jar
UTF-8
- 17
- 17
+ 21
+ 21
json
- Dead simple Java JSON API based on sealed interfaces.
+ A Java JSON Library intended to be easy to learn and simple to teach.
https://github.com/bowbahdoe/json
@@ -63,10 +63,9 @@
maven-compiler-plugin
3.8.1
-
- 17
+
+ 21
- -Xlint:all
-Werror
diff --git a/src/main/java/dev/mccue/json/Json.java b/src/main/java/dev/mccue/json/Json.java
index 0c595aa..486f421 100644
--- a/src/main/java/dev/mccue/json/Json.java
+++ b/src/main/java/dev/mccue/json/Json.java
@@ -79,7 +79,7 @@ static Json of(@Nullable JsonEncodable value) {
* @return An instance of {@link Json}.
*/
static Json of(@Nullable BigDecimal value) {
- return value == null ? JsonNull.instance() : new BigDecimalImpl(value);
+ return value == null ? JsonNull.instance() : JsonNumber.of(value);
}
/**
@@ -89,7 +89,7 @@ static Json of(@Nullable BigDecimal value) {
* @return An instance of {@link Json}.
*/
static Json of(double value) {
- return new DoubleImpl(value);
+ return JsonNumber.of(value);
}
/**
@@ -99,7 +99,7 @@ static Json of(double value) {
* @return An instance of {@link Json}.
*/
static Json of(long value) {
- return new LongImpl(value);
+ return JsonNumber.of(value);
}
/**
@@ -109,7 +109,7 @@ static Json of(long value) {
* @return An instance of {@link Json}.
*/
static Json of(float value) {
- return new DoubleImpl(value);
+ return JsonNumber.of(value);
}
/**
@@ -119,7 +119,7 @@ static Json of(float value) {
* @return An instance of {@link Json}.
*/
static Json of(int value) {
- return new LongImpl(value);
+ return JsonNumber.of(value);
}
/**
@@ -129,7 +129,7 @@ static Json of(int value) {
* @return An instance of {@link Json}.
*/
static Json of(@Nullable Double value) {
- return value == null ? JsonNull.instance() : new DoubleImpl(value);
+ return value == null ? JsonNull.instance() : of((double) value);
}
/**
@@ -139,7 +139,7 @@ static Json of(@Nullable Double value) {
* @return An instance of {@link Json}.
*/
static Json of(@Nullable Long value) {
- return value == null ? JsonNull.instance() : new LongImpl(value);
+ return value == null ? JsonNull.instance() : of((long) value);
}
/**
@@ -149,7 +149,7 @@ static Json of(@Nullable Long value) {
* @return An instance of {@link Json}.
*/
static Json of(@Nullable Float value) {
- return value == null ? JsonNull.instance() : new DoubleImpl(value);
+ return value == null ? JsonNull.instance() : of((float) value);
}
/**
@@ -159,7 +159,7 @@ static Json of(@Nullable Float value) {
* @return An instance of {@link Json}.
*/
static Json of(@Nullable Integer value) {
- return value == null ? JsonNull.instance() : new LongImpl(value);
+ return value == null ? JsonNull.instance() : of((int) value);
}
/**
@@ -169,7 +169,7 @@ static Json of(@Nullable Integer value) {
* @return An instance of {@link Json}.
*/
static Json of(@Nullable BigInteger value) {
- return value == null ? JsonNull.instance() : new BigIntegerImpl(value);
+ return value == null ? JsonNull.instance() : JsonNumber.of(value);
}
/**
diff --git a/src/main/java/dev/mccue/json/JsonDecimal.java b/src/main/java/dev/mccue/json/JsonDecimal.java
new file mode 100644
index 0000000..73d7098
--- /dev/null
+++ b/src/main/java/dev/mccue/json/JsonDecimal.java
@@ -0,0 +1,8 @@
+package dev.mccue.json;
+
+import dev.mccue.json.internal.JsonDecimalImpl;
+
+public sealed abstract class JsonDecimal
+ extends JsonNumber
+ permits JsonDecimalImpl {
+}
diff --git a/src/main/java/dev/mccue/json/JsonInteger.java b/src/main/java/dev/mccue/json/JsonInteger.java
new file mode 100644
index 0000000..6561689
--- /dev/null
+++ b/src/main/java/dev/mccue/json/JsonInteger.java
@@ -0,0 +1,8 @@
+package dev.mccue.json;
+
+import dev.mccue.json.internal.JsonIntegerImpl;
+
+public sealed abstract class JsonInteger
+ extends JsonNumber
+ permits JsonIntegerImpl {
+}
diff --git a/src/main/java/dev/mccue/json/JsonNumber.java b/src/main/java/dev/mccue/json/JsonNumber.java
index 216587a..12e02a7 100644
--- a/src/main/java/dev/mccue/json/JsonNumber.java
+++ b/src/main/java/dev/mccue/json/JsonNumber.java
@@ -1,9 +1,7 @@
package dev.mccue.json;
-import dev.mccue.json.internal.BigDecimalImpl;
-import dev.mccue.json.internal.BigIntegerImpl;
-import dev.mccue.json.internal.DoubleImpl;
-import dev.mccue.json.internal.LongImpl;
+import dev.mccue.json.internal.JsonDecimalImpl;
+import dev.mccue.json.internal.JsonIntegerImpl;
import dev.mccue.json.stream.JsonGenerator;
import java.io.Serial;
@@ -16,8 +14,7 @@
*/
public sealed abstract class JsonNumber
extends Number
- implements Json
- permits BigDecimalImpl, DoubleImpl, LongImpl, BigIntegerImpl {
+ implements Json permits JsonDecimal, JsonInteger {
@Serial
private static final long serialVersionUID = 1L;
@@ -35,28 +32,40 @@ protected JsonNumber() {}
public abstract boolean isIntegral();
- public static JsonNumber of(BigDecimal value) {
- return new BigDecimalImpl(value);
+ public static JsonDecimal of(BigDecimal value) {
+ return new JsonDecimalImpl(value.toString());
}
- public static JsonNumber of(double value) {
- return new DoubleImpl(value);
+ public static JsonDecimal of(double value) {
+ if (Double.isInfinite(value)) {
+ throw new IllegalArgumentException("JSON cannot encode an infinite value");
+ }
+ if (Double.isNaN(value)) {
+ throw new IllegalArgumentException("JSON cannot encode a NaN");
+ }
+ return new JsonDecimalImpl(BigDecimal.valueOf(value).toString());
}
- public static JsonNumber of(long value) {
- return new LongImpl(value);
+ public static JsonInteger of(long value) {
+ return new JsonIntegerImpl(BigDecimal.valueOf(value).toString());
}
- public static JsonNumber of(float value) {
- return new DoubleImpl(value);
+ public static JsonDecimal of(float value) {
+ if (Float.isInfinite(value)) {
+ throw new IllegalArgumentException("JSON cannot encode an infinite value");
+ }
+ if (Float.isNaN(value)) {
+ throw new IllegalArgumentException("JSON cannot encode a NaN");
+ }
+ return new JsonDecimalImpl(BigDecimal.valueOf(value).toString());
}
- public static JsonNumber of(int value) {
- return new LongImpl(value);
+ public static JsonInteger of(int value) {
+ return new JsonIntegerImpl(BigDecimal.valueOf(value).toString());
}
- public static JsonNumber of(java.math.BigInteger value) {
- return new BigIntegerImpl(value);
+ public static JsonInteger of(java.math.BigInteger value) {
+ return new JsonIntegerImpl(new BigDecimal(value).toString());
}
@Override
diff --git a/src/main/java/dev/mccue/json/JsonReadOptions.java b/src/main/java/dev/mccue/json/JsonReadOptions.java
index 46613ca..7aebc18 100644
--- a/src/main/java/dev/mccue/json/JsonReadOptions.java
+++ b/src/main/java/dev/mccue/json/JsonReadOptions.java
@@ -6,28 +6,22 @@
* Options for customizing the process of reading Json.
*
* @param eofBehavior What to do if an attempted read reaches an EOF without any Json being read.
- * @param useBigDecimals Whether to use BigDecimals when reading decimal numbers.
*
* @author Ethan McCue
*/
public record JsonReadOptions(
- EOFBehavior eofBehavior,
- boolean useBigDecimals
+ EOFBehavior eofBehavior
) {
public JsonReadOptions {
Objects.requireNonNull(eofBehavior, "eofBehavior must not be null");
}
public JsonReadOptions() {
- this(EOFBehavior.THROW_EXCEPTION, false);
+ this(EOFBehavior.THROW_EXCEPTION);
}
public JsonReadOptions withEOFBehavior(EOFBehavior eofBehavior) {
- return new JsonReadOptions(eofBehavior, useBigDecimals);
- }
-
- public JsonReadOptions withUseBigDecimals(boolean useBigDecimals) {
- return new JsonReadOptions(eofBehavior, useBigDecimals);
+ return new JsonReadOptions(eofBehavior);
}
/**
diff --git a/src/main/java/dev/mccue/json/internal/BigDecimalImpl.java b/src/main/java/dev/mccue/json/internal/BigDecimalImpl.java
deleted file mode 100644
index dcba5f2..0000000
--- a/src/main/java/dev/mccue/json/internal/BigDecimalImpl.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package dev.mccue.json.internal;
-
-import dev.mccue.json.Json;
-import dev.mccue.json.JsonNumber;
-import dev.mccue.json.serialization.JsonSerializationProxy;
-
-import java.io.Serial;
-import java.math.BigInteger;
-import java.util.Objects;
-
-@ValueCandidate
-public final class BigDecimalImpl extends JsonNumber {
- @Serial
- private static final long serialVersionUID = 1L;
- private final java.math.BigDecimal bigDecimalValue;
-
- public BigDecimalImpl(java.math.BigDecimal bigDecimalValue) {
- this.bigDecimalValue = Objects.requireNonNull(
- bigDecimalValue,
- "bigDecimalValue must not be null."
- );
- }
-
- @Override
- public int intValue() {
- return bigDecimalValue.intValue();
- }
-
- @Override
- public long longValue() {
- return bigDecimalValue.longValue();
- }
-
- @Override
- public float floatValue() {
- return bigDecimalValue.floatValue();
- }
-
- @Override
- public double doubleValue() {
- return bigDecimalValue.doubleValue();
- }
-
- @Override
- public java.math.BigDecimal bigDecimalValue() {
- return bigDecimalValue;
- }
-
- @Override
- public java.math.BigInteger bigIntegerValue() {
- return bigDecimalValue.toBigInteger();
- }
-
- @Override
- public int intValueExact() {
- return bigDecimalValue.intValueExact();
- }
-
- @Override
- public long longValueExact() {
- return bigDecimalValue.longValueExact();
- }
-
- @Override
- public BigInteger bigIntegerValueExact() {
- return bigDecimalValue.toBigIntegerExact();
- }
-
- @Override
- public boolean isIntegral() {
- return bigDecimalValue.scale() == 0;
- }
-
- @Override
- public boolean equals(Object o) {
- return (this == o) || (
- o instanceof BigDecimalImpl otherBigDecimal &&
- this.bigDecimalValue.equals(otherBigDecimal.bigDecimalValue)
- );
- }
-
- @Override
- public int hashCode() {
- return this.bigDecimalValue.hashCode();
- }
-
- @Override
- public java.lang.String toString() {
- return this.bigDecimalValue.toString();
- }
-
- @Serial
- private Object writeReplace() {
- return new JsonSerializationProxy(Json.writeString(this));
- }
-
- @Serial
- private Object readResolve() {
- throw new IllegalStateException();
- }
-}
-
diff --git a/src/main/java/dev/mccue/json/internal/DoubleImpl.java b/src/main/java/dev/mccue/json/internal/DoubleImpl.java
deleted file mode 100644
index 85fea88..0000000
--- a/src/main/java/dev/mccue/json/internal/DoubleImpl.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package dev.mccue.json.internal;
-
-import dev.mccue.json.Json;
-import dev.mccue.json.JsonNumber;
-import dev.mccue.json.serialization.JsonSerializationProxy;
-
-import java.io.Serial;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-@ValueCandidate
-public final class DoubleImpl extends JsonNumber {
- @Serial
- private static final long serialVersionUID = 1L;
-
- private final double doubleValue;
-
- public DoubleImpl(double doubleValue) {
- if (Double.isInfinite(doubleValue)) {
- throw new IllegalArgumentException("JSON cannot encode an infinite double");
- }
- if (Double.isNaN(doubleValue)) {
- throw new IllegalArgumentException("JSON cannot encode a NaN double");
- }
-
- this.doubleValue = doubleValue;
- }
-
- @Override
- public java.math.BigDecimal bigDecimalValue() {
- return java.math.BigDecimal.valueOf(doubleValue);
- }
-
- @Override
- public java.math.BigInteger bigIntegerValue() {
- return java.math.BigInteger.valueOf((long) doubleValue);
- }
-
- @Override
- public int intValueExact() {
- if (((int) doubleValue) == doubleValue) {
- return (int) doubleValue;
- }
- else {
- throw new ArithmeticException(doubleValue + " cannot fit into an int");
- }
- }
-
- @Override
- public long longValueExact() {
- if (((long) doubleValue) == doubleValue) {
- return (int) doubleValue;
- }
- else {
- throw new ArithmeticException(doubleValue + " cannot fit into an int");
- }
- }
-
- @Override
- public BigInteger bigIntegerValueExact() {
- return BigDecimal.valueOf(doubleValue).toBigIntegerExact();
- }
-
- @Override
- public boolean isIntegral() {
- return (((int) doubleValue) == doubleValue);
- }
-
- @Override
- public int intValue() {
- return (int) doubleValue;
- }
-
- @Override
- public long longValue() {
- return (long) doubleValue;
- }
-
- @Override
- public float floatValue() {
- return (float) doubleValue;
- }
-
- @Override
- public double doubleValue() {
- return doubleValue;
- }
-
- @Override
- public boolean equals(Object o) {
- return (this == o) || (
- o instanceof DoubleImpl otherDouble &&
- this.doubleValue == otherDouble.doubleValue
- );
- }
-
- @Override
- public int hashCode() {
- return java.lang.Double.hashCode(this.doubleValue);
- }
-
- @Override
- public java.lang.String toString() {
- return java.lang.Double.toString(this.doubleValue);
- }
-
- @Serial
- private Object writeReplace() {
- return new JsonSerializationProxy(Json.writeString(this));
- }
-
- @Serial
- private Object readResolve() {
- throw new IllegalStateException();
- }
-}
diff --git a/src/main/java/dev/mccue/json/internal/JsonDecimalImpl.java b/src/main/java/dev/mccue/json/internal/JsonDecimalImpl.java
new file mode 100644
index 0000000..e318295
--- /dev/null
+++ b/src/main/java/dev/mccue/json/internal/JsonDecimalImpl.java
@@ -0,0 +1,82 @@
+package dev.mccue.json.internal;
+
+import dev.mccue.json.Json;
+import dev.mccue.json.JsonDecimal;
+import dev.mccue.json.serialization.JsonSerializationProxy;
+
+import java.io.Serial;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+public final class JsonDecimalImpl extends JsonDecimal {
+ private final String value;
+
+ public JsonDecimalImpl(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public BigDecimal bigDecimalValue() {
+ return new BigDecimal(value);
+ }
+
+ @Override
+ public int intValue() {
+ return bigDecimalValue().intValue();
+ }
+
+ @Override
+ public long longValue() {
+ return bigDecimalValue().longValue();
+ }
+
+ @Override
+ public float floatValue() {
+ return bigDecimalValue().floatValue();
+ }
+
+ @Override
+ public double doubleValue() {
+ return bigDecimalValue().doubleValue();
+ }
+
+ @Override
+ public java.math.BigInteger bigIntegerValue() {
+ return bigDecimalValue().toBigInteger();
+ }
+
+ @Override
+ public int intValueExact() {
+ return bigDecimalValue().intValueExact();
+ }
+
+ @Override
+ public long longValueExact() {
+ return bigDecimalValue().longValueExact();
+ }
+
+ @Override
+ public BigInteger bigIntegerValueExact() {
+ return bigDecimalValue().toBigIntegerExact();
+ }
+
+ @Override
+ public boolean isIntegral() {
+ return bigDecimalValue().scale() == 0;
+ }
+
+ @Override
+ public java.lang.String toString() {
+ return this.value;
+ }
+
+ @Serial
+ private Object writeReplace() {
+ return new JsonSerializationProxy(Json.writeString(this));
+ }
+
+ @Serial
+ private Object readResolve() {
+ throw new IllegalStateException();
+ }
+}
diff --git a/src/main/java/dev/mccue/json/internal/BigIntegerImpl.java b/src/main/java/dev/mccue/json/internal/JsonIntegerImpl.java
similarity index 51%
rename from src/main/java/dev/mccue/json/internal/BigIntegerImpl.java
rename to src/main/java/dev/mccue/json/internal/JsonIntegerImpl.java
index d3e8bf6..2f4267f 100644
--- a/src/main/java/dev/mccue/json/internal/BigIntegerImpl.java
+++ b/src/main/java/dev/mccue/json/internal/JsonIntegerImpl.java
@@ -1,30 +1,30 @@
package dev.mccue.json.internal;
import dev.mccue.json.Json;
-import dev.mccue.json.JsonNumber;
+import dev.mccue.json.JsonInteger;
import dev.mccue.json.serialization.JsonSerializationProxy;
import java.io.Serial;
-import java.util.Objects;
+import java.math.BigInteger;
-@ValueCandidate
-public final class BigIntegerImpl extends JsonNumber {
+public final class JsonIntegerImpl extends JsonInteger {
@Serial
private static final long serialVersionUID = 1L;
- private final java.math.BigInteger bigIntegerValue;
- public BigIntegerImpl(java.math.BigInteger bigIntegerValue) {
- this.bigIntegerValue = Objects.requireNonNull(bigIntegerValue, "value must not be null");
+ private final String value;
+
+ public JsonIntegerImpl(String value) {
+ this.value = value;
}
@Override
public java.math.BigDecimal bigDecimalValue() {
- return new java.math.BigDecimal(bigIntegerValue);
+ return new java.math.BigDecimal(bigIntegerValue());
}
@Override
public java.math.BigInteger bigIntegerValue() {
- return bigIntegerValue;
+ return new BigInteger(value);
}
@Override
@@ -34,12 +34,12 @@ public int intValueExact() {
@Override
public long longValueExact() {
- return bigIntegerValue.longValueExact();
+ return bigIntegerValue().longValueExact();
}
@Override
public java.math.BigInteger bigIntegerValueExact() {
- return bigIntegerValue;
+ return bigIntegerValue();
}
@Override
@@ -49,40 +49,27 @@ public boolean isIntegral() {
@Override
public int intValue() {
- return bigIntegerValue.intValue();
+ return Integer.parseInt(value);
}
@Override
public long longValue() {
- return bigIntegerValue.longValue();
+ return Long.parseLong(value);
}
@Override
public float floatValue() {
- return bigIntegerValue.floatValue();
+ return Float.parseFloat(value);
}
@Override
public double doubleValue() {
- return bigIntegerValue.doubleValue();
- }
-
- @Override
- public boolean equals(Object o) {
- return (this == o) || (
- o instanceof BigIntegerImpl otherBigInteger &&
- this.bigIntegerValue.equals(otherBigInteger.bigIntegerValue)
- );
- }
-
- @Override
- public int hashCode() {
- return this.bigIntegerValue.hashCode();
+ return Double.parseDouble(value);
}
@Override
public java.lang.String toString() {
- return this.bigIntegerValue.toString();
+ return this.value;
}
@Serial
diff --git a/src/main/java/dev/mccue/json/internal/JsonReaderMethods.java b/src/main/java/dev/mccue/json/internal/JsonReaderMethods.java
index cf34be3..b42767a 100644
--- a/src/main/java/dev/mccue/json/internal/JsonReaderMethods.java
+++ b/src/main/java/dev/mccue/json/internal/JsonReaderMethods.java
@@ -2,18 +2,16 @@
import dev.mccue.json.Json;
-import dev.mccue.json.JsonReadOptions;
-import dev.mccue.json.stream.JsonArrayHandler;
import dev.mccue.json.JsonNumber;
import dev.mccue.json.JsonReadException;
+import dev.mccue.json.JsonReadOptions;
+import dev.mccue.json.stream.JsonArrayHandler;
import dev.mccue.json.stream.JsonStreamReadOptions;
import dev.mccue.json.stream.JsonValueHandler;
import org.jspecify.annotations.Nullable;
import java.io.IOException;
import java.io.PushbackReader;
-import java.math.BigDecimal;
-import java.math.BigInteger;
public final class JsonReaderMethods {
private JsonReaderMethods() {}
@@ -84,28 +82,14 @@ private static String readQuotedString(PushbackReader stream) throws IOException
}
private static JsonNumber readInteger(String string) {
- if (string.length() < 18) { // definitely fits in a Long
- return JsonNumber.of(Long.parseLong(string));
- }
- else {
- try {
- return JsonNumber.of(Long.parseLong(string));
- } catch (NumberFormatException __) {
- return JsonNumber.of(new BigInteger(string));
- }
- }
+ return new JsonIntegerImpl(string);
}
- private static JsonNumber readDecimal(String string, boolean bigDecimal) {
- if (bigDecimal) {
- return new BigDecimalImpl(new BigDecimal(string));
- }
- else {
- return new DoubleImpl(Double.parseDouble(string));
- }
+ private static JsonNumber readDecimal(String string) {
+ return new JsonDecimalImpl(string);
}
- private static JsonNumber readNumber(PushbackReader stream, boolean bigDecimal) throws IOException {
+ private static JsonNumber readNumber(PushbackReader stream) throws IOException {
var buffer = new StringBuilder();
enum Stage {
@@ -304,7 +288,7 @@ enum Stage {
}
if (isDecimal) {
- return readDecimal(buffer.toString(), bigDecimal);
+ return readDecimal(buffer.toString());
}
else {
return readInteger(buffer.toString());
@@ -448,7 +432,7 @@ public static void readStream(
switch (c) {
case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> {
stream.unread(c);
- valueHandler.onNumber(readNumber(stream, options.useBigDecimals()));
+ valueHandler.onNumber(readNumber(stream));
}
case '"' -> {
valueHandler.onString(readQuotedString(stream));
@@ -498,7 +482,7 @@ public static void readStream(
public static Json read(PushbackReader stream, JsonReadOptions options) throws IOException {
var handler = new Handlers.BaseTreeValueHandler();
- readStream(stream, false, new JsonStreamReadOptions(options.useBigDecimals()), handler);
+ readStream(stream, false, new JsonStreamReadOptions(), handler);
if (handler.result == null && options.eofBehavior() == JsonReadOptions.EOFBehavior.THROW_EXCEPTION) {
throw JsonReadException.unexpectedEOF();
}
diff --git a/src/main/java/dev/mccue/json/internal/JsonWriter.java b/src/main/java/dev/mccue/json/internal/JsonWriter.java
index 499e7bc..aa7ac97 100644
--- a/src/main/java/dev/mccue/json/internal/JsonWriter.java
+++ b/src/main/java/dev/mccue/json/internal/JsonWriter.java
@@ -1,32 +1,12 @@
package dev.mccue.json.internal;
import dev.mccue.json.*;
-import dev.mccue.json.internal.*;
import java.io.IOException;
import java.util.IdentityHashMap;
public final class JsonWriter {
public JsonWriter() {}
- private interface Writer {
- void write(Json v, Appendable out, OptionsWithIndentDepth options) throws IOException;
- }
-
- private static final IdentityHashMap, Writer> WRITERS;
-
- static {
- WRITERS = new IdentityHashMap<>();
- WRITERS.put(JsonNull.class, (__, out, ___) -> out.append("null"));
- WRITERS.put(JsonTrue.class, (__, out, ___) -> out.append("true"));
- WRITERS.put(JsonFalse.class, (__, out, ___) -> out.append("false"));
- WRITERS.put(LongImpl.class, (v, out, ___) -> out.append(v.toString()));
- WRITERS.put(DoubleImpl.class, (v, out, ___) -> out.append(v.toString()));
- WRITERS.put(BigIntegerImpl.class, (v, out, ___) -> out.append(v.toString()));
- WRITERS.put(BigDecimalImpl.class, (v, out, ___) -> out.append(v.toString()));
- WRITERS.put(StringImpl.class, (v, out, options) -> writeString((JsonString) v, out, options));
- WRITERS.put(ArrayImpl.class, (v, out, options) -> writeArray((JsonArray) v, out, options));
- WRITERS.put(ObjectImpl.class, (v, out, options) -> writeObject((JsonObject) v, out, options));
- }
private static final short[] CODEPOINT_DECODER;
@@ -203,7 +183,15 @@ static void writeArray(JsonArray a, Appendable out, OptionsWithIndentDepth optio
static void write(Json v, Appendable out, OptionsWithIndentDepth options) throws IOException {
- WRITERS.get(v.getClass()).write(v, out, options);
+ switch (v) {
+ case JsonNull __ -> out.append("null");
+ case JsonTrue __ -> out.append("true");
+ case JsonFalse __ -> out.append("false");
+ case JsonNumber number -> out.append(number.toString());
+ case JsonString string -> writeString(string, out, options);
+ case JsonArray array -> writeArray(array, out, options);
+ case JsonObject object -> writeObject(object, out, options);
+ }
}
public record OptionsWithIndentDepth(
diff --git a/src/main/java/dev/mccue/json/internal/LongImpl.java b/src/main/java/dev/mccue/json/internal/LongImpl.java
deleted file mode 100644
index 2570013..0000000
--- a/src/main/java/dev/mccue/json/internal/LongImpl.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package dev.mccue.json.internal;
-
-import dev.mccue.json.Json;
-import dev.mccue.json.JsonNumber;
-import dev.mccue.json.serialization.JsonSerializationProxy;
-
-import java.io.Serial;
-import java.math.BigInteger;
-
-@ValueCandidate
-public final class LongImpl extends JsonNumber {
- @Serial
- private static final long serialVersionUID = 1L;
- private final long longValue;
-
- public LongImpl(long longValue) {
- this.longValue = longValue;
- }
-
- @Override
- public java.math.BigDecimal bigDecimalValue() {
- return java.math.BigDecimal.valueOf(longValue);
- }
-
- @Override
- public java.math.BigInteger bigIntegerValue() {
- return java.math.BigInteger.valueOf(longValue);
- }
-
- @Override
- public int intValueExact() {
- if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
- return (int) longValue;
- }
- else {
- throw new ArithmeticException(longValue + " cannot fit into an int.");
- }
- }
-
- @Override
- public long longValueExact() {
- return longValue;
- }
-
- @Override
- public BigInteger bigIntegerValueExact() {
- return BigInteger.valueOf(longValue);
- }
-
- @Override
- public boolean isIntegral() {
- return true;
- }
-
-
- @Override
- public int intValue() {
- return (int) longValue;
- }
-
- @Override
- public long longValue() {
- return longValue;
- }
-
- @Override
- public float floatValue() {
- return (float) longValue;
- }
-
- @Override
- public double doubleValue() {
- return (double) longValue;
- }
-
- @Override
- public boolean equals(Object o) {
- return (this == o) || (
- o instanceof LongImpl otherLong &&
- this.longValue == otherLong.longValue
- );
- }
-
- @Override
- public int hashCode() {
- return java.lang.Long.hashCode(this.longValue);
- }
-
- @Override
- public java.lang.String toString() {
- return java.lang.Long.toString(longValue);
- }
-
- @Serial
- private Object writeReplace() {
- return new JsonSerializationProxy(Json.writeString(this));
- }
-
- @Serial
- private Object readResolve() {
- throw new IllegalStateException();
- }
-}
diff --git a/src/main/java/dev/mccue/json/stream/JsonStreamReadOptions.java b/src/main/java/dev/mccue/json/stream/JsonStreamReadOptions.java
index 9d873f0..138713f 100644
--- a/src/main/java/dev/mccue/json/stream/JsonStreamReadOptions.java
+++ b/src/main/java/dev/mccue/json/stream/JsonStreamReadOptions.java
@@ -1,14 +1,7 @@
package dev.mccue.json.stream;
-public record JsonStreamReadOptions(
- boolean useBigDecimals
-) {
+public final class JsonStreamReadOptions {
public JsonStreamReadOptions() {
- this(false);
- }
-
- public JsonStreamReadOptions withUseBigDecimals(boolean useBigDecimals) {
- return new JsonStreamReadOptions(useBigDecimals);
}
}
diff --git a/src/test/java/dev/mccue/json/JsonParsingTest.java b/src/test/java/dev/mccue/json/JsonParsingTest.java
index 9dc33b8..8782534 100644
--- a/src/test/java/dev/mccue/json/JsonParsingTest.java
+++ b/src/test/java/dev/mccue/json/JsonParsingTest.java
@@ -3,13 +3,14 @@
import org.junit.jupiter.api.Test;
import java.io.StringReader;
+import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Random;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.*;
public final class JsonParsingTest {
@Test
@@ -337,4 +338,42 @@ public void testReadMultipleTopLevel() {
forms
);
}
+
+ @Test
+ public void testExtremelyBigNumber() {
+ assertEquals(
+ JsonDecimal.of(new BigDecimal("1231231234124125412532523452345.4325342523452353245345345")),
+ Json.readString("1231231234124125412532523452345.4325342523452353245345345")
+ );
+ }
+
+ @Test
+ public void testNumberEquivalences() {
+ assertEquals(
+ Json.of(new BigInteger("3")),
+ Json.of(new BigDecimal("3"))
+ );
+
+ assertNotEquals(
+ Json.of(new BigInteger("3")),
+ Json.of(new BigDecimal("3.0"))
+ );
+
+ assertEquals(
+ Json.of(new BigInteger("3")),
+ Json.of(3)
+ );
+
+ assertNotEquals(
+ Json.of(3.0),
+ Json.of(3)
+ );
+
+ assertEquals(
+ Json.of(3.0f),
+ Json.of(3.0)
+ );
+ }
+
+
}