feat(serialize-databind): implement alternate API for parsing via ADTs. Probably still need to figure out how to ensure unchecked exceptions are not propagated
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
1a09294690
commit
133e1d75f9
@ -0,0 +1,12 @@
|
||||
package io.gitlab.jfronny.commons.serialize;
|
||||
|
||||
public sealed interface RToken {
|
||||
enum Simple implements RToken {
|
||||
BEGIN_ARRAY, END_ARRAY, BEGIN_OBJECT, END_OBJECT, NULL, END_DOCUMENT
|
||||
}
|
||||
|
||||
record Name(java.lang.String name) implements RToken {}
|
||||
record String(java.lang.String value) implements RToken {}
|
||||
record Number(java.lang.Number value) implements RToken {}
|
||||
record Boolean(boolean value) implements RToken {}
|
||||
}
|
@ -1,8 +1,23 @@
|
||||
package io.gitlab.jfronny.commons.serialize;
|
||||
|
||||
import io.gitlab.jfronny.commons.SamWithReceiver;
|
||||
import io.gitlab.jfronny.commons.throwable.ExceptionWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class SerializeReader<TEx extends Exception, T extends SerializeReader<TEx, T>> implements AutoCloseable {
|
||||
import java.util.Iterator;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* A reader for serialized data.
|
||||
* Although it is marked as {@link Iterable}, you should make sure iteration is only done once, since it <b>consumes tokens</b>!
|
||||
*
|
||||
* @param <TEx> the exception type
|
||||
* @param <T> the reader type
|
||||
*/
|
||||
public abstract class SerializeReader<TEx extends Exception, T extends SerializeReader<TEx, T>> implements AutoCloseable, Iterable<RToken> {
|
||||
protected boolean lenient = false;
|
||||
protected boolean serializeSpecialFloatingPointValues = false;
|
||||
|
||||
@ -67,6 +82,69 @@ public abstract class SerializeReader<TEx extends Exception, T extends Serialize
|
||||
@Override
|
||||
public abstract void close() throws TEx;
|
||||
|
||||
/**
|
||||
* Returns the next token alongside its value as an {@link RToken} and advances the reader.
|
||||
*
|
||||
* @return the next token
|
||||
* @throws TEx if an error occurs
|
||||
*/
|
||||
public RToken next() throws TEx {
|
||||
return switch (peek()) {
|
||||
case BEGIN_ARRAY -> RToken.Simple.BEGIN_ARRAY;
|
||||
case END_ARRAY -> RToken.Simple.END_ARRAY;
|
||||
case BEGIN_OBJECT -> RToken.Simple.BEGIN_OBJECT;
|
||||
case END_OBJECT -> RToken.Simple.END_OBJECT;
|
||||
case NAME -> new RToken.Name(nextName());
|
||||
case STRING -> new RToken.String(nextString());
|
||||
case NUMBER -> new RToken.Number(nextNumber());
|
||||
case BOOLEAN -> new RToken.Boolean(nextBoolean());
|
||||
case NULL -> {
|
||||
nextNull();
|
||||
yield RToken.Simple.NULL;
|
||||
}
|
||||
case END_DOCUMENT -> RToken.Simple.END_DOCUMENT;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Stream} of the tokens within the current object or array.
|
||||
* The stream consumes tokens and advances the reader, so it is not possible to iterate over the tokens more than once.
|
||||
* Additionally, iteration may throw {@link RuntimeException}s created with {@link ExceptionWrapper#wrap(Throwable)} around {@link TEx}.
|
||||
* @return a stream of the tokens
|
||||
*/
|
||||
public @NotNull Stream<RToken> stream() {
|
||||
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator(), Spliterator.NONNULL | Spliterator.ORDERED), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link Iterator} over the tokens within the current object or array.
|
||||
* The iterator consumes tokens and advances the reader, so it is not possible to iterate over the tokens more than once.
|
||||
* Additionally, iteration may throw {@link RuntimeException}s created with {@link ExceptionWrapper#wrap(Throwable)} around {@link TEx}.
|
||||
* @return an iterator over the tokens
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Iterator<RToken> iterator() {
|
||||
return new Iterator<>() {
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
try {
|
||||
return SerializeReader.this.hasNext();
|
||||
} catch (Exception e) {
|
||||
throw ExceptionWrapper.wrap(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RToken next() {
|
||||
try {
|
||||
return SerializeReader.this.next();
|
||||
} catch (Exception e) {
|
||||
throw ExceptionWrapper.wrap(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the current element to the writer.
|
||||
*
|
||||
@ -113,6 +191,10 @@ public abstract class SerializeReader<TEx extends Exception, T extends Serialize
|
||||
return getClass().getSimpleName() + locationString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to provide toString and location information in error messages. Format should resemble that in {@code serialize-json}.
|
||||
* @return a string representation of the location of the reader
|
||||
*/
|
||||
protected String locationString() {
|
||||
return " at path " + getPath();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user