java-commons/commons-serialize/src/main/java/io/gitlab/jfronny/commons/serialize/SerializeReader.java

123 lines
4.1 KiB
Java

package io.gitlab.jfronny.commons.serialize;
import io.gitlab.jfronny.commons.SamWithReceiver;
public abstract class SerializeReader<TEx extends Throwable, T extends SerializeReader<TEx, T>> implements AutoCloseable {
protected boolean lenient = false;
protected boolean serializeSpecialFloatingPointValues = false;
public boolean isLenient() {
return lenient;
}
public T setLenient(boolean lenient) {
this.lenient = lenient;
if (lenient) return setSerializeSpecialFloatingPointValues(true);
return (T) this;
}
public boolean isSerializeSpecialFloatingPointValues() {
return serializeSpecialFloatingPointValues;
}
public T setSerializeSpecialFloatingPointValues(boolean serializeSpecialFloatingPointValues) {
this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
return (T) this;
}
public abstract T beginArray() throws TEx;
public abstract T endArray() throws TEx;
public <R> R array(SerializeReaderFunction<TEx, T, R> consumer) throws TEx {
beginArray();
var result = consumer.accept((T) this);
endArray();
return result;
}
public abstract T beginObject() throws TEx;
public abstract T endObject() throws TEx;
public <R> R object(SerializeReaderFunction<TEx, T, R> consumer) throws TEx {
beginObject();
var result = consumer.accept((T) this);
endObject();
return result;
}
public abstract boolean hasNext() throws TEx;
public abstract Token peek() throws TEx;
public abstract String nextName() throws TEx;
public abstract String nextString() throws TEx;
public abstract boolean nextBoolean() throws TEx;
public abstract void nextNull() throws TEx;
public double nextDouble() throws TEx {
return nextNumber().doubleValue();
}
public long nextLong() throws TEx {
return nextNumber().longValue();
}
public int nextInt() throws TEx {
return nextNumber().intValue();
}
public abstract Number nextNumber() throws TEx;
public abstract void skipValue() throws TEx;
public abstract String getPath();
public abstract String getPreviousPath();
/**
* Copies the current element to the writer.
*
* @param writer the writer to copy to
* @throws TEx if an error occurs
*/
public <TEx2 extends Throwable> void copyTo(SerializeWriter<TEx2, ?> writer) throws TEx, TEx2 {
switch (peek()) {
case BEGIN_ARRAY -> {
this.beginArray();
writer.beginArray();
while (this.hasNext()) {
this.copyTo(writer);
}
this.endArray();
writer.endArray();
}
case END_ARRAY -> throw new IllegalStateException("Cannot copy standalone END_ARRAY");
case BEGIN_OBJECT -> {
this.beginObject();
writer.beginObject();
while (this.hasNext()) {
writer.name(this.nextName());
this.copyTo(writer);
}
this.endObject();
writer.endObject();
}
case END_OBJECT -> throw new IllegalStateException("Cannot copy standalone END_OBJECT");
case NAME -> throw new IllegalStateException("Cannot copy standalone NAME");
case STRING -> writer.value(this.nextString());
case NUMBER -> writer.value(this.nextNumber());
case BOOLEAN -> writer.value(this.nextBoolean());
case NULL -> {
this.nextNull();
writer.nullValue();
}
case END_DOCUMENT -> throw new IllegalStateException("Cannot copy END_DOCUMENT");
}
}
@Override
public String toString() {
return getClass().getSimpleName() + locationString();
}
protected String locationString() {
return " at path " + getPath();
}
@SamWithReceiver
public interface SerializeReaderFunction<TEx extends Throwable, T extends SerializeReader<TEx, T>, R> {
R accept(T reader) throws TEx;
}
}