mirror of
https://github.com/fankes/moshi.git
synced 2025-10-19 16:09:21 +08:00
Make JsonReader.promoteNameToValue() a public API
This commit is contained in:
@@ -514,8 +514,19 @@ public abstract class JsonReader implements Closeable {
|
|||||||
/**
|
/**
|
||||||
* Changes the reader to treat the next name as a string value. This is useful for map adapters so
|
* Changes the reader to treat the next name as a string value. This is useful for map adapters so
|
||||||
* that arbitrary type adapters can use {@link #nextString} to read a name value.
|
* that arbitrary type adapters can use {@link #nextString} to read a name value.
|
||||||
|
*
|
||||||
|
* <p>In this example, calling this method allows two sequential calls to {@link #nextString()}:
|
||||||
|
* <pre> {@code
|
||||||
|
*
|
||||||
|
* JsonReader reader = JsonReader.of(new Buffer().writeUtf8("{\"a\":\"b\"}"));
|
||||||
|
* reader.beginObject();
|
||||||
|
* reader.promoteNameToValue();
|
||||||
|
* assertEquals("a", reader.nextString());
|
||||||
|
* assertEquals("b", reader.nextString());
|
||||||
|
* reader.endObject();
|
||||||
|
* }</pre>
|
||||||
*/
|
*/
|
||||||
abstract void promoteNameToValue() throws IOException;
|
public abstract void promoteNameToValue() throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A set of strings to be chosen with {@link #selectName} or {@link #selectString}. This prepares
|
* A set of strings to be chosen with {@link #selectName} or {@link #selectString}. This prepares
|
||||||
|
@@ -1158,7 +1158,7 @@ final class JsonUtf8Reader extends JsonReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override void promoteNameToValue() throws IOException {
|
@Override public void promoteNameToValue() throws IOException {
|
||||||
if (hasNext()) {
|
if (hasNext()) {
|
||||||
peekedString = nextName();
|
peekedString = nextName();
|
||||||
peeked = PEEKED_BUFFERED;
|
peeked = PEEKED_BUFFERED;
|
||||||
|
@@ -162,12 +162,13 @@ final class JsonUtf8Writer extends JsonWriter {
|
|||||||
throw new IllegalStateException("JsonWriter is closed.");
|
throw new IllegalStateException("JsonWriter is closed.");
|
||||||
}
|
}
|
||||||
int context = peekScope();
|
int context = peekScope();
|
||||||
if ((context != EMPTY_OBJECT && context != NONEMPTY_OBJECT) || deferredName != null) {
|
if ((context != EMPTY_OBJECT && context != NONEMPTY_OBJECT)
|
||||||
|
|| deferredName != null
|
||||||
|
|| promoteValueToName) {
|
||||||
throw new IllegalStateException("Nesting problem.");
|
throw new IllegalStateException("Nesting problem.");
|
||||||
}
|
}
|
||||||
deferredName = name;
|
deferredName = name;
|
||||||
pathNames[stackSize - 1] = name;
|
pathNames[stackSize - 1] = name;
|
||||||
promoteValueToName = false;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +185,7 @@ final class JsonUtf8Writer extends JsonWriter {
|
|||||||
return nullValue();
|
return nullValue();
|
||||||
}
|
}
|
||||||
if (promoteValueToName) {
|
if (promoteValueToName) {
|
||||||
|
promoteValueToName = false;
|
||||||
return name(value);
|
return name(value);
|
||||||
}
|
}
|
||||||
writeDeferredName();
|
writeDeferredName();
|
||||||
@@ -236,6 +238,7 @@ final class JsonUtf8Writer extends JsonWriter {
|
|||||||
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
|
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
|
||||||
}
|
}
|
||||||
if (promoteValueToName) {
|
if (promoteValueToName) {
|
||||||
|
promoteValueToName = false;
|
||||||
return name(Double.toString(value));
|
return name(Double.toString(value));
|
||||||
}
|
}
|
||||||
writeDeferredName();
|
writeDeferredName();
|
||||||
@@ -247,6 +250,7 @@ final class JsonUtf8Writer extends JsonWriter {
|
|||||||
|
|
||||||
@Override public JsonWriter value(long value) throws IOException {
|
@Override public JsonWriter value(long value) throws IOException {
|
||||||
if (promoteValueToName) {
|
if (promoteValueToName) {
|
||||||
|
promoteValueToName = false;
|
||||||
return name(Long.toString(value));
|
return name(Long.toString(value));
|
||||||
}
|
}
|
||||||
writeDeferredName();
|
writeDeferredName();
|
||||||
@@ -267,6 +271,7 @@ final class JsonUtf8Writer extends JsonWriter {
|
|||||||
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
|
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
|
||||||
}
|
}
|
||||||
if (promoteValueToName) {
|
if (promoteValueToName) {
|
||||||
|
promoteValueToName = false;
|
||||||
return name(string);
|
return name(string);
|
||||||
}
|
}
|
||||||
writeDeferredName();
|
writeDeferredName();
|
||||||
|
@@ -330,7 +330,7 @@ final class JsonValueReader extends JsonReader {
|
|||||||
return new JsonValueReader(this);
|
return new JsonValueReader(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override void promoteNameToValue() throws IOException {
|
@Override public void promoteNameToValue() throws IOException {
|
||||||
if (hasNext()) {
|
if (hasNext()) {
|
||||||
String name = nextName();
|
String name = nextName();
|
||||||
push(name);
|
push(name);
|
||||||
|
@@ -130,17 +130,17 @@ final class JsonValueWriter extends JsonWriter {
|
|||||||
if (stackSize == 0) {
|
if (stackSize == 0) {
|
||||||
throw new IllegalStateException("JsonWriter is closed.");
|
throw new IllegalStateException("JsonWriter is closed.");
|
||||||
}
|
}
|
||||||
if (peekScope() != EMPTY_OBJECT || deferredName != null) {
|
if (peekScope() != EMPTY_OBJECT || deferredName != null || promoteValueToName) {
|
||||||
throw new IllegalStateException("Nesting problem.");
|
throw new IllegalStateException("Nesting problem.");
|
||||||
}
|
}
|
||||||
deferredName = name;
|
deferredName = name;
|
||||||
pathNames[stackSize - 1] = name;
|
pathNames[stackSize - 1] = name;
|
||||||
promoteValueToName = false;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public JsonWriter value(@Nullable String value) throws IOException {
|
@Override public JsonWriter value(@Nullable String value) throws IOException {
|
||||||
if (promoteValueToName) {
|
if (promoteValueToName) {
|
||||||
|
promoteValueToName = false;
|
||||||
return name(value);
|
return name(value);
|
||||||
}
|
}
|
||||||
add(value);
|
add(value);
|
||||||
@@ -184,6 +184,7 @@ final class JsonValueWriter extends JsonWriter {
|
|||||||
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
|
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
|
||||||
}
|
}
|
||||||
if (promoteValueToName) {
|
if (promoteValueToName) {
|
||||||
|
promoteValueToName = false;
|
||||||
return name(Double.toString(value));
|
return name(Double.toString(value));
|
||||||
}
|
}
|
||||||
add(value);
|
add(value);
|
||||||
@@ -193,6 +194,7 @@ final class JsonValueWriter extends JsonWriter {
|
|||||||
|
|
||||||
@Override public JsonWriter value(long value) throws IOException {
|
@Override public JsonWriter value(long value) throws IOException {
|
||||||
if (promoteValueToName) {
|
if (promoteValueToName) {
|
||||||
|
promoteValueToName = false;
|
||||||
return name(Long.toString(value));
|
return name(Long.toString(value));
|
||||||
}
|
}
|
||||||
add(value);
|
add(value);
|
||||||
@@ -223,6 +225,7 @@ final class JsonValueWriter extends JsonWriter {
|
|||||||
? ((BigDecimal) value)
|
? ((BigDecimal) value)
|
||||||
: new BigDecimal(value.toString());
|
: new BigDecimal(value.toString());
|
||||||
if (promoteValueToName) {
|
if (promoteValueToName) {
|
||||||
|
promoteValueToName = false;
|
||||||
return name(bigDecimalValue.toString());
|
return name(bigDecimalValue.toString());
|
||||||
}
|
}
|
||||||
add(bigDecimalValue);
|
add(bigDecimalValue);
|
||||||
|
@@ -443,8 +443,20 @@ public abstract class JsonWriter implements Closeable, Flushable {
|
|||||||
/**
|
/**
|
||||||
* Changes the writer to treat the next value as a string name. This is useful for map adapters so
|
* Changes the writer to treat the next value as a string name. This is useful for map adapters so
|
||||||
* that arbitrary type adapters can use {@link #value} to write a name value.
|
* that arbitrary type adapters can use {@link #value} to write a name value.
|
||||||
|
*
|
||||||
|
* <p>In this example, calling this method allows two sequential calls to {@link #value(String)}
|
||||||
|
* to produce the object, {@code {"a": "b"}}.
|
||||||
|
* <pre> {@code
|
||||||
|
*
|
||||||
|
* JsonWriter writer = JsonWriter.of(...);
|
||||||
|
* writer.beginObject();
|
||||||
|
* writer.promoteValueToName();
|
||||||
|
* writer.value("a");
|
||||||
|
* writer.value("b");
|
||||||
|
* writer.endObject();
|
||||||
|
* }</pre>
|
||||||
*/
|
*/
|
||||||
final void promoteValueToName() throws IOException {
|
public final void promoteValueToName() throws IOException {
|
||||||
int context = peekScope();
|
int context = peekScope();
|
||||||
if (context != NONEMPTY_OBJECT && context != EMPTY_OBJECT) {
|
if (context != NONEMPTY_OBJECT && context != EMPTY_OBJECT) {
|
||||||
throw new IllegalStateException("Nesting problem.");
|
throw new IllegalStateException("Nesting problem.");
|
||||||
|
@@ -20,7 +20,6 @@ import java.io.IOException;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
@@ -1158,6 +1157,85 @@ public final class JsonReaderTest {
|
|||||||
reader.endObject();
|
reader.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test public void promoteStringNameToValue() throws IOException {
|
||||||
|
JsonReader reader = newReader("{\"a\":\"b\"}");
|
||||||
|
reader.beginObject();
|
||||||
|
reader.promoteNameToValue();
|
||||||
|
assertEquals("a", reader.nextString());
|
||||||
|
assertEquals("b", reader.nextString());
|
||||||
|
reader.endObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteDoubleNameToValue() throws IOException {
|
||||||
|
JsonReader reader = newReader("{\"5\":\"b\"}");
|
||||||
|
reader.beginObject();
|
||||||
|
reader.promoteNameToValue();
|
||||||
|
assertEquals(5.0, reader.nextDouble(), 0.0);
|
||||||
|
assertEquals("b", reader.nextString());
|
||||||
|
reader.endObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteLongNameToValue() throws IOException {
|
||||||
|
JsonReader reader = newReader("{\"5\":\"b\"}");
|
||||||
|
reader.beginObject();
|
||||||
|
reader.promoteNameToValue();
|
||||||
|
assertEquals(5L, reader.nextLong());
|
||||||
|
assertEquals("b", reader.nextString());
|
||||||
|
reader.endObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteNullNameToValue() throws IOException {
|
||||||
|
JsonReader reader = newReader("{\"null\":\"b\"}");
|
||||||
|
reader.beginObject();
|
||||||
|
reader.promoteNameToValue();
|
||||||
|
try {
|
||||||
|
reader.nextNull();
|
||||||
|
fail();
|
||||||
|
} catch (JsonDataException expected) {
|
||||||
|
}
|
||||||
|
assertEquals("null", reader.nextString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteBooleanNameToValue() throws IOException {
|
||||||
|
JsonReader reader = newReader("{\"true\":\"b\"}");
|
||||||
|
reader.beginObject();
|
||||||
|
reader.promoteNameToValue();
|
||||||
|
try {
|
||||||
|
reader.nextBoolean();
|
||||||
|
fail();
|
||||||
|
} catch (JsonDataException expected) {
|
||||||
|
}
|
||||||
|
assertEquals("true", reader.nextString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteBooleanNameToValueCannotBeReadAsName() throws IOException {
|
||||||
|
JsonReader reader = newReader("{\"true\":\"b\"}");
|
||||||
|
reader.beginObject();
|
||||||
|
reader.promoteNameToValue();
|
||||||
|
try {
|
||||||
|
reader.nextName();
|
||||||
|
fail();
|
||||||
|
} catch (JsonDataException expected) {
|
||||||
|
}
|
||||||
|
assertEquals("true", reader.nextString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteSkippedNameToValue() throws IOException {
|
||||||
|
JsonReader reader = newReader("{\"true\":\"b\"}");
|
||||||
|
reader.beginObject();
|
||||||
|
reader.promoteNameToValue();
|
||||||
|
reader.skipValue();
|
||||||
|
assertEquals("b", reader.nextString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteNameToValueAtEndOfObject() throws IOException {
|
||||||
|
JsonReader reader = newReader("{}");
|
||||||
|
reader.beginObject();
|
||||||
|
reader.promoteNameToValue();
|
||||||
|
assertThat(reader.hasNext()).isFalse();
|
||||||
|
reader.endObject();
|
||||||
|
}
|
||||||
|
|
||||||
@Test public void optionsStrings() {
|
@Test public void optionsStrings() {
|
||||||
String[] options = new String[] { "a", "b", "c" };
|
String[] options = new String[] { "a", "b", "c" };
|
||||||
JsonReader.Options abc = JsonReader.Options.of("a", "b", "c");
|
JsonReader.Options abc = JsonReader.Options.of("a", "b", "c");
|
||||||
|
@@ -814,4 +814,88 @@ public final class JsonWriterTest {
|
|||||||
assertThat(e).hasMessage("Map keys must be non-null");
|
assertThat(e).hasMessage("Map keys must be non-null");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test public void promoteStringNameToValue() throws IOException {
|
||||||
|
JsonWriter writer = factory.newWriter();
|
||||||
|
writer.beginObject();
|
||||||
|
writer.promoteValueToName();
|
||||||
|
writer.value("a");
|
||||||
|
writer.value("b");
|
||||||
|
writer.endObject();
|
||||||
|
assertThat(factory.json()).isEqualTo("{\"a\":\"b\"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteDoubleNameToValue() throws IOException {
|
||||||
|
JsonWriter writer = factory.newWriter();
|
||||||
|
writer.beginObject();
|
||||||
|
writer.promoteValueToName();
|
||||||
|
writer.value(5.0);
|
||||||
|
writer.value("b");
|
||||||
|
writer.endObject();
|
||||||
|
assertThat(factory.json()).isEqualTo("{\"5.0\":\"b\"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteLongNameToValue() throws IOException {
|
||||||
|
JsonWriter writer = factory.newWriter();
|
||||||
|
writer.beginObject();
|
||||||
|
writer.promoteValueToName();
|
||||||
|
writer.value(5L);
|
||||||
|
writer.value("b");
|
||||||
|
writer.endObject();
|
||||||
|
assertThat(factory.json()).isEqualTo("{\"5\":\"b\"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteNumberNameToValue() throws IOException {
|
||||||
|
JsonWriter writer = factory.newWriter();
|
||||||
|
writer.beginObject();
|
||||||
|
writer.promoteValueToName();
|
||||||
|
writer.value(BigInteger.ONE);
|
||||||
|
writer.value("b");
|
||||||
|
writer.endObject();
|
||||||
|
assertThat(factory.json()).isEqualTo("{\"1\":\"b\"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteNullNameToValue() throws IOException {
|
||||||
|
JsonWriter writer = factory.newWriter();
|
||||||
|
writer.beginObject();
|
||||||
|
writer.promoteValueToName();
|
||||||
|
try {
|
||||||
|
writer.nullValue();
|
||||||
|
fail();
|
||||||
|
} catch (IllegalStateException expected) {
|
||||||
|
assertThat(expected).hasMessage("null cannot be used as a map key in JSON at path $.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteBooleanNameToValue() throws IOException {
|
||||||
|
JsonWriter writer = factory.newWriter();
|
||||||
|
writer.beginObject();
|
||||||
|
writer.promoteValueToName();
|
||||||
|
try {
|
||||||
|
writer.value(true);
|
||||||
|
fail();
|
||||||
|
} catch (IllegalStateException expected) {
|
||||||
|
assertThat(expected).hasMessage("Boolean cannot be used as a map key in JSON at path $.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteNameToValueCannotBeWrittenAsName() throws IOException {
|
||||||
|
JsonWriter writer = factory.newWriter();
|
||||||
|
writer.beginObject();
|
||||||
|
writer.promoteValueToName();
|
||||||
|
try {
|
||||||
|
writer.name("a");
|
||||||
|
fail();
|
||||||
|
} catch (IllegalStateException expected) {
|
||||||
|
assertThat(expected).hasMessage("Nesting problem.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void promoteNameToValueAtEndOfObject() throws IOException {
|
||||||
|
JsonWriter writer = factory.newWriter();
|
||||||
|
writer.beginObject();
|
||||||
|
writer.promoteValueToName();
|
||||||
|
writer.endObject();
|
||||||
|
assertThat(factory.json()).isEqualTo("{}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user